Pinpoint帮助我把这个原型放在发射台上 – 我非常接近,除了:
>我需要根据these instructions升级到beta6 SDK.Global.json现在显示如下:
- {
- "projects": [ "src","test" ],"sdk": {
- "version": "1.0.0-beta6"
- }
- }
>我更新了project.json中的引用:
- {
- "webroot": "wwwroot","version": "1.0.0-*","dependencies": {
- "Microsoft.AspNet.Mvc": "6.0.0-beta6","Microsoft.AspNet.Server.IIS": "1.0.0-beta6","Microsoft.AspNet.Server.WebListener": "1.0.0-beta6","Microsoft.AspNet.StaticFiles": "1.0.0-beta6","System.IdentityModel.Tokens": "5.0.0-beta6-207211625","Serilog.Framework.Logging": "1.0.0-beta-43","Microsoft.AspNet.Authentication.OAuthBearer": "1.0.0-beta6"
- },"commands": {
- "web": "Microsoft.AspNet.Hosting --config hosting.ini"
- },"frameworks": {
- "dnx451": { }
- },"exclude": [
- "wwwroot","node_modules","bower_components"
- ],"publishExclude": [
- "node_modules","bower_components","**.xproj","**.user","**.vspscc"
- ]
- }
>启动配置方法中的中间件顺序很重要. USEOAuthBearerAuthentication需要在UseMvc之前使用. Startup.cs中的Configure方法现在显示如下:
- public void Configure(IApplicationBuilder app,IHostingEnvironment env)
- {
- app.USEOAuthBearerAuthentication();
- app.UseMvc();
- }
我正在使用ASP.NET 5,并试图实现一个非常简单的概念证明来生成和使用JWT令牌.我已经阅读了文章here,@L_404_2@和here,但this one最符合我的需求.
为此,我非常仔细地阅读文章,重新阅读,内部化所有的评论,然后站起来一个简单的例子.我现在可以生成一个JWT令牌,但是当我尝试使用授权属性[Authorize(“Bearer”)]来调用我的控制器操作时,我收到以下消息:
The following authentication scheme was not accepted: Bearer
由于我没有看到如何做到这一点的高保真A到Z的例子,请考虑以下步骤来重现:
>在Visual Studio 2015中创建一个新的Web API项目(我正在使用Enterprise),选择“新建项目… Web … ASP.NET Web应用程序”,然后选择“ASP.NET 5”下的“Web API”选项预览模板“
>使用beta 5 SDK,global.json如下所示:
- {
- "projects": [ "src","sdk": {
- "version": "1.0.0-beta5","runtime": "clr","architecture": "x86"
- }
- }
>引入JWT令牌所需的依赖项,project.json如下所示:
- {
- "webroot": "wwwroot","dependencies": {
- "Microsoft.AspNet.Mvc": "6.0.0-beta6","System.IdentityModel.Tokens": "5.0.0-beta5-206011020","Microsoft.AspNet.Authentication.OAuthBearer": "1.0.0-beta5"
- },"commands": {
- "web": "Microsoft.AspNet.Hosting --config hosting.ini"
- },"frameworks": {
- "dnx451": { }
- },"exclude": [
- "wwwroot","bower_components"
- ],"publishExclude": [
- "node_modules","**.vspscc"
- ]
- }
> Startup.cs(这是不适合生产的示例)
- public class Startup
- {
- const string _TokenIssuer = "contoso.com" ;
- const string _TokenAudience = "contoso.com/resources" ;
- RsaSecurityKey _key = null ;
- SigningCredentials _signingCredentials = null ;
- public Startup(IHostingEnvironment env)
- {
- GenerateRsaKeys();
- }
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddInstance(_signingCredentials);
- services.ConfigureOAuthBearerAuthentication
- (
- options =>
- {
- options.AutomaticAuthentication = true;
- options.TokenValidationParameters.IssuerSigningKey = _key ;
- options.TokenValidationParameters.ValidAudience = _TokenAudience;
- options.TokenValidationParameters.ValidIssuer = _TokenIssuer ;
- }
- );
- services.ConfigureAuthorization
- (
- options =>
- {
- options.
- AddPolicy
- (
- "Bearer",new AuthorizationPolicyBuilder().
- AddAuthenticationSchemes(OAuthBearerAuthenticationDefaults.AuthenticationScheme).
- RequireAuthenticatedUser().
- Build()
- );
- }
- );
- services.AddMvc();
- }
- public void Configure(IApplicationBuilder app,IHostingEnvironment env,ILoggerFactory loggerfactory)
- {
- app.UseMvc();
- app.USEOAuthBearerAuthentication();
- }
- void GenerateRsaKeys()
- {
- using(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048))
- {
- _key = new RsaSecurityKey(rsa.ExportParameters(true));
- _signingCredentials =
- new SigningCredentials
- (
- _key,SecurityAlgorithms.RsaSha256Signature,SecurityAlgorithms.Sha256Digest,"secret"
- );
- rsa.PersistKeyInCsp = false;
- }
- }
- }
>一些型号:
Credentials.cs
- public class Credentials
- {
- public string user { set;get;}
- public string password { set;get;}
- }
JwtToken.cs
- public class JwtToken
- {
- public string access_token { set; get; }
- public string token_type { set; get; }
- }
>用于提取令牌的令牌控制器(这是不适合生产的示例),TokenController.cs:
- [ Route("[controller]") ]
- public class TokenController : Controller
- {
- private readonly OAuthBearerAuthenticationOptions _bearerOptions ;
- private readonly SigningCredentials _signingCredentials ;
- public TokenController
- (
- IOptions<OAuthBearerAuthenticationOptions> bearerOptions,SigningCredentials signingCredentials
- )
- {
- _bearerOptions = bearerOptions.Options ;
- _signingCredentials = signingCredentials ;
- }
- // POST: /token
- [HttpPost()]
- public JwtToken Token([FromBody] Credentials credentials)
- {
- // Pretend to validate credentials...
- JwtSecurityTokenHandler handler =
- _bearerOptions .
- SecurityTokenValidators .
- OfType<JwtSecurityTokenHandler>() .
- First();
- JwtSecurityToken securityToken =
- handler .
- CreateToken
- (
- issuer : _bearerOptions.TokenValidationParameters.ValidIssuer,audience : _bearerOptions.TokenValidationParameters.ValidAudience,signingCredentials : _signingCredentials,subject : new ClaimsIdentity
- (
- new Claim []
- {
- new Claim(ClaimTypes.Name,"somebody"),new Claim(ClaimTypes.Role,"admin" ),"teacher" ),}
- ),expires : DateTime.Today.AddDays(1)
- );
- string token = handler.WriteToken(securityToken);
- return new JwtToken()
- {
- access_token = token,token_type = "bearer"
- };
- }
- }
>一个值控制器来演示摄取令牌ValuesController.cs:
- [Route("api/[controller]")]
- public class ValuesController : Controller
- {
- // GET: api/values
- [Authorize("Bearer")]
- [HttpGet]
- public IEnumerable<string> Get()
- {
- return new string[] { "value1","value2" };
- }
- // GET api/values/5
- [HttpGet("{id}")]
- public string Get(int id)
- {
- return "value";
- }
- }
>启动postman(或您最喜欢的REST客户端)的副本,在Visual Studio下启动示例应用程序,并使用与JSON主体类似的http:// localhost:22553 / token /
- {
- "user" : "user","password" : "secret"
- }
该应用程序使用令牌进行响应:
- {
- "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6bnVsbH0.eyJ1bmlxdWVfbmFtZSI6InNvbWVib2R5Iiwicm9sZSI6WyJhZG1pbiIsInRlYWNoZXIiXSwiaXNzIjoiY29udG9zby5jb20iLCJhdWQiOiJjb250b3NvLmNvbS9yZXNvdXJjZXMiLCJleHAiOjE0Mzk1MzU2MDB9.anRgL10XFG_bKDDxY3D2xQSfhPRLGMjUTreQNsP1jDA6eRKwXHf3jtpCwm_saoWyUDFFA2TMI9e_LbP6F5l7vtozCluziE_GQkPkspUSWuWIpQJLPRTTPPZHGKmPmK4MLEl1zPPrggJWbvF9RBw3mMQ0KoMfjSL0vUQ8kZ7VXAel8dnYJccd-CFdnB6aDe79x2E9Se2iLxdhr--R_qgvfz1Fa6tR1dstqLQ-UjYqPWY4SOgBjM3abtjfLLVEzeQMVyezX7Cx9ObMXAGbGvQL6GB_T5RlfAoXWME4jM8Bzhd-07wwd732bBws4OXivj1sSz-qawNTnXmnuccLRtI1uA","token_type": "bearer"
- }
>从先前的POST复制令牌,然后在邮递员中创建一个类似于http:// localhost:22553 / api / values的GET请求,注意添加一个授权头,其值为“bearer YOURTOKEN”(例如承载权限为yeetok .)
>请注意,该应用程序响应错误:
System.InvalidOperationException
The following authentication scheme was not accepted: Bearer
堆栈跟踪如下:
- at Microsoft.AspNet.Http.Authentication.Internal.DefaultAuthenticationManager.< AuthenticateAsync> d__9.MoveNext()
- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
- at Microsoft.AspNet.Http.Authentication.AuthenticationManager.< AuthenticateAsync> d__2.MoveNext()
- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter< TResult> .GetResult()
- at Microsoft.AspNet.Mvc.AuthorizeFilter.< OnAuthorizationAsync> d__5.MoveNext()
- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
- at Microsoft.AspNet.Mvc.Core.FilterActionInvoker.< InvokeAuthorizationFilterAsync> d__43.MoveNext()
- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
- at Microsoft.AspNet.Mvc.Core.FilterActionInvoker.< InvokeAllAuthorizationFiltersAsync> d__42.MoveNext()
- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
- at Microsoft.AspNet.Mvc.Core.FilterActionInvoker.< InvokeAsync> d__40.MoveNext()
- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
- at Microsoft.AspNet.Mvc.MvcRouteHandler.< InvokeActionAsync> d__4.MoveNext()
- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
- at Microsoft.AspNet.Mvc.MvcRouteHandler.< RouteAsync> d__3.MoveNext()
- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
- at Microsoft.AspNet.Mvc.Routing.InnerAttributeRoute.< RouteAsync> d__10.MoveNext()
- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
- at Microsoft.AspNet.Routing.RouteCollection.< RouteAsync> d__9.MoveNext()
- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
- at Microsoft.AspNet.Builder.RouterMiddleware.< Invoke> d__4.MoveNext()
- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
- at Microsoft.AspNet.Hosting.Internal.RequestServicesContainerMiddleware.< Invoke> d__3.MoveNext()
- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
- at Microsoft.AspNet.Hosting.Internal.HostingEngine.< > c__DisplayClass29_0.< < Start> b__0> d.MoveNext()
- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
- at Microsoft.AspNet.Loader.IIS.RuntimeHttpApplication.< ProcessRequestAsyncImpl> d__10.MoveNext()
- --- exception rethrown ---
- at Microsoft.AspNet.Loader.IIS.RuntimeHttpApplication.< ProcessRequestAsyncImpl> d__10.MoveNext()
- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
- at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
- at Microsoft.AspNet.Loader.IIS.HttpApplicationBase.< InvokeProcessRequestAsyncImpl> d__9.MoveNext()
请注意,添加日志记录几乎不会增加其他洞察力,因为以下日志显示:
- 2015-08-13 13:32:35.969 -07:00 [Information] Request successfully matched the route with name 'null' and template '"api/Values"'.
- Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNet.Http.dll
- 2015-08-13 13:32:36.247 -07:00 [Error] An error occurred while handling the request.
- 2015-08-13 13:32:36.247 -07:00 System.InvalidOperationException: The following authentication scheme was not accepted: Bearer
我希望有人可能会了解这个例子发生的故障.