3

現在、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");
    }
4

2 に答える 2

0

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;
   }
于 2013-11-27T21:06:23.577 に答える