我想在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"中使用了这段代码。因此我有
filterContext对象
你可以得到
RequestContext对象
很容易在任何WebAPI-Method中使用,例如
this.RequestContext.Principal.Identity
因此,
var claims =
((ClaimsIdentity)this.RequestContext.Principal.Identity).Claims;
可以在任何web API控制器中工作。