AspNetCore.Authentication.JwtBearer 失败,没有 SecurityTokenValidator 可用于带有 .net core RC2 的令牌 [英] AspNetCore.Authentication.JwtBearer fails with No SecurityTokenValidator available for token with .net core RC2

查看:37
本文介绍了AspNetCore.Authentication.JwtBearer 失败,没有 SecurityTokenValidator 可用于带有 .net core RC2 的令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试让一个简单的端点正常工作,该端点使用 AspNew.Security.OpenIdConnect.Server 发出并使用 JWT 令牌,以发出令牌并使用 Microsoft.AspNetCore.Authentication.JwtBearer 进行验证.

I'm trying to get a simple endpoint working that issues and consumes JWT tokens using AspNew.Security.OpenIdConnect.Server to issue the token and validating using Microsoft.AspNetCore.Authentication.JwtBearer.

我可以很好地生成令牌,但尝试对令牌进行身份验证失败,并出现错误 Bearer 未通过身份验证.失败消息:没有可用于令牌的 SecurityTokenValidator:{token}

I can generate the token fine but trying to authenticate the token fails with the error Bearer was not authenticated. Failure message: No SecurityTokenValidator available for token: {token}

在这一点上,我已经剥离了所有内容并拥有以下内容:

At this point I've stripped everything out and have the following:

项目.json

{
  "dependencies": {
    "Microsoft.AspNetCore.Mvc": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.Json": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging.Console": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging.Debug": "1.0.0-rc2-final",
    "AspNet.Security.OAuth.Validation": "1.0.0-alpha1-final",
    "AspNet.Security.OpenIdConnect.Server": "1.0.0-beta5-final",
    "Microsoft.AspNetCore.Authentication": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Authentication.JwtBearer": "1.0.0-rc2-final"
  },

  "tools": {
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": "portable-net45+win8+dnxcore50"
    }
  },

  "frameworks": {
    "net461": { }
  },

  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "Views",
      "appsettings.json",
      "web.config"
    ]
  },

  "scripts": {
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}

Startup.cs 方法:

Startup.cs methods:

// This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthorization(options =>
                {
                    options.AddPolicy(JwtBearerDefaults.AuthenticationScheme,
                        builder =>
                        {
                            builder.
                            AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).
                            RequireAuthenticatedUser().
                            Build();
                        }
                    );
                }
            );

            services.AddAuthentication();
            services.AddDistributedMemoryCache();
            services.AddMvc();
            services.AddOptions();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            var jwtOptions = new JwtBearerOptions()
            {
                AuthenticationScheme = JwtBearerDefaults.AuthenticationScheme,
                AutomaticAuthenticate = true,
                Authority = "http://localhost:5000/",
                Audience = "http://localhost:5000/",
                RequireHttpsMetadata = false
            };

            jwtOptions.ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration>
                (
                    metadataAddress: jwtOptions.Authority + ".well-known/openid-configuration",
                    configRetriever: new OpenIdConnectConfigurationRetriever(),
                    docRetriever: new HttpDocumentRetriever { RequireHttps = false }
                );


            app.UseJwtBearerAuthentication(jwtOptions);

            app.UseOpenIdConnectServer(options =>
            {
                options.AllowInsecureHttp = true;
                options.AuthorizationEndpointPath = Microsoft.AspNetCore.Http.PathString.Empty;
                options.Provider = new OpenIdConnectServerProvider
                {
                    OnValidateTokenRequest = context =>
                    {
                        context.Skip();
                        return Task.FromResult(0);
                    },

                    OnGrantResourceOwnerCredentials = context =>
                    {
                        var identity = new ClaimsIdentity(context.Options.AuthenticationScheme);
                        identity.AddClaim(ClaimTypes.NameIdentifier, "[unique id]");

                        identity.AddClaim("urn:customclaim", "value", OpenIdConnectConstants.Destinations.AccessToken, OpenIdConnectConstants.Destinations.IdentityToken);

                        var ticket = new AuthenticationTicket(
                            new ClaimsPrincipal(identity),
                            new Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties(),
                            context.Options.AuthenticationScheme);

                        ticket.SetScopes("profile", "offline_access");

                        context.Validate(ticket);

                        return Task.FromResult(0);
                    }
                };
            });            

            app.UseMvc();
        }

发送 x-url 编码的 POST 到 http://localhost:5000 并使用 grant_type=password, username=foo,password=bar 生成预期的 access_token.

sending x-url-encoded POST to http://localhost:5000 with grant_type=password, username=foo, password=bar generates the expected access_token.

我已将 [Authorize("Bearer")] 属性添加到 ValuesController,这在调用 JwtBearerMiddlewear 时按预期工作,但我无法获取要验证的令牌.

I've added the [Authorize("Bearer")] attribute to the ValuesController and this is working as expected in the JwtBearerMiddlewear is invoked but I am unable to get the token to validate.

有没有人使用 .net core RC2 来实现这个功能?我在 RC1 上也有同样的工作,但一直无法进行.

Has anyone got this working with .net core RC2? I've got the same thing working on RC1 but have been unable to get this going.

谢谢.

推荐答案

从 beta5 开始(适用于 ASP.NET Core RC2),OpenID Connect 服务器中间件不再使用 JWT 作为访问令牌的默认格式.相反,它使用不透明的令牌,由坚如磐石的 ASP.NET Core 数据保护堆栈加密(就像身份验证 cookie).

Starting with beta5 (for ASP.NET Core RC2), the OpenID Connect server middleware no longer uses JWT as the default format for access tokens. Instead, it uses opaque tokens, encrypted by the rock-solid ASP.NET Core Data Protection stack (exactly like authentication cookies).

您有 3 个选项来修复您看到的错误:

You have 3 options to fix the error you're seeing:

  • 使用 为支持不透明令牌而开发的新 OAuth2 验证中间件(推荐选项,如果您的 API 和授权服务器属于同一应用程序).为此,请保留 project.json 中的 AspNet.Security.OAuth.Validation 引用并替换 app.UseJwtBearerAuthentication(...)只需 app.UseOAuthValidation().您还可以从 project.json 中删除 Microsoft.AspNetCore.Authentication.JwtBearer.
  • Use the new OAuth2 validation middleware developed to support opaque tokens (the recommended option, if your API and your authorization server are part of the same app). For that, keep the AspNet.Security.OAuth.Validation reference you have in project.json and replace app.UseJwtBearerAuthentication(...) by just app.UseOAuthValidation(). You can also remove Microsoft.AspNetCore.Authentication.JwtBearer from project.json.
  • 通过在选项中调用 options.AccessTokenHandler = new JwtSecurityTokenHandler(); 强制 OpenID Connect 服务器中间件使用 JWT 令牌.请注意,您还必须调用 ticket.SetResources(...) 以使用 JWT 令牌附加适当的受众(请参阅其他 发帖了解更多信息).
  • Force the OpenID Connect server middleware to use JWT tokens by calling options.AccessTokenHandler = new JwtSecurityTokenHandler(); in the options. Note that you'll also have to call ticket.SetResources(...) to attach the appropriate audience with the JWT tokens (see this other SO post for more information).
  • 使用 新的自省中间件.此选项更复杂,需要实现 ValidateIntrospectionRequest 事件来验证客户端凭据.仅当您知道自己在做什么时才使用它.
  • Use the new introspection middleware. This option is more complex and requires implementing the ValidateIntrospectionRequest event to validate the client credentials. Only use it if you know what you're doing.

这篇关于AspNetCore.Authentication.JwtBearer 失败,没有 SecurityTokenValidator 可用于带有 .net core RC2 的令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