[英]Why is IIdentity getting reset / replaced in ASP.NET Web API?
在ASP.Net Web API方法上使用[Authorize]
属性会导致“ 401未经授权”响应。
我有一个用于处理context.AuthenticateRequest
事件的Http模块,在该事件中,我检查了请求的Authorization标头( Basic
授权),如果有效,则将System.Threading.Thread.CurrentPrincipal
设置为一个新的GenericPrincipal
,该GenericPrincipal
包含一个新的GenericIdentity
基于在“授权”标头中的信息上。 我还将HttpContext.Current.User
设置为GenericPrincipal
的相同实例。
在这一点上, IsAuthenticated
的财产IIdentity
是真实的。 但是,在调用控制器中的操作方法时, System.Threading.Thread.CurrentPrincipal
已设置为System.Security.Claims.ClaimsPrincipal
其中包含System.Security.Claims.ClaimsIdentity
且IsAuthenticated
= false。
所以...在我设置CurrentPrincipal
的点与到达操作方法之间的管线中的某个位置, CurrentPrincipal
和Identity正在被替换。
API的某些方法访问ASP.Net Identity用户(对于相关网站,API本身不使用ASP.Net Identity进行身份验证/授权),因此API项目使用所有相关的ASP.Net Identity进行设置NuGet软件包等
我在其他API项目中使用了相同的Http模块,因为它没有所有的ASP.Net Identity NuGet包等,并且它像冠军一样工作。
我怀疑ASP.Net Identity配置导致我的Basic
身份验证System.Security.Claims.ClaimsPrincipal
被替换。
任何帮助将非常感激!
这是我的代码:
Http模块 -在此方法的末尾,正确设置了System.Threading.Thread.CurrentPrincipal
和HttpContext.Current.User
。
public class FsApiHttpAuthentication : IHttpModule, IDisposable {
public void Init( HttpApplication context ) {
context.AuthenticateRequest += AuthenticateRequests;
context.EndRequest += TriggerCredentials;
}
private static void AuthenticateRequests( object sender, EventArgs e ) {
string authHeader = HttpContext.Current.Request.Headers["Authorization"];
if ( authHeader != null ) {
System.Net.Http.Headers.AuthenticationHeaderValue authHeaderVal = System.Net.Http.Headers.AuthenticationHeaderValue.Parse(authHeader);
if ( authHeaderVal.Parameter != null ) {
byte[] unencoded = Convert.FromBase64String(authHeaderVal.Parameter);
string userpw = System.Text.Encoding.GetEncoding("iso-8859-1").GetString(unencoded);
string[] creds = userpw.Split(':');
CredentialCache.Credential cred = CredentialCache.GetCredential(creds[0], creds[1]);
if ( cred != null ) {
System.Security.Principal.GenericIdentity identity = new System.Security.Principal.GenericIdentity
(cred.Username);System.Threading.Thread.CurrentPrincipal = new System.Security.Principal.GenericPrincipal(identity, roles);
if ( string.IsNullOrWhiteSpace(cred.RolesList) ) {
System.Threading.Thread.CurrentPrincipal = new System.Security.Principal.GenericPrincipal(identity, null);
} else {
System.Threading.Thread.CurrentPrincipal = new System.Security.Principal.GenericPrincipal(identity, cred.RolesList.Split(','));
}
HttpContext.Current.User = System.Threading.Thread.CurrentPrincipal;
}
}
}
}
Api控制器 -达到此控制器中的Post
操作时, System.Threading.Thread.CurrentPrincipal
和HttpContext.Current.User
已设置为System.Security.Claims.ClaimsPrincipal
其中包含System.Security.Claims.ClaimsIdentity
且IsAuthenticated
=假。
public class ConsumerAccountController : ApiController {
private ApplicationUserManager _userManager;
private ApplicationUserManager UserManager {
get {
return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
set {
_userManager = value;
}
}
public async System.Threading.Tasks.Task<IHttpActionResult> Post( API.FinancialSamaritan.com.ViewModels.UserCredentials creds ) {
API.FinancialSamaritan.com.ViewModels.CreateUserResult cccur = null;
try {
string username = creds.Username;
string password = creds.Password;
var user = new API.FinancialSamaritan.com.Models.ApplicationUser {
UserName = username,
Email = username,
SecurityQuestion = creds.SecurityQuestion,
SecurityAnswer = UserManager.PasswordHasher.HashPassword(creds.SecurityAnswer),
IsPasswordChangeRequired = true,
EmailConfirmed = true
};
IdentityResult userResult = await UserManager.CreateAsync(user, password);
...
[Authorize]
属性是从System.Web.Http.AuthorizeAttribute
而不是System.Web.Mvc.AuthorizeAttribute
派生的。 我必须完全限定属性的名称空间,以便使用[Authorize]
MVC版本。 感谢@RonBrogan为我指出正确的方向!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.