Проверка токенов, выданных AspNet.Security.OpenIdConnect.Server (ASP.NET vNext)
Я использую Visual Studio 2015 Enterprise и ASP.NET vNext Beta8 для создания конечной точки, которая выдает и использует токены JWT. Первоначально я подошел к этому, генерируя токены сам, как описаноВот, Позже полезностатья @Pinpoint показал, что AspNet.Security.OpenIdConnect.Server (a.k.a. OIDC) можно настроить для выдачи и использования токенов для меня.
Поэтому я следовал этим инструкциям, поднял конечную точку и отправил сообщение в формате x-www-form-urlencoded отпочтальон Я получаю обратно законный токен:
{
"token_type": "bearer",
"access_token": "eyJ0eXAiO....",
"expires_in": "3599"
}
Это здорово, но и там, где я застреваю. Теперь, как мне аннотировать действие контроллера, чтобы оно требовало этот токен?
Я думал, что все, что мне нужно сделать, это украсить свой метод контроллера с помощью [Authorize ("Bearer")], добавить схему аутентификации:
services.AddAuthorization
(
options =>
{
options.AddPolicy
(
JwtBearerDefaults.AuthenticationScheme,
builder =>
{
builder.
AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).
RequireAuthenticatedUser().
Build();
}
);
}
);
А затем вызовите действие моего контроллера с заголовком «Authorare bearer eyJ0eXAiO ....», как я делал в своем предыдущем примере. К сожалению, кажется, что весь этот подход делает исключение:
Произошло необработанное исключение при обработке запроса.
SocketException: не может быть установлено соединение, потому что целевая машина активно отказалась от него 127.0.0.1:50000
WebException: невозможно подключиться к удаленному серверу
HttpRequestException: произошла ошибка при отправке запроса.
IOException: IDX10804: невозможно получить документ из: 'HTTP: // локальный: 50000 / .well известный / конфигурация OpenID». Microsoft.IdentityModel.Logging.LogHelper.Throw (Строковое сообщение, Тип exceptionType, EventLevel logLevel, Исключение innerException)
InvalidOperationException: IDX10803: невозможно получить конфигурацию из: 'HTTP: // локальный: 50000 / .well известный / конфигурация OpenID». Внутреннее исключение: 'IDX10804: невозможно получить документ из:'HTTP: // локальный: 50000 / .well известный / конфигурация OpenID''.
Рассмотрите следующие шаги для воспроизведения (но, пожалуйста, не считайте этот производственно-достойный код):
Примените инструментарий ASP.NET Beta8, как описаноВот
Откройте Visual Studio Enterprise 2015 и создайте новый проект шаблона веб-API ASP.NET 5 Preview.
Изменить проект.json
{
"webroot": "wwwroot",
"версия": "1.0.0- *",
"зависимости": {
«Microsoft.AspNet.IISPlatformHandler»: «1.0.0-бета8»,
«Microsoft.AspNet.Mvc»: «6.0.0-бета8»,
«Microsoft.AspNet.Server.Kestrel»: «1.0.0-бета8»,
«Microsoft.AspNet.Authentication.JwtBearer»: «1.0.0-бета8»,
"AspNet.Security.OpenIdConnect.Server": "1.0.0-beta3",
«Microsoft.AspNet.Authentication.OpenIdConnect»: «1.0.0-бета8»,
«Microsoft.Framework.ConfigurationModel.Json»: «1.0.0-бета4»,
«Microsoft.AspNet.Diagnostics»: «1.0.0-бета8»
},
"команды": {
"Интернет": "Microsoft.AspNet.Server.Kestrel"
},
"рамки": {
"dnx451": {}
},
"исключить": [
"Wwwroot",
"node_modules"
],
"publishExclude": [
".user»,
".vspscc»
]
}
Измените файл Startup.cs следующим образом (это любезно предоставлено исходной статьей @ Pinpoint; я удалил комментарии и добавил фрагмент AddAuthorization):
public class Startup
{
public Startup(IHostingEnvironment env)
{
}
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization
(
options =>
{
options.AddPolicy
(
JwtBearerDefaults.AuthenticationScheme,
builder =>
{
builder.
AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).
RequireAuthenticatedUser().
Build();
}
);
}
);
services.AddAuthentication();
services.AddCaching();
services.AddMvc();
services.AddOptions();
}
// Configure is called after ConfigureServices is called.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IOptions<AppSettings> appSettings)
{
app.UseDeveloperExceptionPage();
// Add a new middleware validating access tokens issued by the OIDC server.
app.UseJwtBearerAuthentication(options => {
options.AutomaticAuthentication = true;
options.Audience = "http://localhost:50000/";
options.Authority = "http://localhost:50000/";
options.ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration>
(
metadataAddress : options.Authority + ".well-known/openid-configuration",
configRetriever : new OpenIdConnectConfigurationRetriever(),
docRetriever : new HttpDocumentRetriever { RequireHttps = false }
);
});
// Add a new middleware issuing tokens.
app.UseOpenIdConnectServer
(
configuration =>
{
configuration.Options.TokenEndpointPath= "/authorization/v1";
configuration.Options.AllowInsecureHttp = true;
configuration.Provider = new OpenIdConnectServerProvider {
OnValidateClientAuthentication = context =>
{
context.Skipped();
return Task.FromResult<object>(null);
},
OnGrantResourceOwnerCredentials = context =>
{
var identity = new ClaimsIdentity(OpenIdConnectDefaults.AuthenticationScheme);
identity.AddClaim( new Claim(ClaimTypes.NameIdentifier, "todo") );
identity.AddClaim( new Claim("urn:customclaim", "value", "token id_token"));
context.Validated(new ClaimsPrincipal(identity));
return Task.FromResult<object>(null);
}
};
}
);
app.UseMvc();
}
}
Измените wizarded ValuesController.cs, чтобы указать атрибут Authorize:[Route("api/[controller]")]
public class ValuesController : Controller
{
// GET: api/values
[Authorize("Bearer")]
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
Запустите проект и получите токен, используяпочтальон, Для получения токена используйте POST x-www-form-urlencoded с «grant_type» из «password», «username» что-нибудь, «password» что-нибудь и «resource» адресом конечной точки API. Например, мой конкретный URLHTTP: // локальный: 37734 / разрешение / v1.
Скопируйте токен в кодировке Base64, затем используйте токен для вызова контроллера значений мастера, используяпочтальон, Для использования токена создайте GET с заголовками Content-Type application / json и носителем авторизации eyJ0eXAiO .... (ваш токен). Мой конкретный URLHTTP: // локальный: 37734 / API / значения.
Соблюдайте исключение, упомянутое ранее.
Если подход [Authorize ("Bearer")], который я пытаюсь описать выше, является неправильным, я был бы очень признателен, если бы кто-нибудь помог мне разобраться в передовых методах получения токена JWT с помощью OIDC.
Спасибо.