【发布时间】:2013-11-26 18:33:54
【问题描述】:
我目前在我的 MVC.NET 应用程序中使用 windows azure 活动目录作为单点登录,这部分效果很好。我可以针对 WAAD 进行身份验证并毫无问题地加载我的 ClaimsPrinical。
下一步是通过添加来自不同数据源的新声明来转换从 WAAD 检索到的声明。为此,我创建了一个继承 ClaimsAuthenticationManager 的类(如下)。声明被添加到 Principal 并在 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: me@mydomain.com}
我在这里缺少什么?在所有处理转换声明的示例中,我发现没有提到从 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");
}
【问题讨论】:
-
MyAuthenticationManager 是否在应用程序的 .config 文件中配置?
-
您的测试有缺陷,因为您试图查找带有字符串“Email”的声明,它应该是 ClaimTypes.Email 或“schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress”
-
是的,MyAuthenticationManager 是在 .config 文件中配置的。 Authenticate方法被调用,我可以单步执行。
-
是的,测试有缺陷,我将它更新为 ClaimTypes.Email 但它仍然是相同的行为。我选择了电子邮件,但我还有其他正在测试的自定义声明,所以从这个角度来看没有任何变化。
标签: asp.net-mvc cookies azure claims