【问题标题】:ClaimsIdentity not working properly in WebApiClaimsIdentity 在 WebApi 中无法正常工作
【发布时间】:2021-11-22 16:47:35
【问题描述】:

我想使用 ClaimsIdentity 在 WebApi 中授权用户。在继承 ApiController 类的 AccountController 中,我有两种方法来测试用户身份验证。一种是用于根据他的 AD 名称从其他应用程序接收用户数据并验证他将他的数据保存为声明的正确方法。另一种是一种测试方法,我在前一种方法之后调用它来检查用户是否经过身份验证并设置了声明。 不幸的是,即使生成了 cookie,登录方法似乎也没有正确设置他的身份。第二种方法就像用户甚至没有经过身份验证并且没有任何声明一样工作。 我尝试了各种创建他的身份的组合,但似乎没有任何效果。 也许你能看到我错过了什么。

AccountController.cs

        [HttpGet]
        [Route("account/login/{userActDirName}/{realmId}")]
        public async Task<IHttpActionResult> Login(string userActDirName, long realmId)
        {
                //getting user data
                var user = await UserManager.FindAsync(userActDirName, "1");
                if (user == null)
                {
                    user = new ApplicationUser() { UserName = userActDirName };
                    IdentityResult result = await UserManager.CreateAsync(user, "1");

                    if (!result.Succeeded)
                    {
                        ...
                    }

                    user = await UserManager.FindAsync(userActDirName, "1");
                }
                Authentication.SignOut();

                ClaimsIdentity cookieIdentity = UserManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
                cookieIdentity.AddClaim(new Claim(ClaimTypes.Name, userActDirName));
                cookieIdentity.AddClaim(new Claim("User", JsonConvert.SerializeObject(userData)));

                
                Authentication.SignIn(new AuthenticationProperties() { IsPersistent = false }, cookieIdentity);
        }

    private ApplicationUserManager _userManager;

        private IAuthenticationManager Authentication
        {
            get { return HttpContext.Current.GetOwinContext().Authentication; }
        }
        public ApplicationUserManager UserManager
        {
            get
            {
                return _userManager ?? HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
            }
            private set
            {
                _userManager = value;
            }
        }

IdentityConfig.cs

public class ApplicationUserManager : UserManager<ApplicationUser>
    {
        public ApplicationUserManager(IUserStore<ApplicationUser> store)
            : base(store)
        {
        }

        public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
        {
            var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
            // Configure validation logic for usernames
            manager.UserValidator = new UserValidator<ApplicationUser>(manager)
            {
                AllowOnlyAlphanumericUserNames = false,
                RequireUniqueEmail = false
            };
            // Configure validation logic for passwords
            manager.PasswordValidator = new PasswordValidator
            {
                RequiredLength = -1,
                RequireNonLetterOrDigit = false,
                RequireDigit = false,
                RequireLowercase = false,
                RequireUppercase = false,
            };
            var dataProtectionProvider = options.DataProtectionProvider;
            if (dataProtectionProvider != null)
            {
                manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
            }
            return manager;
        }
    }

Startup.cs

[assembly: OwinStartup(typeof(Api.Startup))]

namespace Api
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
        }
    }
}

Startup.Auth.cs

public void ConfigureAuth(IAppBuilder app)
        {
            System.Web.Helpers.AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name;
            // Configure the db context and user manager to use a single instance per request
            app.CreatePerOwinContext(ApplicationDbContext.Create);
            app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

            // Enable the application to use a cookie to store information for the signed in user
            // and to use a cookie to temporarily store information about a user logging in with a third party login provider
            app.UseCookieAuthentication(new CookieAuthenticationOptions()
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/Login")
            });
        }

【问题讨论】:

    标签: c# asp.net-web-api2 owin claims-based-identity


    【解决方案1】:

    由于您在创建完整用户对象作为 JSON 的声明时使用了字符串“用户”,因此使用以下代码:

    cookieIdentity.AddClaim(new Claim("User", JsonConvert.SerializeObject(userData)));
    

    因此,在检查用户是否通过身份验证时,请使用以下代码检查上述声明是否存在。它还将为您提供在添加“用户”声明时存储的完整 JSON。

    记住下面的类型转换非常重要 也使用以下命名空间

    using System.Security.Claims;
    

    在使用以下代码之前

    var user = "";
    var claims = 
    ((ClaimsIdentity)filterContext.RequestContext.Principal.Identity).Claims;
                        
    foreach (var c in claims)
    {
        if (c.Type == "User")
             user = c.Value;
    }
    

    我在自定义“AuthorizationFilterAttribute”中使用了此代码。所以我有

    filterContext 对象

    你可以得到

    RequestContext 对象

    在任何 WebAPI 方法中都很容易,例如

            this.RequestContext.Principal.Identity
    

    因此,

    var claims = 
        ((ClaimsIdentity)this.RequestContext.Principal.Identity).Claims;
    

    适用于任何 Web api 控制器。

    【讨论】:

    • this.RequestContext.Principal.Identity 将在基于 ApiController 的控制器中的任何位置工作
    猜你喜欢
    • 2018-06-23
    • 2016-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    相关资源
    最近更新 更多