Adal.js does not get tokens for external api endpoint resource

前端 未结 4 1689
时光取名叫无心
时光取名叫无心 2020-12-28 08:00

I\'m trying out adal.js with an Angular SPA (Single Page Application) web site that gets data from an external Web API site (different domain). Authentication against the SP

4条回答
  •  再見小時候
    2020-12-28 08:52

    I'm not sure if our setup is exactly the same, but I think it it comparable.

    I have a Angular SPA that uses and external Web API through Azure API Management (APIM). My code might not be best practice, but it works for me so far :)

    The SPAs Azure AD app has a delegated permission to access the External APIs Azure AD app.

    The SPA (is based upon the Adal TodoList SPA sample)

    app.js

    adalProvider.init(
        {
            instance: 'https://login.microsoftonline.com/', 
            tenant: 'mysecrettenant.onmicrosoft.com',
            clientId: '********-****-****-****-**********',//ClientId of the Azure AD app for my SPA app            
            extraQueryParameter: 'nux=1',
            cacheLocation: 'localStorage', // enable this for IE, as sessionStorage does not work for localhost.
        },
        $httpProvider
        );
    

    Snippet from the todoListSvc.js

    getWhoAmIBackend: function () {
            return $http.get('/api/Employee/GetWhoAmIBackend');
        },
    

    Snippets from the EmployeeController

    public string GetWhoAmIBackend()
        {
            try
            {
                AuthenticationResult result = GetAuthenticated();
    
                HttpClient client = new HttpClient();
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
    
                var request = new HttpRequestMessage()
                {
                    RequestUri = new Uri(string.Format("{0}", "https://api.mydomain.com/secretapi/api/Employees/GetWhoAmI")),
                    Method = HttpMethod.Get, //This is the URL to my APIM endpoint, but you should be able to use a direct link to your external API
    
                };
                request.Headers.Add("Ocp-Apim-Trace", "true"); //Not needed if you don't use APIM
                request.Headers.Add("Ocp-Apim-Subscription-Key", "******mysecret subscriptionkey****"); //Not needed if you don't use APIM
    
                var response = client.SendAsync(request).Result;
                if (response.IsSuccessStatusCode)
                {
                    var res = response.Content.ReadAsStringAsync().Result;
                    return res;
                }
                return "No dice :(";
            }
            catch (Exception e)
            {
                if (e.InnerException != null)
                    throw e.InnerException;
                throw e;
            }
        }
    
            private static AuthenticationResult GetAuthenticated()
        {
            BootstrapContext bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext as BootstrapContext;
            var token = bootstrapContext.Token;
    
            Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext authContext =
                new Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext("https://login.microsoftonline.com/mysecrettenant.onmicrosoft.com");
    
            //The Client here is the SPA in Azure AD. The first param is the ClientId and the second is a key created in the Azure Portal for the AD App
            ClientCredential credential = new ClientCredential("clientid****-****", "secretkey ********-****");
    
            //Get username from Claims
            string userName = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn) != null ? ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn).Value : ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email).Value;
    
            //Creating UserAssertion used for the "On-Behalf-Of" flow
            UserAssertion userAssertion = new UserAssertion(bootstrapContext.Token, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName);
    
            //Getting the token to talk to the external API
            var result = authContext.AcquireToken("https://mysecrettenant.onmicrosoft.com/backendAPI", credential, userAssertion);
            return result;
        }
    

    Now, in my backend external API, my Startup.Auth.cs looks like this:

    The external API Startup.Auth.cs

            public void ConfigureAuth(IAppBuilder app)
        {
            app.UseWindowsAzureActiveDirectoryBearerAuthentication(
                new WindowsAzureActiveDirectoryBearerAuthenticationOptions
                {
                    Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
                    TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidAudience = ConfigurationManager.AppSettings["ida:Audience"],
                        SaveSigninToken = true
                    },
                    AuthenticationType = "OAuth2Bearer"
                });
        }
    

    Please let me know if this helps or if I can be of further assistance.

提交回复
热议问题