ClaimsIdentity在WebApi中不能正常工作



我想在WebApi中使用ClaimsIdentity授权用户。在继承ApiController类的AccountController中,我有两个方法来测试用户身份验证。一种是根据用户的AD名称从其他应用程序接收用户的数据并对其进行身份验证,并将其数据保存为Claim。另一个是一个测试方法调用前一个检查后如果用户身份验证,设置。不幸的是,即使生成了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")
});
}

由于您使用了字符串" User"同时以JSON形式创建完整用户对象的声明,使用以下代码:

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

因此,在检查用户是否通过身份验证时,使用以下代码检查上述声明是否存在。它还会提供你在添加"User"时存储的完整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&quot中使用了这段代码。因此我有

filterContext对象

你可以得到

RequestContext对象

很容易在任何WebAPI-Method中使用,例如

this.RequestContext.Principal.Identity

因此,

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

可以在任何web API控制器中工作。

最新更新