IdentityServer / IdentityServer4.AccessTokenValidation

IdentityServer Access Token Validation for ASP.NET Core
Apache License 2.0
544 stars 214 forks source link

Support for ASP.NET Core 2.0.0 #72

Closed martincostello closed 7 years ago

martincostello commented 7 years ago

Due to the various types being moved around in ASP.NET Core 2.0.0, it's not possible to reference this in a project targeting netstandard2.0.

leastprivilege commented 7 years ago

True. If all you need is JWT validation, we recommend using Microsoft's JwtBearer for the time being.

maganuk commented 7 years ago

Any chance this will get an upgrade to core 2? We're using reference tokens.

fjlucas commented 7 years ago

We also have our application working with core 1.1. We are waiting for this update in order to be able to migrate it the 2.0. Any roadmap for this feature?

pjmagee commented 7 years ago

Same here. Migrating to dotnet core 2.0 but having issues due to this. Worth re-working to use Microsoft JwtBearer?

pjmagee commented 7 years ago

I replaced this nuget package with the Microsoft.AspNetCore.Authentication.JwtBearer and the below code worked well as a replacement.

services
    .AddAuthentication((options) =>
    {
        options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters();
        options.RequireHttpsMetadata = false;
        options.Audience = identityServerConfig.Audience;
        options.Authority = identityServerConfig.Authority;
    });
SuperJMN commented 7 years ago

Please, check this: https://github.com/IdentityServer/IdentityServer4.AccessTokenValidation/issues/75

abakumov-v commented 7 years ago

Hi! @pjmagee tell me please, what is the identityServerConfig variable?

pjmagee commented 7 years ago

That's just a configuration object that reads from app.settings.json basically, with our actual product values. i.e the audience value which should be the same value used on the identity server and the authority is the actual url to the identity server. E.g audience field would be "api openid profile" and the identity server value would just be something like "http://productidentityserver.internal.domain:8082/"

SuperJMN commented 7 years ago

Is there a workaround to use ADFS? Thanks!

leastprivilege commented 7 years ago

I just pushed 2.0.0-rc1 to nuget. Give it a try.

bouassaba commented 7 years ago

@leastprivilege I just tried the 2.0.0-rc1 you pushed some houres ago, but I'm struggling in getting the new services.AddAuthentication().AddIdentityServerAuthentication() in Startup.ConfigureServices() to work with [Authorize] on the controller. I'm doing something similar to this:

In Startup.cs:

services.AddAuthentication()
    .AddIdentityServerAuthentication(options =>
    {
        options.Authority = Configuration["Url"];
    options.RequireHttpsMetadata = false;
    options.ApiName = "api";
    );

In ValuesController.cs:

[Authorize]
[Route("api/[controller]")]
public class ValuesController : Controller
{
    // ... omitted for simplicity
}

In the logs I get the following:

      Request successfully matched the route with name '(null)' and template 'api/Values'.
dbug: Microsoft.AspNetCore.Mvc.Internal.ActionSelector[2]
      Action 'WebApplication1.Web.Controllers.ValuesController.Post (WebApplication1.Web)' with id '6aef0e78-7902-4c78-9bde-e8706f85bb09' did not match the constraint 'Microsoft.AspNetCore.Mvc.Internal.HttpMethodActionConstraint'
dbug: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      Executing action WebApplication1.Web.Controllers.ValuesController.Get (WebApplication1.Web)
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      Authorization failed for user: (null).WebApplication1
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3]
      Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
info: Microsoft.AspNetCore.Mvc.ChallengeResult[1]
      Executing ChallengeResult with authentication schemes ().
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[12]
      AuthenticationScheme: Identity.Application was challenged.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action WebApplication1.Web.Controllers.ValuesController.Get (WebApplication1.Web) in 42.9723ms
dbug: Microsoft.AspNetCore.Server.Kestrel[9]
      Connection id "0HL7ODNDLMNDH" completed keep alive response.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 93.8871ms 302
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/Account/Login?ReturnUrl=%2Fapi%2Fvalues
dbug: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[9]
      AuthenticationScheme: Identity.Application was not authenticated.
dbug: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[9]
      AuthenticationScheme: Identity.Application was not authenticated.
trce: IdentityServer4.Hosting.EndpointRouter[0]
      No endpoint entry found for request path: /Account/Login
