Skip to content

Create sample that shows how to integrate with Azure Active Directory ( AAD ) #494

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

Open
mores opened this issue Jan 4, 2019 · 22 comments
Open
Labels
feature-request Improvements and additions to the library.

Comments

@mores
Copy link

mores commented Jan 4, 2019

It is known that Azure Active Directory endpoints do not allow Cross Origin Resourece Sharing (CORS).

Others have documented it is a PITA to integrate with Azure Active #135

Others got frustrated about Azure AD not respecting OIDC, so they switched to using their own library directly #126

@mores
Copy link
Author

mores commented Jan 7, 2019

I have a sample that works with google sso.
I then preceded to replace all google urls and keys with those from Azure.
I currently have this isssue:
SEC7120: [CORS] The origin 'https://demo:4200' did not find 'https://demo:4200' in the Access-Control-Allow-Origin response header for cross-origin resource at 'https://login.microsoftonline.com/XXXXXXXXXX/discovery/v2.0/keys'.

But it looks like the return url does contain a valid id_token.

@manfredsteyer manfredsteyer added the feature-request Improvements and additions to the library. label Jan 22, 2019
@manfredsteyer
Copy link
Owner

We will write something down regarding ADFS and Azure AD. For the time beeing, you might find the following snippet from a real-world project useful.

All those things can also be configured within an config-object passed to .configure(...).

this.oauthService.redirectUri = environment.oauthRedirectUri;
this.oauthService.clientId = 'client-id';
this.oauthService.responseType = 'code token id_token';
this.oauthService.scope = 'openid allatclaims';
this.oauthService.logoutUrl = 'https://adfs-test.de/adfs/oauth2/logout';
this.oauthService.issuer = 'https://adfs-test.de/adfs';

/* This needs to be set manually b/c ADFS and Azure AD do not support CORS */
this.oauthService.resource = 'urn:example:example';
this.oauthService.userinfoEndpoint = 'https://adfs-test.de/adfs/userinfo';
this.oauthService.loginUrl = 'https://adfs-test.de/adfs/oauth2/authorize/';
this.oauthService.tokenEndpoint = 'https://adfs-test.de/adfs/oauth2/token/';

this.oauthService.events.pipe(filter(e => e.type === 'token_received')).subscribe(_ =>
{
   // do this and that ...
});

this.oauthService.tokenValidationHandler = new NullValidationHandler();

Another thing to consider is that you have to configure two apps/resources in your Azure AD: The client (Angular app) and the Backend.

@folego
Copy link

folego commented Mar 11, 2019

Hi manfredsteyer,

Thank you for the library. I used to create an Ionic App and worked very well.
Now I am trying to do the same with Azure AD, using the v1 or v2. Doing some research, I notice that Azure doesn't allow call and get the discovery document because they don't have the CORS enabled (like @mores comment before).

Do you have success to write an example using AAD? I am struggling to understand the different URLs that Azure provides in the configuration and how to use them using your last sample code posted here.

In my app, I am getting a valid token and sending to the API, and there I am validating using the .Net Core JWT authentication.

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
   {
      options.Authority = "https://dev-262704.oktapreview.com/oauth2/default";
      options.Audience = "api://default";
   });

@mores
Copy link
Author

mores commented Mar 27, 2019

I think that this is needed:
this.oauthService.strictDiscoveryDocumentValidation = false;
other wise you get
discovery_document_validation_error

@mores
Copy link
Author

mores commented Mar 27, 2019

When I tried the scope per your comment, azure is reporting:
The scope openid allatclaims is not valid
so I am using
this.oauthService.scope = 'openid';

@mores
Copy link
Author

mores commented Mar 27, 2019

"oauth2AllowImplicitFlow": true, should be in the Manifest of the registered app inside of Azure Active Directory admin center

@mores
Copy link
Author

mores commented Mar 28, 2019

Here is my extremely simple Login button for Azure: https://github.com/mores/angular-examples/tree/master/oidc-azure

I update src/app/app.component.ts with my guid tenant - and my client id

After hitting the login button, the url that shows in my browser is in the form of https://demo:4200/#access_token=eyJ0eXAiOiJ< snip >Vio68Xw &token_type=Bearer&expires_in=14399&scope=email+openid+profile&id_token=eyJ0eXAiOiJ< snip >IrXM4i1J8Q&state=Pxz< snip >a08&session_state=5e798974-< snip >-cdf9dcb4c3a0

I have gotten back valid tokens from Azure.

Console shows:
error loading jwks angular-oauth2-oidc.js:521

has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Any help is appreciated.

@jeroenheijmans
Copy link
Collaborator

If you get a CORS error, is there also a failed request in the network tab of your dev tools? What host is it trying to reach?

If you could also add this gist's code way up early in your code, then you'd also get some additional logging you could share, so we can know what bit of logic in the library is causing the CORS request.

@mores
Copy link
Author

mores commented Mar 28, 2019

I do not see any errors in the network tab.

There are two OAuthErrorEvent
type: "jwks_load_error"
statusText: "Unknown Error"

type: "discovery_document_load_error"
statusText: "Unknown Error"

It is having issues with this url: https://login.microsoftonline.com/ < enter guid here>/discovery/v2.0/keys

@mores
Copy link
Author

mores commented Mar 28, 2019

