Search code examples
c#asp.net-coreidentityserver4

Get accessToken in Identity Server ASP.NET Core


I'm using IdentityServer with an ASP.NET Core MVC applications.

In IdentityServer my client defined like this:

new Client
    {
        ClientId = "admin.client",
        ClientName = "Admin Application",
        AllowedGrantTypes = GrantTypes.Implicit,
        ClientSecrets =
                        {
                            new Secret("secret".Sha256())
                        },
        RedirectUris = { "http://localhost:45876/signin-oidc" },
        PostLogoutRedirectUris = { "http://localhost:45876/signout-callback-oidc" },
        AllowedCorsOrigins = new[] { "http://localhost:45876/" },
        AllowedScopes =
                        {
                            IdentityServerConstants.StandardScopes.OpenId,
                            IdentityServerConstants.StandardScopes.Profile
                        },
        AllowOfflineAccess = true
}

And client register like this:

services.AddAuthentication(
            options =>
                {
                    options.DefaultScheme = "Cookies";
                    options.DefaultChallengeScheme = "oidc";
                })
            .AddCookie("Cookies")
            .AddOpenIdConnect(
                "oidc",
                options =>
                    {
                        options.SignInScheme = "Cookies";

                        options.Authority = "http://localhost:5001/";
                        options.RequireHttpsMetadata = false;


                        options.ClientId = "admin.client";
                        options.ClientSecret = "secret";
                        options.ResponseType = "code id_token";
                        options.SaveTokens = true;
                        options.GetClaimsFromUserInfoEndpoint = true;

                        options.Scope.Add("openid");
                        options.Scope.Add("profile");
                    });

My problem is when I want to get accessToken that is null.

I'm trying to get it with this code:

 var token = await _httpContextAccessor.HttpContext.GetTokenAsync("access_token");
 string accessToken = User.FindFirst("access_token")?.Value;

Both of them return null.

Where is my problem?


Solution

  • The first problem is that you are config the client application to use the Hybrid flow to interact with IdentityServer :

     options.ResponseType = "code id_token";
    

    But the client config is only allowed to use Implicit flow :

     AllowedGrantTypes = GrantTypes.Implicit,
    

    That will threw invalid grant type error during the authentication request .

    The second problem is that you didn't config the ApiResource :

    public static IEnumerable<ApiResource> GetApis()
    {
        return new List<ApiResource>
        {
            new ApiResource("api1", "My API")
        };
    }
    

    The client is also not request the permission to access api resource , although you can make your client application authenticate user with identity server , it will return back ID token , not Access token :

    • ID token contains at a bare minimum an identifier for the user (called the sub aka subject claim) and information about how and when the user authenticated

    • Access token allows access to an API resource , contain information about the client and the user (if present).

    Since you are using web application(mvc as client app) . A better choice to to use hybrid flow , which enables both API access and user authentication. Here is code sample .