dbug: Microsoft.AspNetCore.Builder.RouterMiddleware[1]
      Request did not match any routes.
dbug: Microsoft.AspNetCore.Server.Kestrel[9]
      Connection id "0HL7ODNDLMNDH" completed keep alive response.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 26.4759ms 404

At the end I'm getting a 404.

I have the IdentityServer and the API in the same project (I don't think this should have any side affects).

Any idea how can I get it working ? I looked in the samples, but they all still use the old app.UseIdentityServerAuthentication() in Startup.Configure().

EDIT: Forgot to initially mention that I'm trying to use the JWT Authentication Scheme.

Thanks.

leastprivilege commented 7 years ago

see here

https://github.com/IdentityServer/IdentityServer4.Samples/blob/dev/Clients/src/SampleApi/Startup.cs#L23-L31

Having the API and IdentityServer in the same app does have side effects - unless you really know how the new authN system in asp.net core 2 works. For simplicity I would recommend separating them.

bouassaba commented 7 years ago

Following your example (which doesn't use app.UseIdentityServer() because it's client code only), I couldn't get neither http://localhost/.well-known/openid-configuration nor http://localhost/connect/tokento work.

I guess that these endpoints are still provided only by app.UseIdentityServer() ?

After adding app.UseIdentityServer(), the endpoints I mentioned above are now working, but the generated Bearer Token is not able to authenticate the controller endpoint which results in a 404.

When looking at the logs, I see the following:

      Request starting HTTP/1.1 GET http://localhost:5000/Account/Login?ReturnUrl=%2Fapi%2Fvalues
dbug: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[9]
      AuthenticationScheme: Identity.Application was not authenticated.
dbug: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[9]
      AuthenticationScheme: Identity.Application was not authenticated.
dbug: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[9]
      AuthenticationScheme: Identity.Application was not authenticated.
trce: IdentityServer4.Hosting.EndpointRouter[0]
      No endpoint entry found for request path: /Account/Login

The log says that it somehow uses the CookieAuthenticationHandler and trying to find some sort of /Account/Login endpoint. This tells me that the Bearer Authentication Workflow is not enabled.

Maybe I missed something ?

bouassaba commented 7 years ago

I figured it out.

In case somebody faces the same issues like me, the reason that happened is that I forgot to make a separate project for the API as @leastprivilege mentioned.

bouassaba commented 7 years ago

Having the IdentityServer + API in the same project is something that it's not supported because of the latest changes in IdentityServer4 or the new ASP.NET Core 2.0 Authentication System ?

leastprivilege commented 7 years ago

It is "supported" - but to get started, it is easier to separate them. Once you have that working you can take the next step.

bouassaba commented 7 years ago

Thanks, I got it working now.

Is there any samples that I can look into that shows how to run IdentityServer4 + API (ASP.NET Core 2.0) in the same project ?

leastprivilege commented 7 years ago

No - but I guess you need to explicitly reference the token validation middleware in the authorize attribute - something like

[Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme]

maganuk commented 7 years ago

Working well for me with introspection and api in the same project.

omerlh commented 7 years ago

In my case, API and IdentityServer are running on a different project with different URLs. I follow all the samples here, but I still had to use [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme] in order to authenticate requests. Without adding this, requests will fail with 401 error. Is that required now in .net core 2?

leastprivilege commented 7 years ago

see here

https://github.com/IdentityServer/IdentityServer4.Samples/blob/dev/Clients/src/SampleApi/Startup.cs#L23

omerlh commented 7 years ago

Apparently, the order has a meaning. I had:

app.UseMvc();
app.UseAuthentication();

changed to

app.UseAuthentication();
app.UseMvc();

And now things are working...

andymac4182 commented 7 years ago

@omerlh That is the order that the middleware is executed.

future81 commented 6 years ago

I had InvalidOperationException: No authenticationScheme was specified, and there was no DefaultChallengeScheme found. so I needed to add this:


services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(x=>
{
                    x.Authority = "xxx";
                    x.ApiName = "xxx";
                    x.RequireHttpsMetadata = false;
});

and in configure method: app.UseAuthentication(); services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme) Adds the default schema you can use :

[Authorize] only in that case. of course You'll need to add package and using IdentityServer4.AccessTokenValidation; This applies to IdentityServer4.AccessTokenValidation ver 2.1