1
votes

I am switching my application from Azure Active Directory authentication to authentication with Identity Server (using Azure AD as external auth). The authentication and authorization part is implemented and my web API successfully validates token and give me what I'm asking.

Our application also uses external APIs, such as Graph API and SharePoint Online which require Azure AD token. E.g. when I go to https://graph.microsoft.com/v1.0/me from my JS application with token that I get back from Identity Server, Graph API response is

401
{
  "error": {
    "code": "InvalidAuthenticationToken",
    "message": "Access token validation failure.",
    "innerError": {
      "request-id": "ce7651bb-5dc4-49e9-90ff-02df440ed4ad",
      "date": "2017-08-11T08:53:12"
    }
  }
}

I expected that because Identity Server is giving me his token, and not passing the existing token that is provided by Azure AD. I copied all the claims from Azure AD token into identity server token, but no changes.

What would be the right approach to enable my application to continue using APIs which require Azure AD token?

EDIT:

What I'm hoping for is this.

  1. Click login button on Js (or any other client app)
  2. Redirect to Identity Server login screen
  3. Click on Azure AD external auth
  4. Redirect to Microsoft login page and enter your credentials there
  5. Redirect to Identity server app

    a. I started Fiddler and see that "Microsoft" redirect to {IdentityServerAppUrl}/signin-aad (I suppose this is because I configured CallbackPath property on OpenID Connect options). This request carry a cookie idsrv.external. I'm not sure but I think inside is access token from Azure AD. I don't know how to decode this. I tried with base64, but it is not working.

    b. When this request is finished redirect is made to {IdentityServerAppUrl}/account/ExternalLoginCallback. In this action method I check with debugger all fields and data in request but I can't find token from AAD. I'm hoping to get token and put it in additional calims.

  6. Identity Server app redirect to JS client app with its own token and additional claim that contains Azure AD token that is valid on graph API and SharePoint.

First I would like to locate Action method or middleware that handle {IdentityServerAppUrl}/signin-aad?

Second, is there any way to get token from Azure AD or any other external provider inside {IdentityServerAppUrl}/account/ExternalLoginCallback Action method?

Be aware that I'm new to this kind of stuff and maybe I'm totally wrong with this thinking.

I manage to do Azure AD authentication without Identity Server, but know we have request to have multiple external providers and I'm hoping to handle all authentication in one app. If one day I get request to have additional external provider I need to add to just in one place.

2
You could try getting access token for microsoft graph api with OpenID Connect ASP.Net OWIN middleware in identity server , then store the access token/refresh token with user identify information in database . Searching access token/refresh token in database with user identity to call microsoft graph .Nan Yu
This solution passed through my head, but I was hoping to find something more simpler. Something like tell Identity server 4 to user AzureAd token instead to create his own. Bus just for external auth for AzureAd for other providers use default behavior.Alan Jagar

2 Answers

3
votes

You need to retrieve an access token from AAD for the Graph API - how that exactly works, check the Microsoft documentation.

Once you have that access token, you can return it as a claim in either the IdentityServer identity or access token (depending if you want to make it available to your front or back-end).

You can also try that first in a simple MVC app to remove the moving partsy - and once you have the AD part working, move your code to the app using the identityserver middleware.

2
votes

I am also looking for an answer to this question. However, I think it should work a bit differently. IdentityServer gives you a JWT that you can use to authorize to the recources that make up your app. E.g.: yourAPI-1 and yourAPI-2. With the JWT you can pass on the identity. Microsoft Graph is an external resource. Therefore we would need the access token form the Graph API as a claim or external resource, same way as you'd receive an access token for an internal resource.

I would guess that there should be a way of forwarding whatever information you get from the identity provider (Azure AD) to IdentityServer for your client (JS app) to pick up. I am facing the same problem here.

There is another thread about this topic that caught my attention which I will look into. It requires to build your IdentityServer from the source with a few modifications: ASP.NET Identity (with IdentityServer4) get external resource oauth access token

I will let you know what the outcome is and push it to a git repo that you can use if it works: