Настройка различных схем авторизации / аутентификации
Я реализую безопасность в приложении ASP.NET Core 1.0.1, которое используется в качестве веб-API. Я пытаюсь понять, если и как реализовать 2 разные схемы аутентификации.
В идеале я хотел бы разрешить аутентификацию через Azure Active Directory или через имя пользователя / пароль для определенных внутренних служб, которые связываются с приложением.
Можно ли настроить ASP.NET Core для такой настройки, при которой конечная точка проходит аутентификацию через Azure AD или токен JWT?
Я пробовал что-то подобное, но после вызова конечной точки генерирования токена я получаю 500 без какой-либо информации. Удаление конфигурации Azure AD позволяет конечной точке работать идеально:
services.AddAuthorization(configuration =>
{
configuration.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser().Build());
configuration.AddPolicy("OpenIdConnect", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(OpenIdConnectDefaults.AuthenticationScheme)
.RequireAuthenticatedUser().Build());
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
ClientId = Configuration["Authentication:AzureAD:ClientId"],
Authority
= Configuration["Authentication:AzureAd:AADInstance"]
+ Configuration["Authentication:AzureAd:TenantId"],
ResponseType = OpenIdConnectResponseType.IdToken,
SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme
});
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
TokenValidationParameters = new TokenValidationParameters
{
ClockSkew = TimeSpan.FromMinutes(1),
IssuerSigningKey = TokenAuthenticationOptions.Credentials.Key,
ValidateAudience = true,
ValidateIssuer = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidAudience = TokenAuthenticationOptions.Audience,
ValidIssuer = TokenAuthenticationOptions.Issuer
}
});
1 ответ
Использовать OpenIdConnectDefaults.AuthenticationScheme
постоянная при добавлении политики авторизации и при добавлении промежуточного программного обеспечения для аутентификации.
Здесь вы используете OpenIdConnectDefaults
, Хорошо. Держите эту линию.
services.AddAuthorization(configuration =>
{
...
configuration.AddPolicy("OpenIdConnect", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(OpenIdConnectDefaults.AuthenticationScheme) // keep
.RequireAuthenticatedUser().Build());
});
Здесь вы используете CookieAuthenticationDefaults
, Удалить эту строку.
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
...
SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme // delete
});
Зачем?
Когда ваша политика авторизации OpenIdConnect запускается, она будет искать схему аутентификации с именем OpenIdConnectDefaults.AuthenticationScheme
, Он не найдет его, потому что зарегистрированное промежуточное ПО OpenIdConnect называется CookieAuthenticationDefaults.AuthenticationScheme
, Если вы удалите эту ошибочную строку, то код будет автоматически использовать соответствующую настройку по умолчанию.
Редактировать: Комментарий к образцу
Второе разумное решение
Связанный пример приложения из комментариев звонков services.AddAuthentication
и устанавливает SignInScheme
в "печенье". Это изменяет схему входа по умолчанию для всего промежуточного программного обеспечения аутентификации. Результат: вызов app.UseOpenIdConnectAuthentication
теперь эквивалентно этому:
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme
}
Это именно то, что Камило имел в первую очередь. Так почему мой ответ сработал?
Мой ответ сработал, потому что не важно, что SignInScheme
имя мы выбираем; важно то, что эти имена соответствуют друг другу. Если мы установим нашу схему входа для аутентификации OpenIdConnect в "Cookies", то при добавлении политики авторизации нам нужно будет запросить эту схему по имени, например так:
services.AddAuthorization(configuration =>
{
...
configuration.AddPolicy("OpenIdConnect", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme) <----
.RequireAuthenticatedUser().Build());
});
Третье разумное решение
Чтобы подчеркнуть важность согласованности, вот третье разумное решение, которое использует произвольный знак в имени схемы.
services.AddAuthorization(configuration =>
{
configuration.AddPolicy("OpenIdConnect", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes("Foobar")
.RequireAuthenticatedUser().Build());
});
Здесь вы используете CookieAuthenticationDefaults
, Удалить эту строку.
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
SignInScheme = "Foobar"
});