authentication - AspNetCore.Authentication.JwtBearer 失败,没有 SecurityTokenValidator 可用于带有 .net core RC2 的 token

标签 authentication asp.net-core jwt openid-connect aspnet-contrib

我试图让一个简单的端点工作,使用 AspNew.Security.OpenIdConnect.Server 发布和使用 JWT token 来发布 token 并使用 Microsoft.AspNetCore.Authentication.JwtBearer 进行验证。

我可以很好地生成 token ,但尝试验证 token 失败并出现错误 Bearer was not authenticated. Failure message: No SecurityTokenValidator available for token: {token}
在这一点上,我已经剥离了所有内容并具有以下内容:

项目.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 方法:

// 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。

我添加了 [Authorize("Bearer")]属性到 ValuesController 并且这在调用 JwtBearerMiddlewear 时按预期工作,但我无法获取 token 进行验证。

有没有人在.net core RC2 上工作过?我在 RC1 上也有同样的工作,但一直无法做到这一点。

谢谢。

最佳答案

从 beta5 开始(用于 ASP.NET Core RC2),the OpenID Connect server middleware no longer uses JWT as the default format for access tokens .相反,它使用不透明的 token ,由坚如磐石的 ASP.NET Core 数据保护堆栈加密(就像身份验证 cookie)。

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

  • 使用 new OAuth2 validation middleware开发以支持不透明 token ( 推荐选项 ,如果您的 API 和授权服务器是同一应用程序的一部分)。为此,请保留 AspNet.Security.OAuth.Validation您在 project.json 中的引用资料并替换 app.UseJwtBearerAuthentication(...)通过 app.UseOAuthValidation() .您也可以删除 Microsoft.AspNetCore.Authentication.JwtBearer来自 project.json .


  • 通过调用 options.AccessTokenHandler = new JwtSecurityTokenHandler(); 强制 OpenID Connect 服务器中间件使用 JWT token 在选项中。请注意,您还必须调用 ticket.SetResources(...)使用 JWT token 附加适当的受众(参见其他 SO post 了解更多信息)。


  • 使用 new introspection middleware .此选项更复杂,需要实现 ValidateIntrospectionRequest验证客户端凭据的事件。仅当您知道自己在做什么时才使用它。
  • 关于authentication - AspNetCore.Authentication.JwtBearer 失败,没有 SecurityTokenValidator 可用于带有 .net core RC2 的 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37335676/

    相关文章:

    public-key-encryption - JWT 如何实现公钥加密?

    javascript - 想要在基于 React 的应用程序中保护 jwt

    sql - 如何通过 WCF 连接到另一台虚拟机上的数据库?

    c# - AD FS 和表单例份验证

    java - Android - JDBC 登录

    c# - Azure DevOps如何通过引用另一个解决方案中的另一个项目来构建项目

    c# - 在同一主机和端口下运行多个应用程序

    authentication - 为什么我无法连接到 ssh 反向隧道?

    c# - Asp Net core Controller URL参数

    java.lang.NoClassDefFoundError : javax/xml/bind/DatatypeConverter while decoding JWT token with Java 11