Search code examples
asp.net-web-apiazure-active-directoryaccess-tokenbearer-token

Why do I get an HTML page as a response when using Access Token and the desired result when using ID Token? (Azure AD)


When I successfully login through my Web API with my Azure AD credentials, I receive the ID & Access Token.

I understood that a best practice to consume a Web API is to use an Access Token instead of an ID Token.

In Postman I use ID Token and can Access all data where Authorization is required. When using the Access Token to consume the API, I get a Microsoft HTML login page and a 200 OK Status

<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->
<!DOCTYPE html>
<html dir="ltr" class="" lang="en">

<head>
    <title>Sign in to your account</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=2.0, user-scalable=yes">
    <meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Expires" content="-1">
    <link rel="preconnect" href="https://aadcdn.msftauth.net" crossorigin>
    <meta http-equiv="x-dns-prefetch-control" content="on">
    <link rel="dns-prefetch" href="//aadcdn.msftauth.net">
    <link rel="dns-prefetch" href="//aadcdn.msauth.net">

    <meta name="PageID" content="ConvergedSignIn" />
    <meta name="SiteID" content="" />
    <meta name="ReqLC" content="1033" />
    <meta name="LocLC" content="en-US" />

    <meta name="referrer" content="origin" />

    <noscript>
        <meta http-equiv="Refresh" content="0; URL=https://login.microsoftonline.com/jsdisabled" />
    </noscript>
...

Solution

  • I could consume the Web API by using the ID-token with all token validation parameters set to false - in services.AddAuthentication... Startup.cs.

    I changed some Token Validation Parameters to true. I also use AcquireTokenByUsernamePassword to generate valid Access Tokens from Graph API:

    IPublicClientApplication app = PublicClientApplicationBuilder
        .Create(clientId)
        .WithAuthority(authority)
        .WithTenantId(tenantId)
        .Build();
    
    var securePassword = new SecureString();
    foreach (char c in user.Password.ToCharArray())  // fetch the password
        securePassword.AppendChar(c);  // keystroke by keystroke
    
    var tokens = app.AcquireTokenByUsernamePassword(scopes, user.UserName, securePassword).ExecuteAsync().Result;
    
    _graphServiceClient = new GraphServiceClient(
        new DelegateAuthenticationProvider(x =>
        {
            x.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken);
    
            return Task.FromResult(0);
        }));