我目前在我的MVC.NET应用程序中使用Windows Azure活动目录作为单一登录,并且该部分效果很好。我可以通过WAAD进行身份验证,并且无需任何问题即可加载我的ClaimsPrincipal。用Windows Azure Active Directory(WAAD)转换声明
下一步是通过添加来自不同数据源的新索赔来转换从WAAD检索到的索赔。就此而言,我创建了一个继承ClaimsAuthenticationManager的类(见下文)。声明被添加到委托人,并在CreateSession方法中持久化到会话cookie。
我现在的问题是,ClaimsPrincipal.Current不包含我添加的任何附加声明。当我设置的SessionAuthenticationModule_SessionSecurityTokenReceived事件断点,我可以看到,还有的ClaimsPrincipal.Current
ClaimsPrincipal.Current.FindAll(ClaimTypes.Email)
Count = 0
和e.SessionToken.ClaimsPrincipal之间的差异。
e.SessionToken.ClaimsPrincipal.FindAll(ClaimTypes.Email)
Count = 1
[0]: {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress: [email protected]}
我在这里错过了什么?在处理转换声明的所有示例中,我都没有提到从Cookie手动重新加载ClaimsPrincipal。会话安全标记事件是否会重新加载ClaimsPrincipal或我打破安全模型?
谢谢。
public class MyAuthenticationManager : ClaimsAuthenticationManager
{
public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
{
if (!incomingPrincipal.Identity.IsAuthenticated)
{
return base.Authenticate(resourceName, incomingPrincipal);
}
var transformedPrincipal = this.CreateUserPrincipal(incomingPrincipal.Identity.Name);
this.CreateSession(transformedPrincipal);
return transformedPrincipal;
}
private ClaimsPrincipal CreateUserPrincipal(String userName)
{
List<Claim> claims = new List<Claim>();
var user = SecurityController.GetUserIdentity(userName);
claims.Add(new Claim(ClaimTypes.Name, userName));
claims.Add(new Claim(ClaimTypes.Email, user.Email));
claims.Add(new Claim(ClaimTypes.GivenName, user.FirstName));
claims.Add(new Claim(ClaimTypes.Surname, user.LastName));
return new ClaimsPrincipal(new ClaimsIdentity(claims, "MyCustom"));
}
private void CreateSession(ClaimsPrincipal transformedPrincipal)
{
var sessionSecurityToken = new SessionSecurityToken(transformedPrincipal, TimeSpan.FromHours(8));
if (FederatedAuthentication.SessionAuthenticationModule != null &&
FederatedAuthentication.SessionAuthenticationModule.ContainsSessionTokenCookie(HttpContext.Current.Request.Cookies))
{
return;
}
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionSecurityToken);
//Added line below as per suggestion in one of the posts
//Doesn't seem to have any effect
Thread.CurrentPrincipal = transformedPrincipal;
FederatedAuthentication.SessionAuthenticationModule.SessionSecurityTokenReceived += SessionAuthenticationModule_SessionSecurityTokenReceived;
}
void SessionAuthenticationModule_SessionSecurityTokenReceived(object sender, SessionSecurityTokenReceivedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("SessionAuthenticationModule_SessionSecurityTokenReceived");
}
在应用程序的.config文件中配置了MyAuthenticationManager吗? – mcollier
您的测试存在缺陷,因为您尝试使用字符串“电子邮件”查找声明,因此它应该是ClaimTypes.Email或“http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress “ – Rob
是的,MyAuthenticationManager是在.config文件中配置的。 Authenticate方法被调用,我可以通过它。 –