Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IdentityServer4 ValidIssuers

Is there any way to tell IdentityServer4's authentication system to allow multiple issuers for the tokens?

I have an application that is using Identity Server to issue bearer tokens, and as long as the front end and the back end use the same URL to get tokens from authentication works fine.

However, I now have a need to have the same site accessed through multiple CNAMEs, meaning that the client will request tokens from two different URLs.

The error that is sent to the logs is:

info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware[7]

Bearer was not authenticated. Failure message: IDX10205: Issuer validation failed. Issuer: 'http://domainb.com'. Did not match: validationParameters.ValidIssuer: 'http://domaina.com' or validationParameters.ValidIssuers: 'null'.

The presence of a ValidIssuers collection seems to indicate that you can set multiple places from which the API will accept tokens, but I cannot find anything like that exposed in options exposed by UseIdentityServerAuthentication.

I am aware of the Authority option, but that only allows me to set a single valid authority.

Is there are any way of setting multiple valid issuers, or setting it to use something other than the hostname as the issuer id?

UPDATE

My identity server configuration on the server side looks like this:

services.AddIdentityServer(options => { 
                             options.IssuerUri = "http://authserver"; })
     .AddAspNetIdentity<ApplicationUser>();

this is from the auth server side of things.

On the client API, the UseIdentityServerAuthentication call looks like this:

app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions()
{
    Authority = AppSettingsConfigurationRoot["Authentication:AuthorityEndpoint"],
    RequireHttpsMetadata = false,
    ApiName = "rqapi",
    AutomaticAuthenticate = true,
    ClaimsIssuer = "http://localhost:5001"
});

The address in the {{AppSettingsConfigurationROot["Authentication:AuthorityEndpoint"] is usually set at the public DNS name of the server so that the token issuer as seen by AngularJS matches the URL of the IdentityServer from the point of view of the C# API.

like image 548
Richard Comish Avatar asked Apr 20 '18 22:04

Richard Comish


People also ask

Is IdentityServer4 obsolete?

Rebranding. IdentityServer will be rebranded as Duende IdentityServer. IdentityServer4 support will last until the end of life of . NET Core 3.1 that means till November 2022.

What is the use of IdentityServer4?

IdentityServer is an authentication server that implements OpenID Connect (OIDC) and OAuth 2.0 standards for ASP.NET Core. It's designed to provide a common way to authenticate requests to all of your applications, whether they're web, native, mobile, or API endpoints.

What is redirect URI in IdentityServer4?

the allowed interactions with the token service (called a grant type) a network location where identity and/or access token gets sent to (called a redirect URI)


1 Answers

As Original Poster wrote in a comment, the (now, 2020, deprecated) IdentityServer4.AccessTokenValidation package doesn't expose the right options. To read more about the recent deprecation check this blogpost, but if you still are using it, here's how I solved this issue.

The AddIdentityServerAuthentication(...) extension method is a wrapper (the code is super readable!) to combine two authentication schemes:

  1. JwtBearer
  2. OAuth2Introspection

It uses its own configuration class, and simply doesn't expose all the JwtBearer options (possibly just an omission, possibly because some options are not valid for both schemes.

If -like me- you only need JwtBearer you might get away with simply using just that, and using the ValidIssuers array. So:

services.AddAuthentication("Bearer")
    .AddJwtBearer(options =>
    {
        options.Authority = "https://example.org";
        options.Audience = "foo-api"; // options.ApiName in the IDS4 variant
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidIssuers = new[]
            {
                "https://example.org", // first issuer
                "https://example.com", // some other issuer
            },
            NameClaimType = "name", // To mimick IDS4's variant
            RoleClaimType = "role", // To mimick IDS4's variant
        };
    });

As far as I understand, this will use example.org as the Authority and get the openid-configuration and so forth from that domain. But any JWT token offered to this API would be accepted as long as one of the ValidIssuers is the iss (issuer claim) in the token.

like image 196
Jeroen Avatar answered Oct 09 '22 23:10

Jeroen