ASP.NET 5 OAuthBearerAuthentication: следующая схема аутентификации не была принята: носитель
обновление:
Pinpoint помог мне получить этот прототип с пусковой площадки - я был очень близок, за исключением:
- мне нужно обновить до beta6 СДК в эти инструкции. Глобальный.json теперь выглядит следующим образом:
{
"projects": [ "src", "test" ],
"sdk": {
"version": "1.0.0-beta6"
}
}
- я обновил ссылки в проекте.в 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. Метод Configure при запуске.CS теперь выглядит следующим образом:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseOAuthBearerAuthentication();
app.UseMvc();
}
я работаю с ASP.NET 5 и пытается реализовать чрезвычайно простое доказательство концепции для генерации и потребления токенов JWT. Я читал статьи здесь, здесь и здесь но этот наиболее близко соответствует моим потребностям.
С этой целью, я очень внимательно прочитал статью, перечитал его, усвоил все комментарии, а затем встал простой пример. Теперь я могу создать токен JWT, но когда я пытаюсь вызвать действие контроллера, которое было украшено атрибутом authorize [Authorize ("Bearer")], я получаю следующее сообщение:
следующая схема аутентификации не была принята: предъявитель
поскольку я не видел примера с высокой точностью A-to-Z о том, как это сделать, рассмотрите следующие шаги для воспроизвести:
- создайте новый проект веб-API в Visual Studio 2015 (я использую Enterprise), выбрав "создать Project...Web...ASP.NET веб-приложение", а затем параметр "веб-API" в разделе "ASP.NET 5 Шаблоны предварительного просмотра"
- использование бета-версии 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"
]
}
- Автозагрузка.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;
}
}
}
- некоторые модели:
учетные данные.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"
};
}
}
- A контроллер значений для демонстрации приема маркера 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-qawNTnXmnuccLRtI1uA",
"token_type": "bearer"
}
скопируйте маркер из предыдущего POST, затем в postman сделайте запрос GET как к http://localhost: 22553 / api / values, заботясь о том, чтобы добавить заголовок авторизации со значением "носитель YOURTOKEN" (например, носитель eyJ0eXAiOiJKV1QiLCJ...)
обратите внимание, что приложение отвечает с ошибкой:
1 ответов
вы должны зарегистрировать промежуточное по аутентификации на носителе OAuth2 перед MVC, или ваши пользователи будут неавторизованы при достижении MVC:
public class Startup {
public void Configure(IApplicationBuilder app) {
app.UseJwtBearerAuthentication(new JwtBearerOptions {
// Your JWT bearer options.
});
app.UseMvc();
}
}