jwt – ASP.NET 5 OAuthBearerAuthentication:以下认证方案未被接受:承载

更新:

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,herehere,但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

我希望有人可能会了解这个例子发生的故障.

解决方法

您必须在MVC之前注册OAuth2承载认证中间件,否则您的用户在达到MVC时将被未认证:
public class Startup {
    public void Configure(IApplicationBuilder app) {
        app.UseJwtBearerAuthentication(new JwtBearerOptions {
            // Your JWT bearer options.
        });

        app.UseMvc();
    }
}

相关文章

这篇文章主要讲解了“WPF如何实现带筛选功能的DataGrid”,文...
本篇内容介绍了“基于WPF如何实现3D画廊动画效果”的有关知识...
Some samples are below for ASP.Net web form controls:(fr...
问题描述: 对于未定义为 System.String 的列,唯一有效的值...
最近用到了CalendarExtender,结果不知道为什么发生了错位,...
ASP.NET 2.0 page lifecyle ASP.NET 2.0 event sequence cha...