exp*_*nit 65 c# asp.net claims-based-identity asp.net-4.5 asp.net-web-api
在Web API项目中,我重写了正常的身份验证过程来检查令牌.代码看起来像这样:
if ( true ) // validate the token or whatever here
{
var claims = new List<Claim>();
claims.Add( new Claim( ClaimTypes.Name, "MyUser" ) );
claims.Add( new Claim( ClaimTypes.NameIdentifier, "MyUserID" ) );
claims.Add( new Claim( ClaimTypes.Role, "MyRole" ) );
var claimsIdentity = new ClaimsIdentity( claims );
var principal = new ClaimsPrincipal( new[] { claimsIdentity } );
Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;
}
Run Code Online (Sandbox Code Playgroud)
然后,当我将[Authorize]
属性应用于控制器时,它无法授权.
调试代码确认相同的行为:
// ALWAYS FALSE!
if ( HttpContext.Current.User.Identity.IsAuthenticated ) {
// do something
}
Run Code Online (Sandbox Code Playgroud)
为什么即使我构建了有效的ClaimsIdentity并将其分配给线程,它仍然认为用户未经过身份验证?
exp*_*nit 121
问题是由于.Net 4.5的突破性变化.正如本文所解释的那样,简单地构建声明标识不再使其IsAuthenticated返回true.相反,您需要将一些字符串(无关紧要)传递给构造函数.
所以在上面的代码中这一行:
var claimsIdentity = new ClaimsIdentity( claims );
Run Code Online (Sandbox Code Playgroud)
变成这样:
// exact string doesn't matter
var claimsIdentity = new ClaimsIdentity( claims, "CustomApiKeyAuth" );
Run Code Online (Sandbox Code Playgroud)
问题解决了.更新:请参阅Leo的其他答案.确切的AuthenticationType值可能重要,也可能不重要,具体取决于您在auth管道中的其他内容.
更新2:正如Robin van der Knaap在评论中所建议的那样,其中一个System.Security.Claims.AuthenticationTypes
值可能是合适的.
var claimsIdentity = new ClaimsIdentity( claims, AuthenticationTypes.Password );
// and elsewhere in your application...
if (User.Identity.AuthenticationType == AuthenticationTypes.Password) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
Leo*_*Leo 13
虽然提供的答案在其中有一定的有效性,但它并不完全正确.你不能假设只是添加任何字符串将神奇地工作.正如其中一条评论中所述,该字符串必须与AuthenticationTypes
枚举中的一个匹配,而枚举又必须与OWIN认证/授权中间件中指定的枚举匹配....例如......
public void ConfigureOAuth(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
OAuthAuthorizationServerOptions serverOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new Microsoft.Owin.PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
AuthenticationType = AuthenticationTypes.Password,
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
Provider = new AppAuthServerProvider()
};
app.UseOAuthAuthorizationServer(serverOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()
{
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
AuthenticationType = AuthenticationTypes.Password
});
}
Run Code Online (Sandbox Code Playgroud)
但是,在上述情况下,这并不重要.但是,如果您使用更多身份验证/授权级别,声明将与匹配相同的声明关联AuthenticationType
...另一个示例是当您使用Cookie身份验证时...
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "ApplicationCookie",
LoginPath = new PathString("/auth/login")
});
}
Run Code Online (Sandbox Code Playgroud)
其中AuthenticationType
描述了cookie的名称,因为您的应用程序可能已从其他提供程序获取其他cookie,因此设置AuthenticationType
实例化声明以便将其关联到正确的cookie非常重要.
归档时间: |
|
查看次数: |
26617 次 |
最近记录: |