Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding ability to authenticate rest calls with bearer token #96

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

sicurezza
Copy link

No description provided.

change: load metadata using tenant or common, depending on presence of org_domain_hint
…. Added new settings resourceId and issuer. Added resourceId in Settings page
Copy link
Owner

@psignoret psignoret left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First of all, apologies for the (huge) delay in this review. Second, thanks! I really like the idea of adding logic here to accept an access token issued by Azure AD (for the app in question).

I'm a bit confused by the implementation with regards to token validation. I noticed that you've added code to parse the JWT token. This is unnecessary, the JWT library already does this, and it already verifies the nbf and iat. So, a lot of this code is actually unnecessary.

I haven't quite looked at the code related to the REST request itself, I need to go learn a bit more about the filters you've added--if I have any comments on that, I'll update this.

This code could use some style clean-up, to ensure we're sticking to the WordPress coding standards: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/

* @param \AADSSO_Settings $settings The settings to use.
*
*/
private static function validate_token_claims( $bearer_token, $settings){
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When this is used, Firebase\JWT::decode() has already decoded the JWT, validated the nbf and exp claims, and verified the signature. There is no need to do your own splitting, decoding or expiry validation.

*
* @return mixed The decoded authorization result.
*/
private static function split_id_token($bearer_token) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned above, this is all handled by Firebase\JWT, there's no need to do this yourself.

/**
* Validates signature and claims of a bearer_token value returned
*
* @param array $authentication_request_body The body to use in the Authentication Request.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The @param doesn't match the method signature.

/**
* Decodes and validates an id_token value returned
*
* @param array $authentication_request_body The body to use in the Authentication Request.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@param doesn't match the method.

Settings.php Outdated
@@ -107,7 +117,8 @@ class AADSSO_Settings {
/**
* @var string The OpenID Connect configuration discovery endpoint.
*/
public $openid_configuration_endpoint = 'https://login.microsoftonline.com/common/.well-known/openid-configuration';
public $openid_configuration_endpoint_prefix = 'https://login.microsoftonline.com/';
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In daa9697, we made openid_configuration_endpoint a configurable setting. This allows the site to be either multi-tenant without external users (using common), or single-tenant with external users (using the tenanted endpoint). So, this is unnecessary.

*
* @param array $authentication_request_body The body to use in the Authentication Request.
* @param \AADSSO_Settings $settings The settings to use.
*
* @return mixed The decoded authorization result.
*/
public static function validate_id_token( $id_token, $settings, $antiforgery_id ) {
private static function validate_token_signature( $id_token, $settings) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method does more than validate the token signature. (See comments below for more details.) The change to the method documentation isn't quite clear.

Settings.php Outdated
@@ -19,6 +19,11 @@ class AADSSO_Settings {
public $client_id = '';

/**
* @var string The resource ID obtained after registering an application in AAD.
*/
public $resource_id = '';
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In which situation would the "resource ID" be different from the "client ID"?

Settings.php Outdated
@@ -206,8 +217,10 @@ public static function init() {
*/
$openid_configuration = get_transient( 'aadsso_openid_configuration' );
if( false === $openid_configuration || isset( $_GET['aadsso_reload_openid_config'] ) ) {
$tenant = !empty($instance->org_domain_hint) ? $instance->org_domain_hint : 'common';
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned on L120, this is unnecessary, since the OpenID Connect configuration endpoint is configurable.

@@ -278,7 +382,7 @@ function authenticate( $user, $username, $password ) {
// exists in WordPress (either because it already existed, or we created it
// on-the-fly). All that's left is to set the roles based on group membership.
if ( true === $this->settings->enable_aad_group_to_wp_role ) {
$user = $this->update_wp_user_roles( $user, $jwt->upn, $jwt->tid );
$user = $this->update_wp_user_roles( $user, $jwt->oid, $jwt->tid );
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, good catch! (This was only working before because Azure AD Graph API lets you use the UPN as the object ID for most requests, but this wouldn't hold up for external users.)

@sicurezza
Copy link
Author

Hi,
I edited files according to your questions.

regarding the resource id and client id they are different.

When an application requests azureAD a token to authenticate with a second application (in our case our application request a token to authenticate with wordpress) then it uses the resource id to identify the resource. This information is stored in AUD field of the token and the receiving application has to verify that the token it receives is for itself.

@bradkovach
Copy link
Contributor

Is this so that AD bearer tokens can be used through the WP REST API?

@sicurezza
Copy link
Author

yes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants