ASP.NET 5 OAuthBearerAuthentication: следующая схема аутентификации не была принята: Bearer

Обновлено:

Pinpoint помог мне снять этот прототип со стартовой площадки - я был очень близок, за исключением:

Мне нужно обновить до бета6 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"
  ]
}
Порядок промежуточного программного обеспечения в методе Configure при запуске имеет значение. UseOAuthBearerAuthentication должен предшествовать UseMvc. Метод Configure в Startup.cs теперь выглядит следующим образом:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseOAuthBearerAuthentication();      

    app.UseMvc();
}

Я работаю с ASP.NET 5 и пытаюсь реализовать чрезвычайно простое доказательство концепции генерации и использования токенов JWT. Я прочитал статьиВот, Вот а такжеВот ноэтот наиболее близко соответствует моим потребностям.

С этой целью я очень внимательно прочитал статью, перечитал ее, усвоил все комментарии и затем привел простой пример. Теперь я могу сгенерировать токен JWT, но когда я пытаюсь вызвать действие моего контроллера, которое было украшено атрибутом авторизации [Authorize ("Bearer")], я получаю следующее сообщение:

Следующая схема аутентификации не была принята: Носитель

Так как я не видел высококачественного A-to-Z примера того, как это сделать, рассмотрите следующие шаги для воспроизведения:

Создайте новый проект Web API в Visual Studio 2015 (я использую Enterprise), выбрав «Новый проект ... Web ... ASP.NET Web Application», а затем параметр «Web API» в «ASP.NET 5 Preview». Шаблоны»Используя бета-5 SDK, global.json выглядит следующим образом:
{
  "projects": [ "src", "test" ],
  "sdk": {
    "version": "1.0.0-beta5",
    "runtime": "clr",
    "architecture": "x86"
  }
}
С учетом зависимостей, необходимых для токенов JWT, файл 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",
        "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",
        "node_modules",
        "bower_components"
    ],
    "publishExclude": [
        "node_modules",
        "bower_components",
        "**.xproj",
        "**.user",
        "**.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"   ),
                        new Claim(ClaimTypes.Role,"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";
    }
}
Запустите копиюпочтальон (или ваш любимый клиент REST), запустите пример приложения под Visual Studio и сделайте запрос POST,аналогичный на http: // localhost: 22553 / token / с телом JSON:
{
    "user" : "user",
    "password" : "secret"
}

Приложение отвечает токеном:

{
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6bnVsbH0.eyJ1bmlxdWVfbmFtZSI6InNvbWVib2R5Iiwicm9sZSI6WyJhZG1pbiIsInRlYWNoZXIiXSwiaXNzIjoiY29udG9zby5jb20iLCJhdWQiOiJjb250b3NvLmNvbS9yZXNvdXJjZXMiLCJleHAiOjE0Mzk1MzU2MDB9.anRgL10XFG_bKDDxY3D2xQSfhPRLGMjUTreQNsP1jDA6eRKwXHf3jtpCwm_saoWyUDFFA2TMI9e_LbP6F5l7vtozCluziE_GQkPkspUSWuWIpQJLPRTTPPZHGKmPmK4MLEl1zPPrggJWbvF9RBw3mMQ0KoMfjSL0vUQ8kZ7VXAel8dnYJccd-CFdnB6aDe79x2E9Se2iLxdhr--R_qgvfz1Fa6tR1dstqLQ-UjYqPWY4SOgBjM3abtjfLLVEzeQMVyezX7Cx9ObMXAGbGvQL6GB_T5RlfAoXWME4jM8Bzhd-07wwd732bBws4OXivj1sSz-qawNTnXmnuccLRtI1u,A",
  "token_type": "bearer"
}

Скопируйте токен из предыдущего POST, затем в почтальоне сделайте GET запросаналогичный на http: // localhost: 22553 / api / values, стараясь добавить заголовок авторизации со значением «bearer YOURTOKEN» (например, bearer eyJ0eXAiOiJKV1QiLCJ ...)

Обратите внимание, что приложение отвечает с ошибкой:

System.InvalidOperationException Следующая схема аутентификации не была принята: Носитель

Стек трассировки выглядит следующим образом:

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

Я надеюсь, что кто-то может понять, где происходит сбой в этом примере.

Ответы на вопрос(1)

Ваш ответ на вопрос