I now understand what @manfredsteyer was trying to say in his comment above....
any and all communication is proxied through adfs-test.de. ( middleware )
adfs-test.de is a private server needed to facilitate the communication from angular to azure.

@mores
Copy link
Author

mores commented Mar 29, 2019

Other people are having issues validating token too: microsoft/azure-spring-boot#476

I am able to verify the idToken but not the accessToken. Looking to see if Microsoft can shed any light here:
https://github.com/MicrosoftDocs/azure-docs/issues/28355

@JanSvejda
Copy link

Currently, I made it work with Azure B2C with the following setup:

import { Injectable } from '@angular/core';
import { OAuthService } from 'angular-oauth2-oidc';
import { MyValidationHandler } from './validation.handler';

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  constructor(private oauthService: OAuthService, private validationHandler: MyValidationHandler) {
  }

  getIdentityClaims() {
    return this.oauthService.getIdentityClaims();
  }
  logout() {
    this.oauthService.logOut();
  }
  login() {
    this.oauthService.initImplicitFlow();
  }

  setup() {
    this.oauthService.configure({
      responseType: 'token id_token',
      logoutUrl: 'http://localhost:8080/',
      issuer: 'https://<name>.b2clogin.com/<name>.onmicrosoft.com/v2.0/',
      strictDiscoveryDocumentValidation: false,
      tokenEndpoint: 'https://<name>.b2clogin.com/<name>.onmicrosoft.com/oauth2/v2.0/token?p=signinsignup',
      loginUrl: 'https://devcvp.b2clogin.com/devcvp.onmicrosoft.com/oauth2/v2.0/authorize?p=b2c_1_signinsignup',
      redirectUri: 'http://localhost:8080/login/oauth2/code/dsa-azure-b2c',
      clientId: '<client-id>',
      dummyClientSecret: '<secret>',
      scope: 'openid offline_access ....',
      skipIssuerCheck: true,
      oidc: true,
    });
    this.validationHandler.setKeyUri('https://<name>.b2clogin.com/<name>.onmicrosoft.com/discovery/v2.0/keys?p=signinsignup');
    this.oauthService.tokenValidationHandler = this.validationHandler;
    this.oauthService.setStorage(sessionStorage);

    this.oauthService.tryLogin({});
  }
}

I also had to use the PR #527 from @ismcagdas. Otherwise the flow fails.

Furthermore, to validate the tokens, I adapted the JwkValidationHandler to first fetch the keys from a configured URL, though nothing complicated.

Hope this helps.

@mores
Copy link
Author

mores commented Apr 3, 2019

I think I found out what "special processing" means:
AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet#609 (comment)
( Azure is adding a ‘nonce’ to the header - The JWS is signed with a SHA2 of the nonce, the ‘nonce’ is replaced before the JWS is serialized. )
It sounds like there is a need for a AzureValidationHandler to validate the access token.

@mores
Copy link
Author

mores commented Apr 8, 2019

I think I have a good working example now: https://github.com/mores/angular-examples/tree/master/oidc-azure
This ONLY utilizes an idToken, which will validate from a subclass of JwksValidationHandler.

@Matt-J-Hosking
Copy link

They seem to have enabled CORS for their jwks endpoint now. Best to switch over or get caught out like we did with a cached copy of the old keys.

@PrashantShrimal
Copy link

I am totally new in OIDC and need to use OIDC with Azure active directory. Does any one have a working example where no Identity server is required. I tried Mores's example but it also need a 'PRIVATE_PROXY_SERVER'.

@webdeveloperninja
Copy link

Where did you get the issuer url in the portal?

@Matt-J-Hosking
Copy link

Where did you get the issuer url in the portal?

If you open 'https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration' (the standard OIDC discovery endpoint) you get all the JSON data for their configuration. Replace 'common' with your Azure tenant ID for more specific values.

@ccruza
Copy link

ccruza commented Aug 21, 2019

I think I have a good working example now: https://github.com/mores/angular-examples/tree/master/oidc-azure
This ONLY utilizes an idToken, which will validate from a subclass of JwksValidationHandler.

Hello @mores
I followed your example. I did not understand this part (app.component.ts) :

this.oauthService.loadDiscoveryDocument( 'https://' + PRIVATE_PROXY_SERVER + '/angular2azure/openid-configuration?tenant=' + TENANT_GUID ).then( doc => {......

So, I change it for:

this.oauthService.loadDiscoveryDocument('https://login.microsoftonline.com/thisismydirectoryname.onmicrosoft.com/v2.0/.well-known/openid-configuration').then( doc => {....

And It started to work, so now everything is fine.. I'm going to adapt this to my actual project..

Thanks a lot!

@mjisaak
Copy link

mjisaak commented Sep 26, 2019

I wrote a blog post about how to use the component with Azure AD B2C:
https://about-azure.com/2019/09/26/using-azure-ad-b2c-with-angular-8/
The post includes a live demo and the source code. Hope that helps you.

@gerbermichi
Copy link

Does anyone have experience with the userinfo endpoint?
The following code leads to a 401 - "Access token validation failure. Invalid audience."
oauthService.loadUserProfile().then(u => console.log(u));

@eastjie
Copy link

eastjie commented Jan 7, 2021

Does anyone implement in Azure AD (not Azure B2C) with PCKE successfully? Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request Improvements and additions to the library.
Projects
None yet
Development

No branches or pull requests