Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

typescript - Getting and using Microsoft Graph token in Angular 6 to get group membership from Azure

I have an Angular 6 app where I am authenticating the user using microsoft-adal-angular6 against Azure Active Directory. That is working fine.

I then take the user OID and run:

https://graph.microsoft.com/v1.0/users/' + this.userOID + '/memberOf

To run that call I need to have my applications token and the appropriate permission.

https://login.microsoftonline.com/' + this.appID + '/oauth2/v2.0/token

my code looks like this...

getAuzrdddeToken(): Observable<any> {
    const url = 'https://login.microsoftonline.com/' 
        + environment.adalConfigGraph.orgID + '/oauth2/v2.0/token';

    const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'});

    const body = new HttpParams();
    body.set('client_id',  environment.adalConfigGraph.clientID);
    body.set('grant_type', 'client_credentials');
    body.set('scope', 'https://graph.microsoft.com/.default');
    body.set('client_secret',  environment.adalConfigGraph.secret);

    return this._http.post(url, body, {headers: headers}).pipe(
        tap(data => console.log('======== Token: ' + JSON.stringify(data))),
    );
}

I have the permission working fine, and the call itself is working in Postman, but when I try to build this into Angular I am getting the following error.

Access to XMLHttpRequest at 'https://login.microsoftonline.com/xxx/oauth2/v2.0/token' from origin 'http://localhost:4201' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I'm not a particularly advanced Angular/AAD user, but it seems to me that maybe I am constructing my service wrong or the header or the body of the request?

I am also currently trying to store the token in a string on the class where I get the token, but if someone can help me with the correct way to store that for consumption around the Angular app, that would be appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You shouldn't be using client_credentials on the client side like this. It is extremely dangerous since any scope you authorized can be leveraged by any malicious actor without your knowledge (i.e. mail.read would give me the ability to read every single user's email without you knowing about it).

If you need to use either the Client Credentials or Authorization Code grants, then you need to manage the tokens server-side. This ensures the client_secret isn't exposed on the client. Ideally, you should go one step further and store the secret in a Key Vault to provide an extra layer of protection.


updated with highlevel diagram

Below is a really high-level overview of how the Authorization Code might work here. Conceptually, the access_token only lives on the server. So when you need information from an API such as Graph, your app's frontend calls your app's backend, which in turn routes the call (along with the token) back to Graph.

There are a couple of big upsides to doing it this way:

  1. You get to control exactly what data gets sent to the client
  2. You can edit/revise the data before sending it off (i.e. maybe you want to always mask potentially risky data).
  3. You can merge your own data with Graph before returning it, allowing you to make a single call return the entire dataset rather than having to make multiple round trips.
  4. If you request the offline_access scope, you can get (and store) a refresh_token. This lets you refresh the access_token whenever you need without having to ask the user to authenticate against. In turn, this allows you to work with the user's data even when they are not online; a huge benefit if you have some long-running processes you'd rather run during downtimes rather than during your app's peak operation.

enter image description here

If you need to execute everything client-side, then you need to use the Implicit Grant. This requires the user to authenticate before your application can access the API.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...