No se pueden recuperar reclamaciones en .NET Core 2.0
Estoy usando unServidor de autenticación OpenId ConnectespecíficamenteIdentity Server 4 (versión 1.5.2) en .NET Core 1.1. Tengo esto ejecutándose con las aplicaciones web ASP.NET Framework MVC 5 y ASP.NET Core 1.1 MVC. La siguiente configuración es de una aplicación web .NET Core 1.1:
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
app.UseDeveloperExceptionPage();
app.UseStatusCodePages();
app.UseRewriter(new RewriteOptions().AddRedirectToHttps());
app.UseStaticFiles();
#region Configure Authentication
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
app.UseCookieAuthentication(
new CookieAuthenticationOptions
{
AuthenticationScheme = "Cookies",
AutomaticAuthenticate = true,
AccessDeniedPath = "/AccessDenied"
});
app.UseOpenIdConnectAuthentication(
new OpenIdConnectOptions
{
AuthenticationScheme = "oidc",
SignInScheme = "Cookies",
Authority = "https://localhost:44316",
ClientId = "test-mule",
ClientSecret = "secret",
ResponseType = "code id_token",
SaveTokens = true,
GetClaimsFromUserInfoEndpoint = true,
PostLogoutRedirectUri = "https://localhost:44324",
RequireHttpsMetadata = true,
Scope = { "openid", "profile", "name", "email", "org", "role" },
TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role"
}
});
#endregion Configure Authentication
app.UseMvc();
}
Una vez que inicie sesión, puedo enumerar los reclamos asociados con el usuario autenticado:
var claims = User.Claims.OrderBy(c => c.Type).ToList();
En la aplicación ASP.NET 1.1, ofrece la siguiente lista de notificaciones:
amr pwd
aud test-mule
auth_time 1504529067
c_hash nouhsuXtd5iKT7B33zxkxg
email tom@
exp 1504532668
family_name Cobley
given_name Tom
iat 1504529068
idp local
iss https://localhost:44316
name tom
nbf 1504529068
nonce 6364012...
org IBX
role SysAdmin
role TeleMarketing
role AccountManager
role DataManager
role Member
sid 2091...
sub 1b19...440fa
Que es lo que quiero / espero.
Ahora estoy tratando de replicar este comportamiento en mi primerASP.NET Core 2.0 aplicación con lo siguienteStartup
configuración:
public Startup()
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
}
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication("Cookies")
.AddCookie("Cookies", options =>
{
options.LoginPath = "/SignIn";
options.AccessDeniedPath = "/AccessDenied";
})
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = "https://localhost:44316";
options.ClientId = "test-mule";
options.ClientSecret = "secret";
options.ResponseType = "code id_token";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.SignedOutRedirectUri = "https://localhost:44367";
options.RequireHttpsMetadata = true;
options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("name");
options.Scope.Add("email");
options.Scope.Add("org");
options.Scope.Add("role");
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role"
};
});
// Add framework services.
services.AddMvc();
}
Para referencia el/Signin
la acción del controlador se ve así:
[Route("/SignIn")]
public IActionResult SignIn(string returnUrl = null)
{
if (!Url.IsLocalUrl(returnUrl)) returnUrl = "/";
var props = new AuthenticationProperties
{
RedirectUri = returnUrl
};
return Challenge(props, "oidc");
}
En este entorno, después de un inicio de sesión exitoso, si enumero las reclamaciones del Usuario, solo veo un subconjunto de lo que está disponible en Core 1.1:
email tom@...
family_name Cobley
given_name Tom
idp local
name tom.cobley
sid 2091...
sub 1b19...440fa
He ejecutado registros de seguimiento tanto en el cliente como en el servidor, pero no puedo ver / identificar nada desfavorable). También estoy asumiendo que no es un problema de Identity Server, ya que es'sólo' ¿Un servicio Open Id Connect que debería ser coherente con cualquier cliente?
¿Alguien puede señalarme en la dirección correcta en cuanto a dónde me estoy equivocando?
Gracias.
ActualizarSiguiendo la sugerencia de MVCutter, agregué un controlador de eventos `OnUserInformationReceived porque noté que no todas mis reclamaciones personalizadas se asignaban correctamente a la identidad del usuario. No estoy seguro de por qué esto es necesario o si hay un mejor lugar para hacerlo, pero parece que me da lo que quiero por ahora.
private Task OnUserInformationReceivedHandler(
UserInformationReceivedContext context)
{
if (!(context.Principal.Identity is ClaimsIdentity claimsId))
{
throw new Exception();
}
// Get a list of all claims attached to the UserInformationRecieved context
var ctxClaims = context.User.Children().ToList();
foreach (var ctxClaim in ctxClaims)
{
var claimType = ctxClaim.Path;
var token = ctxClaim.FirstOrDefault();
if (token == null)
{
continue;
}
var claims = new List<Claim>();
if (token.Children().Any())
{
claims.AddRange(
token.Children()
.Select(c => new Claim(claimType, c.Value<string>())));
}
else
{
claims.Add(new Claim(claimType, token.Value<string>()));
}
foreach (var claim in claims)
{
if (!claimsId.Claims.Any(
c => c.Type == claim.Type &&
c.Value == claim.Value))
{
claimsId.AddClaim(claim);
}
}
}
return Task.CompletedTask;
}