Epistemologist
Epistemologist

Reputation: 1091

Identity Server 4 internal API

I am using Identity Server 4 and adding more API end points to be used but I can't seem to make it working correctly. When I send a call to identity server api with access token it says

Microsoft.IdentityModel.Tokens.SecurityTokenInvalidAudienceException: IDX10214: Audience validation failed.

And API name Claims is not in access token. I am using DB configuration stores.

Here how I have configured Identity server 4.

Startup.cs

    services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));

            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddIdentity<ApplicationUser, IdentityRole>(options=>
                {
                    // example of setting options
                    options.Tokens.ChangePhoneNumberTokenProvider = "Phone";

                    // password settings chosen due to NIST SP 800-63
                    options.Password.RequiredLength = 3; // personally i'd prefer to see 10+
                    options.Password.RequiredUniqueChars = 0;
                    options.Password.RequireDigit = false;
                    options.Password.RequireLowercase = false;
                    options.Password.RequireUppercase = false;
                    options.Password.RequireNonAlphanumeric = false;
                })
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

            // Add application services.
            services.AddTransient<IEmailSender, EmailSender>();

            services.AddMvc();

            var migrationsAssembly = typeof(StartupDevelopment).GetTypeInfo().Assembly.GetName().Name;
            // configure identity server with in-memory stores, keys, clients and scopes
            services.AddIdentityServer(options =>
                    {
                        options.Discovery.CustomEntries.Add("Claims", "/api/claims");                         
                    }
                )                
                .AddDeveloperSigningCredential()
                .AddDeveloperSigningCredential()             
                .AddConfigurationStore(options =>
                {
                    options.ConfigureDbContext = builder =>
                        builder.UseSqlServer(Configuration.GetConnectionString("ConfigurationStore"),
                            sql => sql.MigrationsAssembly(migrationsAssembly));
                })                
                .AddOperationalStore(options =>
                {
                    options.ConfigureDbContext = builder =>
                        builder.UseSqlServer(Configuration.GetConnectionString("OperationalStore"),
                            sql => sql.MigrationsAssembly(migrationsAssembly));

                    // this enables automatic token cleanup. this is optional.
//                    options.EnableTokenCleanup = true;
//                    options.TokenCleanupInterval = 30;
                })               
                .AddAspNetIdentity<ApplicationUser>();

            services.AddAuthentication()
                .AddIdentityServerAuthentication("token", isAuth =>
                {
                    isAuth.Authority = IdentityServerConfigurations.Authority;
                    isAuth.ApiName = "claims"; // TODO change this name to refelect broader api changes
                    isAuth.RequireHttpsMetadata = IdentityServerConfigurations.Ssl;
                });

Config.cs

new Client
                {
                    ClientId = "mvc",
                    ClientName = "MVC Client",
                    AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,

                    RequireConsent = false,

                    AccessTokenLifetime = 300,                           
                    UpdateAccessTokenClaimsOnRefresh = true,                                                                    
                    ClientSecrets = 
                    {
                        new Secret("secret".Sha256())
                    },

                    RedirectUris = { "https://localhost:44383/signin-oidc" },
                    PostLogoutRedirectUris = { "https://localhost:44383/signout-callback-oidc" },


                    AllowedScopes =
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        IdentityServerConstants.StandardScopes.Address,
                        "claims"                               
                    },
                    AllowOfflineAccess = true
                }

In ClaimsController

[Authorize(AuthenticationSchemes = "token")] 

Upvotes: 0

Views: 667

Answers (2)

Epistemologist
Epistemologist

Reputation: 1091

OK I was missing configuration to request a scope from client side.

options.Scope.Add("claims");

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

Upvotes: 1

Aeseir
Aeseir

Reputation: 8434

Can't see token validation implementation here, which is what is used for "token".

You need to implement Token Validation Handler if you want it to be able to use the token to access the custom api (with the "token").

Please have a look at the documentation for example on how this is done:

http://docs.identityserver.io/en/release/topics/apis.html#refprotectingapis

Upvotes: 0

Related Questions