为什么 IIdentity 在 ASP.NET Web API 中被重置/替换?

Why is IIdentity getting reset / replaced in ASP.NET Web API?

在 ASP.Net Web API 方法上使用 [Authorize] 属性会导致“401 未经授权”响应。

我有一个处理 context.AuthenticateRequest 事件的 Http 模块,我在其中检查请求的授权 header(Basic 授权),如果有效,则设置 System.Threading.Thread.CurrentPrincipal 到包含新 GenericIdentity 的新 GenericPrincipal,基于授权 header 中的信息。我还将 HttpContext.Current.User 设置为 GenericPrincipal 的相同实例。

此时,IIdentityIsAuthenticated属性为真。但是,在调用控制器中的操作方法时,System.Threading.Thread.CurrentPrincipal 已设置为包含 System.Security.Claims.ClaimsIdentityIsAuthenticated = false.

System.Security.Claims.ClaimsPrincipal

所以...在我设置 CurrentPrincipal 的点和到达操作方法之间的管道中的某处,CurrentPrincipal 和身份被替换。

API获取ASP.Net身份用户的一些方法(相关网站,API本身不使用ASP.Net身份authentication/authorization),因此 API 项目设置了所有相关的 ASP.Net Identity NuGet 包等

我在其他 API 项目中使用了相同的 Http 模块,这些项目没有所有 ASP.Net Identity NuGet 包等,它工作得很好。

我怀疑 ASP.Net 身份配置导致我的 Basic 身份验证 System.Security.Claims.ClaimsPrincipal 被替换。

如有任何帮助,我们将不胜感激!

这是我的代码:
Http Module - 在此方法结束时,System.Threading.Thread.CurrentPrincipalHttpContext.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.CurrentPrincipalHttpContext.Current.User到包含 System.Security.Claims.ClaimsIdentityIsAuthenticated = false 的 System.Security.Claims.ClaimsPrincipal

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 为我指明了正确的方向!