Кажется, что для настройки аутентификации OpenIdConnect от .NET Core 2.2 до IdentityServer3 мне нужно настроить с помощью общего вызова AddOpenIdConnect(), и для того, чтобы политика области работала, я переопределил OnTokenValidated
, где я анализирую полученный токен доступа, и добавляю привязывает его к объекту ClaimsPrincipal
.
Я не нашел другого способа заставить политику области действия работать. Хотя это кажется немного хакерским. Есть ли лучший или более простой способ, поэтому мне не нужно переопределять события или, по крайней мере, не анализировать токен доступа? В любом случае он анализируется в структуре, поэтому я подозреваю, что для получения областей действия в принципале утверждений были доступны другие функции.
Перемещая наш код с .NET 4.5.2 на .NET Core 2.2, мне нужно настроить аутентификацию для нашего IdentityServer3
сервера совсем другим способом.
Я надеялся, что новые функции в более поздних фреймворках позволят упростить настройку аутентификации в отношении IdentityServer3
, но я не нашел подходящего примера.
Я видел, как кто-то говорил, что пакет IdentityServer4.AccessTokenValidation
NuGet может работать с IdentityServer3
, но единственный пример, который я нашел, был с простой проверкой подлинности JWT, не допускающей неявный поток входа пользователя.
Следовательно, я использовал стандартные библиотеки ASP.NET Core для настройки openidconnect, а затем мне нужно настроить код, чтобы он заработал.
Не уверен, что приведенный ниже код обрабатывает все, что ему нужно, но, по крайней мере, я получил место, где я могу войти в систему и использовать новый веб-сайт, а также написать тесты кипариса. Любые предложения о том, как сделать это лучше или проще, будут оценены.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
app.UseMvc();
}
public void ConfigureServices(IServiceCollection services)
{
// Without this, I get "Correlation failed." error from Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.HandleRequestAsync()
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddAuthentication(o => {
o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
}).AddCookie().AddOpenIdConnect(o =>
{
o.Authority = "https://myidentityserver3.myfirm.com";
o.ClientId = "myidentityserver3clientname";
o.SignedOutRedirectUri = "https://localhost:50011/signout";
o.ResponseType = "id_token token";
o.SaveTokens = true;
o.Scope.Add("openid");
o.Scope.Add("roles");
o.Scope.Add("profile");
o.Scope.Add("customrequiredscopeforapi");
o.GetClaimsFromUserInfoEndpoint = false;
{
var old = o.Events.OnTokenValidated;
o.Events.OnTokenValidated = async ctx =>
{
if (old != null) await old(ctx);
var token = MyCustomAuthUtils.ParseBearerToken(ctx.ProtocolMessage.AccessToken);
foreach (var scope in token.Scopes)
{
ctx.Principal.AddIdentity(new ClaimsIdentity(new[] { new Claim("Scope", scope) }));
}
// Our controllers need access token to call other web api's, so putting it here.
// Not sure if that is a good way to do it.
ctx.Principal.AddIdentity(new ClaimsIdentity(new[] { new Claim("access_token", ctx.ProtocolMessage.AccessToken) }));
};
}
});
var mvcBuilder = services.AddMvc(o =>
{
o.Filters.Add(new AuthorizeFilter(ScopePolicy.Create("customrequiredscopeforapi")));
});
services.AddAuthorization();
}