基於OpenIDConnect規範,角色聲明和名稱聲明的標準類型是role
和name
。但在.net核心System.Security.Claims.ClaimsIdentity.NameClaimType
設置爲「http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name」和System.Security.Claims.ClaimsIdentity.RoleClaimType
設置爲「http://schemas.microsoft.com/ws/2008/06/identity/claims/role」爲什麼.Net Core有自己的聲明類型?
我的問題在這裏是與角色。
我的ASP.NET核心應用程序使用OpenIdConnect進行身份驗證。成功驗證後,OpenIdConnect提供商將該角色作爲索賠集合的一部分發回,其中Cliam.Type
設置爲role
,根據OpenId規範這是正確的。
但是由於.Net Core有自己的角色類型,IsInRole()
方法總是返回false。因爲我認爲IsInRole()
方法使用Microsoft的角色類型進行比較。
爲什麼.net使用不同類型的索賠而不是使用標準約定?和我怎麼解決IsInRole()
問題
更新1
嗯,我試着啓動期間配置要求的類型,但沒有奏效。
startup.cs
public class Startup
{
public Startup(IHostingEnvironment env)
{
// some stuff here that is not related to Identity like building configuration
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddApplicationInsightsTelemetry(Configuration);
services.AddAuthorization();
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
});
// Add Kendo UI services to the services container
services.AddKendo();
// Transform Microsoft cliam types to my claim type
services.AddIdentity<ApplicationUser, ApplicationRole>(options =>
{
options.ClaimsIdentity.RoleClaimType = "role";
options.ClaimsIdentity.UserNameClaimType = "name";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime appLifetime)
{
loggerFactory.AddSerilog();
appLifetime.ApplicationStopped.Register(Log.CloseAndFlush);
app.UseExceptionHandler("/Home/Error");
app.UseApplicationInsightsRequestTelemetry();
app.UseApplicationInsightsExceptionTelemetry();
app.UseStaticFiles();
app.UseIdentityServer(Configuration["Identity:Authority"], Configuration["Identity:ClientId"], Configuration["Identity:PostLogoutRedirectUri"]);
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
// Configure Kendo UI
app.UseKendo(env);
}
}
UseIdentityServer擴展方法
public static void UseIdentityServer(this IApplicationBuilder app, string authority, string clientId, string postlogoutRedirectUri)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
AuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme,
LoginPath = IdentityConstant.CallbackPath,
AccessDeniedPath = new PathString(IdentityConstant.AccessDeniedPath),
CookieName = IdentityConstant.AuthenticationCookieName,
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap = new Dictionary<string, string>();
var connectOptions = new OpenIdConnectOptions()
{
AutomaticChallenge = true,
Authority = authority,
ClientId = clientId,
ResponseType = IdentityConstant.ResponseType,
AuthenticationScheme = IdentityConstant.OpenIdAuthenticationScheme,
SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme,
PostLogoutRedirectUri = postlogoutRedirectUri,
CallbackPath = IdentityConstant.CallbackPath,
Events = new OpenIdConnectEvents()
{
OnTokenValidated = async context =>
{
var userInfoClient = new UserInfoClient(context.Options.Authority + IdentityConstant.UserInfoEndpoint);
var response = await userInfoClient.GetAsync(context.ProtocolMessage.AccessToken);
var claims = response.Claims;
//We will create new identity to store only required claims.
var newIdentity = new ClaimsIdentity(context.Ticket.Principal.Identity.AuthenticationType);
// keep the id_token for logout
newIdentity.AddClaim(new Claim(IdentityConstant.IdTokenClaim, context.ProtocolMessage.IdToken));
// add userinfo claims
newIdentity.AddClaims(claims);
// overwrite existing authentication ticket
context.Ticket = new AuthenticationTicket(
new ClaimsPrincipal(newIdentity),
context.Ticket.Properties,
context.Ticket.AuthenticationScheme);
await Task.FromResult(0);
}
}
};
connectOptions.Scope.Add(IdentityConstant.OpenIdScope);
connectOptions.Scope.Add(IdentityConstant.ProfileScope);
connectOptions.Scope.Add("roles");
app.UseOpenIdConnectAuthentication(connectOptions);
}
更新2
我用IdentityServer3爲我們所有的應用程序的認證。如果客戶端應用程序使用經典的ASP.NET MVC開發的,那麼ASP.Net的智威湯遜處理程序將轉換傳入role
要求類型http://schemas.microsoft.com/ws/2008/06/identity/claims/role
(更多細節可以在Claims Transformation
節中找到here)時,客戶端應用程序
然而同樣是不正確的使用ASP.NET Core開發。 .net核心不會將索賠類型轉換爲.Net索賠類型,這是正確的。但是.Net Core內部使用.Net聲明類型來查找用戶的角色聲明。
這意味着我需要將.Net聲明類型轉換爲期望的聲明類型,但不知道在哪裏?
http://schemas.microsoft.com/ws/2008/06/identity/claims/role這種類型是特定於Microsoft ..這些是標準聲明http://openid.net/specs/openid-connect -core-1_0.html#Claims – LP13