Search code examples
asp.netasp.net-core-webapiazure-identity

.Net core 6 API authentication with client credentials


API's authentication configfiguration code looks like the following:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                                    .AddMicrosoftIdentityWebApi(jwtBearerOptions =>
                                    { }, msIdentityOptions =>
                                    {
                                        configuration.Bind("AzureAd", optionsB);
                                        var defaultBackChannel = new HttpClient();
                                        defaultBackChannel.DefaultRequestHeaders.Add("Origin", "shard-manager");
                                        msIdentityOptions.Backchannel = defaultBackChannel;
                                        
                                    })
                                    .EnableTokenAcquisitionToCallDownstreamApi(e => { })
                                    .AddInMemoryTokenCaches();

I want to authenticate using a client Id and client secret and call and endpoint in the API. I can authenticate the app registration azure successfully but when I use the access token to send request to the API it returns 401 unauthorized.

I get the same 401 result when I send the request using postman with access token.

App registration:

enter image description here

enter image description here

Postman:

enter image description here

Not sure what I am missing here.


Solution

  • Note that: As you are using Client credential flow, you have to grant application permissions. For delegated type permissions you have to make use of any user interactive flow such as Authorization code flow.

    I created an Azure AD Application and exposed an API like below:

    enter image description here

    When the scope is added in the API permission blade it is delegated type:

    enter image description here

    Now I generated access token using Client Credential Flow via Postman:

    https://login.microsoftonline.com/TenantID/oauth2/v2.0/token
    
    client_id:ClientID
    client_secret:ClientSecret
    scope:api://ClientID/.default
    grant_type:client_credentials
    

    enter image description here

    When I decoded the access token, scope is not displayed:

    enter image description here

    When I called the API, I got 401 unauthorized error:

    GET https://apiendpoint/weatherforecast
    

    enter image description here

    If you want to use Client credential flow only then create App roles:

    enter image description here

    Now the role is added as Application type permissions:

    enter image description here

    I generated the access token and when decoded it displays the role:

    enter image description here

    Otherwise, for delegated API permissions make use of Authorization Code Flow:

    Generated auth-code using below endpoint:

    https://login.microsoftonline.com/TenantID/oauth2/v2.0/authorize?
    &client_id=ClientID
    &response_type=code
    &redirect_uri=https://jwt.ms
    &response_mode=query
    &scope=api://ClientID/.default
    &state=12345
    

    enter image description here

    Generated access token by using below parameters:

    https://login.microsoftonline.com/TenantID/oauth2/v2.0/token
    
    client_id:ClientID
    scope:api://ClientID/.default
    grant_type:authorization_code
    redirect_uri:https://jwt.ms
    code:code
    client_secret:ClientSecret
    

    enter image description here

    When I decoded the access token, scopes displayed like below:

    enter image description here

    I am able to call the API successfully:

    GET https://apiendpoint/weatherforecast
    

    enter image description here

    • Make sure to update accessTokenAcceptedVersion property set to 2 in the manifest.

    You can refer this SO Thread by me for sample code for Authorization Code Flow by changing the scope.

    Reference:

    azureactive-directory-aspnetcore-webapp· GitHub by jennyf19