I have IdentityServer project that runs on aspnetcore 1.1, Api project and MVC client projects that run on aspnetcore 2.0.
MVC client setup:
```C#
services.AddAuthentication(options => {
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationType;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(o => {
o.Cookie.HttpOnly = true;
})
.AddOpenIdConnect(o =>
{
o.Authority = Configuration["Settings:Authentication:Authority"];
o.ClientId = Configuration["Settings:Authentication:ClientId"];
o.ClientSecret = Configuration["Settings:Authentication:ClientSecret"];
o.SignInScheme = "Cookies";
o.RequireHttpsMetadata = !CurrentEnvironment.IsDevelopment();
o.ResponseType = "code id_token";
o.Scope.Add("api.read");
o.GetClaimsFromUserInfoEndpoint = true;
o.SaveTokens = true;
});
(Naturally app.UseAuthentication() is specified in the Configure method)
API setup
```C#
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
Authority = Configuration["Settings:Authentication:Authority"],
RequireHttpsMetadata = !CurrentEnvironment.IsDevelopment(),
ApiName = Configuration["Settings:Authentication:ApiName"],
ApiSecret = Configuration["Settings:Authentication:ApiSecret"],
EnableCaching = true,
CacheDuration = TimeSpan.FromMinutes(10),
AutomaticAuthenticate = true,
AutomaticChallenge = true
});
API call from the client app:
```C#
var accessToken = await HttpContext.GetTokenAsync("access_token");
var client = new HttpClient();
client.SetBearerToken(accessToken);
var content = await client.GetAsync("http://localhost:5001/test");
(The **test** method of the API is decorated with [Authorize] attribute)
The issue:
MVC method decorated with [Authorize] attribute invokes Login workflow and everything goes well. After that I can invoke the MVC method that calls the API, and that's where the problem is.
API project throws an Exception **No authenticationScheme was specified, and there was no DefaultChallengeScheme found.**
What's also interesting, debug console for the API project lists following(Parts removed for brevity):
...
IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationMiddleware: Warning: No validator configured for reference token. Ensure ApiName and ApiSecret have been configured to use introspection.
IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationMiddleware: Warning: No validator configured for reference token. Ensure ApiName and ApiSecret have been configured to use introspection.
IdentityServer4.AccessTokenValidation.Infrastructure.NopAuthenticationMiddleware: Information: Bearer was not authenticated. Failure message: No token found.
IdentityServer4.AccessTokenValidation.Infrastructure.NopAuthenticationMiddleware: Information: Bearer was not authenticated. Failure message: No token found.
...
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization failed for user: (null).
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization failed for user: (null).
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Microsoft.AspNetCore.Mvc.ChallengeResult: Information: Executing ChallengeResult with authentication schemes ().
Microsoft.AspNetCore.Mvc.ChallengeResult: Information: Executing ChallengeResult with authentication schemes ().
Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNetCore.Authentication.Core.dll
Exception thrown: 'System.InvalidOperationException' in mscorlib.dll
...
It's also worth noting that I use **reference** type access tokens.
What I want to know is, did I do something wrong here, or is it just the fact that API and MVC client use aspnetcore 2.0?
Also, why is **No validator configured for reference token. Ensure ApiName and ApiSecret have been configured to use introspection.** warning being thrown if I obviously set both ApiName and ApiSecret?
Edit:
After some more researching, if I specify adding cookie and openidconnect with first parameter being AuthenticationScheme, then not even the first Login workflow works, but the **No authenticationScheme was specified, and there was no DefaultChallengeScheme found** exception is thrown again.
.AddCookie("Cookies", o => {
o.Cookie.HttpOnly = true;
})
.AddOpenIdConnect("oidc", o =>
{ ... }
```
@brockallen @leastprivilege any clue guys? I'm wrestling with this for days now, could really use help.
I tried replacing app.UseIdentityServerAuthentication with
C#
services.AddAuthentication(o =>
{
o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(o =>
{
o.Audience = Configuration["Settings:Authentication:ApiName"];
o.Authority = Configuration["Settings:Authentication:Authority"];
o.RequireHttpsMetadata = !CurrentEnvironment.IsDevelopment();
});
In my API project, but keep getting exception IDX10500: Signature validation failed. No security keys were provided to validate the signature.
I am also experiencing this problem, and have reproduced both errors with similar configurations. I believe it may be related to the IDServer4 middleware not being supported in .net core 2.0 yet.
Correct -- Microsoft changed the security architecture from 1.x to 2.0. Our 1.x versions assume the old architecture, so they're simply not yet supported on 2.0 because we've not changed them yet. We're working on it.
I solved it by using Microsoft's implementation of JwtBearer validation. If anyone stumbles on the same problem this is how authentication is defined in my API now:
C#
services.AddAuthentication(o =>
{
o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(o =>
{
// my API name as defined in Config.cs - new ApiResource... or in DB ApiResources table
o.Audience = Configuration["Settings:Authentication:ApiName"];
// URL of Auth server(API and Auth are separate projects/applications),
// so for local testing this is http://localhost:5000 if you followed ID4 tutorials
o.Authority = Configuration["Settings:Authentication:Authority"];
o.RequireHttpsMetadata = !CurrentEnvironment.IsDevelopment();
o.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = true,
// Scopes supported by API as defined in Config.cs - new ApiResource... or in DB ApiScopes table
ValidAudiences = new List<string>() {
"api.read",
"api.write"
},
ValidateIssuer = true
};
});
You're going to need using Microsoft.AspNetCore.Authentication.JwtBearer and don't forget app.UseAuthentication() in the Configure method.
MVC client configuration stayed the same as above.
And also, reference tokens don't work with this middleware(at least I can't get them to work)
We'll be updating our other middlewares next week. Look for updates/previews then.
Here's how I fixed the IDX10500: Signature validation failed. No security keys were provided to validate the signature. error message in my code: https://stackoverflow.com/a/46108023/250094
I have the same problem too. When a user (not logged) tries to access a controller with the [Authorize] attribute, the MVC client goes to my ID4 server, the user can successfully log-in but at this very moment, when the token is supposed to get back to the MVC client, I get an error message.
MVC Client and API Server run on Core 2.0, ID4 server run on Core 1.
Could someone help me? Thx
@hugo9773 Have you tried implementing my solution?
@nixa333 Yes I did but still the same problem. Using breakpoints in VisualStudio (in ID4 project), I found that the error fires when ID4 tries to bring the user to the mvc client, like if the url wasn't valid (http://"clienturl"/connect/...). Maybe I'm missing something else..?
I'm also experiencing this issue, when I try accessing a controller decorated with AuthorizedAttribute I get an InvalidOperationException with the message as in the title ("
I tried upgrading to the 2..rc-update1 package, but had the UseIdentityServerAuthentication extension disappear.
I am using a WebAPI only app and I don't want to give up all the work with setting up the Clients scope configuration etc.
Meanwhile I reverted back to the old code and changed my code to catch the exception as a temporary solution:
app.UseExceptionHandler(options =>
options.Run(async (context) =>
{
var feature = context.Features.Get<IExceptionHandlerFeature>();
(string Error, int StatusCode) result = (default, StatusCodes.Status500InternalServerError);
switch (feature?.Error)
{
case null:
goto default;
case InvalidOperationException e when e.HResult == -2146233079:
//e.Message == "No authenticationScheme was specified, and there was no DefaultChallengeScheme found.":and there was no DefaultChallengeScheme found.":
result.StatusCode = StatusCodes.Status403Forbidden;
result.Error = $"The user '{context.User.Identity.Name}' is not authorized to access the page '{context.Request.Path}'.";
break;
default:
result.Error = "Unspecified error";
break;
}
context.Response.StatusCode = result.StatusCode;
await context.Response.WriteAsync(result.Error);
}));
Is there a way to use MS JWT BearerTokens with IdentityServer Client, Scopes etc.?
@nixa333 I have tried your code and it worked. (Y) Thanks. But I have to comment this line below:
o.RequireHttpsMetadata = !CurrentEnvironment.IsDevelopment();
Also can you please explain your code especially what does it mean:
o.Audience = Configuration["Settings:Authentication:ApiName"];
and this
o.Authority = Configuration["Settings:Authentication:Authority"];
@mfuzailzubari
But I have to comment this line below
Perhaps your environment isn't configured as development, so it's requiring HTTPS.
Also can you please explain your code
Those settings are retrieved from the _appsettings.json_ file (read this for more.
I had this problem in a client and did the following:
install-package Microsoft.AspNetCore.Authentication
install-package Microsoft.AspNetCore.Authentication.Cookies # for cookie-based auth
install-package Microsoft.AspNetCore.Authentication.JwtBearer # for JWT-based auth
Startup.Configure: app.UseAuthentication();
Startup.ConfigureServices. Example for JWT-based Bearer-authentication only: services.AddAuthentication(options =>
{
options.DefaultScheme = "bearer"; // this is the default scheme to be used
options.DefaultChallengeScheme = "bearer";
})
// we configure JWT bearer authentication here
.AddJwtBearer("bearer", options =>
{
options.Authority = "https://localhost:5000"; // URL of Identity Server; use IConfiguration instead of hardcoding
options.Audience = "client.mydomain.com"; // ID of the client application; either hardcoded or configureable via IConfiguration if needed
options.RequireHttpsMetadata = true; // require HTTPS (may be disabled in development, but advice against it)
options.SaveToken = true; // cache the token for faster authentication
options.IncludeErrorDetails = true; // get more details on errors; may be disabled in production
});
@MovGP0 what do you mean by use IConfiguration? example?
@ColbyBurke see the ASP.NET Core documentation
I do it like the following:
public static void Setup(IConfiguration configuration)
{
// <snip />
options.Authority = configuration["TokenServer:Authority"];
// <snip />
}
Im a noob. @MovGP0 is it the same if youre using signalR?
haven't tried SignalR yet, but I guess there should be no difference.
So @MovGP0 I have the following:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSignalR();
services.AddAuthentication();
}
Am I missing something, like IConfiguration not supposed to be there? I knew I need to add more to ConfigurationServices I just dont know what to add.
@ColbyBurke this code seems totally fine to me. just use the configuration that you have already injected.
word. thanks
@MovGP0 if its getting me to the localhost but not showing anything, is it a problem unrelated to this?
@nixa333 could you please share your working appsettings.json configuration for the above code
thanks
@embryologist For local development Settings:Authentication:ApiName = "apiResource", Settings:Authentication:Authority = "http://localhost:5000" (this is the IdentityServer project). For production environment, replace Settings:Authentication:Authority value with URL to your Identity Server application.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
I solved it by using Microsoft's implementation of JwtBearer validation. If anyone stumbles on the same problem this is how authentication is defined in my API now:
C# services.AddAuthentication(o => { o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(o => { // my API name as defined in Config.cs - new ApiResource... or in DB ApiResources table o.Audience = Configuration["Settings:Authentication:ApiName"]; // URL of Auth server(API and Auth are separate projects/applications), // so for local testing this is http://localhost:5000 if you followed ID4 tutorials o.Authority = Configuration["Settings:Authentication:Authority"]; o.RequireHttpsMetadata = !CurrentEnvironment.IsDevelopment(); o.TokenValidationParameters = new TokenValidationParameters { ValidateAudience = true, // Scopes supported by API as defined in Config.cs - new ApiResource... or in DB ApiScopes table ValidAudiences = new List<string>() { "api.read", "api.write" }, ValidateIssuer = true }; });You're going to need using Microsoft.AspNetCore.Authentication.JwtBearer and don't forget app.UseAuthentication() in the Configure method.
MVC client configuration stayed the same as above.
And also, reference tokens don't work with this middleware(at least I can't get them to work)