Asp.net mvc 使用Windows Azure Active Directory(WAAD)转换声明

Asp.net mvc 使用Windows Azure Active Directory(WAAD)转换声明,asp.net-mvc,cookies,azure,claims,Asp.net Mvc,Cookies,Azure,Claims,我目前在MVC.NET应用程序中使用windows azure active directory作为单一登录,这一部分非常有效。我可以针对WAAD进行身份验证,并毫无问题地加载我的ClaimsPrinicipal 下一步是通过添加来自不同数据源的新声明来转换从WAAD检索到的声明。在这个程度上,我创建了一个继承ClaimsAuthenticationManager(如下)的类。声明被添加到主体中,并被持久化到CreateSession方法中的会话cookie中 我现在的问题是ClaimsPrin

我目前在MVC.NET应用程序中使用windows azure active directory作为单一登录,这一部分非常有效。我可以针对WAAD进行身份验证,并毫无问题地加载我的ClaimsPrinicipal

下一步是通过添加来自不同数据源的新声明来转换从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: me@mydomain.com}
我错过了什么?在所有处理转换声明的示例中,我发现没有提到从cookie中手动重新加载ClaimsPrinicipal。会话安全令牌事件是重新加载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:ClaimsAuthenticationManager
{
公共重写ClaimsPrincipal身份验证(字符串resourceName,ClaimsPrincipal incomingPrincipal)
{
如果(!incomingPrincipal.Identity.IsAuthenticated)
{
返回base.Authenticate(resourceName,incomingPrincipal);
}
var transformedPrincipal=this.CreateUserPrincipal(incomingPrincipal.Identity.Name);
这个.CreateSession(transformedPrincipal);
返回转换委托人;
}
private ClaimsPrincipal CreateUserPrincipal(字符串用户名)
{
列表声明=新列表();
var user=SecurityController.GetUserIdentity(用户名);
添加(新索赔(ClaimTypes.Name,userName));
添加(新索赔(ClaimTypes.Email,user.Email));
添加(新索赔(ClaimTypes.GivenName,user.FirstName));
claims.Add(新的索赔(ClaimTypes.姓氏,user.LastName));
返回新的ClaimsPrincipal(新的索赔实体(索赔,“我的客户”);
}
私有void CreateSession(ClaimsPrincipal transformedPrincipal)
{
var sessionSecurityToken=新sessionSecurityToken(transformedPrincipal,TimeSpan.FromHours(8));
if(FederatedAuthentication.SessionAuthenticationModule!=null&&
FederatedAuthentication.SessionAuthenticationModule.ContainsSessionTokenCookie(HttpContext.Current.Request.Cookies))
{
返回;
}
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionSecurityToken);
//根据其中一篇文章中的建议,在下面添加了一行
//似乎没有任何效果
Thread.CurrentPrincipal=transformedPrincipal;
FederatedAuthentication.SessionAuthenticationModule.SessionSecurityTokenReceived+=SessionAuthenticationModule\U SessionSecurityTokenReceived;
}
作废SessionAuthenticationModule_SessionSecurityTokenReceived(对象发送方,SessionSecurityTokenReceivedEventArgs e)
{
System.Diagnostics.Debug.WriteLine(“SessionAuthenticationModule_SessionSecurityTokenReceived”);
}

我没有看到您将ClaimsPrincipal(转换后)添加回Thread.CurrentPrincipal。请重试

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);
        //Following is the missing line of code.
        Thread.CurrentPrincipal = transformedPrincipal;
   }

看起来我必须通过ClaimSideEntity而不是ClaimsPrincipal访问声明。现在我可以从应用程序中的任何视图或控制器成功访问声明

((ClaimsIdentity)Thread.CurrentPrincipal.Identity).FindAll(ClaimTypes.Email)
Count = 1
    [0]: {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress: me@mydomain.com}
AuthenticationManager中的最终代码库如下所示(请注意,当前线程上没有对ClaimsPrincipal的显式赋值操作)

公共类MyAuthenticationManager:ClaimsAuthenticationManager
{
公共重写ClaimsPrincipal身份验证(字符串resourceName,ClaimsPrincipal incomingPrincipal)
{
如果(!incomingPrincipal.Identity.IsAuthenticated)
{
返回base.Authenticate(resourceName,incomingPrincipal);
}
var transformedPrincipal=this.CreateUserPrincipal(incomingPrincipal.Identity.Name);
这个.CreateSession(transformedPrincipal);
返回转换委托人;
}
private ClaimsPrincipal CreateUserPrincipal(字符串用户名)
{
列表声明=新列表();
var user=SecurityController.GetUserIdentity(用户名);
添加(新索赔(ClaimTypes.Name,userName));
添加(新声明(“UserId”,user.Id.ToString());
添加(新索赔(ClaimTypes.Email,user.Email));
添加(新索赔(ClaimTypes.GivenName,user.FirstName));
claims.Add(新的索赔(ClaimTypes.姓氏,user.LastName));
//添加(新索赔(ClaimTypes.NameIdentifier,用户名));
如果(user.Account!=null)
{
添加(新的声明(“AccountId”,user.Account.Id.ToString());
添加(新声明(“AccountName”,user.Account.Name.ToString());
}
if(user.Owner!=null)
{
添加(新声明(“OwnerId”,user.Owner.Id.ToString());
添加(新声明(“OwnerName”,user.Owner.Name.ToString());
}
返回新的ClaimsPrincipal(新的索赔实体(索赔,“我的客户”);
}
私有void CreateSession(ClaimsPrincipal transformedPrincipal)
{
if(FederatedAuthentication.SessionAuthenticationModule!=null&&
FederatedAuthentication.SessionAuthenticationModule.ContainsSessionTokenCookie(HttpContext.Current.Request.Cookies))
{
返回;
}
var sessionSecurityToken=新sessionSecurityToken(transformedPrincipal,TimeSpan.FromHours(8));
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionSecurityToken);
}
}

是否配置了MyAuthenticationManager
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("UserId", user.Id.ToString()));
        claims.Add(new Claim(ClaimTypes.Email, user.Email));
        claims.Add(new Claim(ClaimTypes.GivenName, user.FirstName));
        claims.Add(new Claim(ClaimTypes.Surname, user.LastName));
        //claims.Add(new Claim(ClaimTypes.NameIdentifier, userName));

        if (user.Account != null)
        {
            claims.Add(new Claim("AccountId", user.Account.Id.ToString()));
            claims.Add(new Claim("AccountName", user.Account.Name.ToString()));
        }
        if (user.Owner != null)
        {
            claims.Add(new Claim("OwnerId", user.Owner.Id.ToString()));
            claims.Add(new Claim("OwnerName", user.Owner.Name.ToString()));
        }

        return new ClaimsPrincipal(new ClaimsIdentity(claims, "MyCustom"));
    }

    private void CreateSession(ClaimsPrincipal transformedPrincipal)
    {
        if (FederatedAuthentication.SessionAuthenticationModule != null &&
        FederatedAuthentication.SessionAuthenticationModule.ContainsSessionTokenCookie(HttpContext.Current.Request.Cookies))
        {
            return;
        }
        var sessionSecurityToken = new SessionSecurityToken(transformedPrincipal, TimeSpan.FromHours(8));
        FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionSecurityToken);
    }
}