0

I am about to create a WordPress Plugin with Client functionality. I basically want to post wordpress-data to a remote server using the servers REST-API (short overview: I want to simultaneously add projects to wordpress and a remote server). The remote servers resources are protected by Keycloak (or more precise: OpenID Connect/OAuth). I want to authenticate so I'm allowed to execute POST/PUT/DELETE-request.

I already successfully followed the auth-flow for Resource Owner Password Credentials Grant authorization method (made the user add his/her credentials on the plugin settings page and then transfer it to the auth-servers token endpoint to get the access token). But it implies that the auth-server allows Direct Access Grants Enabled for my client, which is not available in productive environment (for security reasons as I was told). So I need to authenticate via Authorization Code Grant. It's a lot more complicated for me, because I need to redirect the user of my client to the auth-servers login page, receive the auth code and then use it to get the access token. I'm unsure how to do it in a safe and easy way.

I thought about adding a button on my plugin options page. The problem is, I don't know how to do it using a form with admin-post.php action. A solution I was thinking about was to instruct the auth server to use my plugin-settings-page-url as the callback address in order to be able to use the $_GET["code"] superglobal. But I read that this is very bad and unsafe practice.

Another thing I am no sure about is, how I can assure that the client stays authorized? Because the access token is only valid for 300 seconds.

Summary: I want to follow the "Authorization Code Grant" Flow in my WP Plugin to be able to send requests to a OAuth2 protected resource.

Any ideas? Any help would be very much appreciated :)


EDIT This is what I have done so far:

(redirect to auth server to get the code)

<form action="https://urltoauthserver.com/auth/realms/myrealm/protocol/openid-connect/auth" method="post">
  <input type="hidden" name="client_id" value="my_client_id" />
  <input type="hidden" name="redirect_uri" value="<?php echo plugins_url('/myplugin/redirect.php');?>" />
  <input type="hidden" name="response_type" value="code" />
  <input type="hidden" name="scope" value="openid" />
  <input type="hidden" name="state" value="E9QcyBYe7kVaxjgXOrdwRevUD">
</form>

(and in redirect.php):

if(isset($_GET['code']) && $_GET['state'] === 'E9QcyBYe7kVaxjgXOrdwRevUD') {
    $code = $_GET["code"];

    $grant_type = "authorization_code";
    $redirect_uri = rtrim($_SERVER['HTTP_REFERER'], '/').$_SERVER['PHP_SELF'];
    $client_id = "my_client_id";
    $url = "https://urltoauthserver.com/auth/realms/myrealm/protocol/openid-connect/token";

    $post_data = array(
            'code'          => $code,
            'grant_type'    => "authorization_code",
            'redirect_uri'  => $redirect_uri,
            'client_id'     => $client_id
        );

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post_data));
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    $curl_response = curl_exec($curl);
    $response = json_decode($curl_response, true);
    curl_close($curl);
    $pb_access_token = $response['access_token'];
    $pb_refresh_token = $response['refresh_token'];
    echo $pb_access_token."<br /><br />";
    echo $pb_refresh_token;
}

So far so bad. I can get the access-token and the refresh-token from the keycloak token endpoint. But since keycloak redirected to my redirect.php directly, I cannot use any of the wordpress functions any more (it's just a PHP file). I need to get the access token back to my wordpress main plugin file for storage and usage. How do I do that? Is my approach safe? I am really puzzled.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.