0

カスタムAuthenticationManagerを使用して追加のクレームを持つカスタムClaimsPrincipalを作成しています。ASP.NET 4.5 では、AuthenticationManagerは自動的に呼び出されず、手動で呼び出す必要があるようです。PostAuthenticateRequestでこれを行うことを提案する投稿を見てきました。私のコードは、Global.asax で次のようになります。

protected void Application_OnPostAuthenticateRequest(object sender, EventArgs e)
{
    System.Web.HttpContext.Current.User =
        FederatedAuthentication.FederationConfiguration.IdentityConfiguration.ClaimsAuthenticationManager.Authenticate("none",
            System.Web.HttpContext.Current.User as ClaimsPrincipal);
}

Cookie でフォーム認証を使用しています。PostAuthenticateRequest が起動されると、現在のプリンシパルが正しく設定されます。問題は、次の要求が ASP.NET Web API に着信したときに、カスタム クレームが失われることです。シングル ページ アプリケーション (SPA) で AJAX 要求に Web API を使用しています。現在の ClaimsPrincipal の内容が Cookie の内容によって上書きされていると思われますが、よくわかりません。カスタム クレームをタイプ セーフに取得するために、継承された ClaimsPrincipal を使用していません。プロセスのどこかで後で失われる新しいクレームを追加しているだけです。追加のクレームがリクエスト間で失われないように、カスタム ClaimsPrincipal を設定する適切な方法は何ですか?

4

1 に答える 1

1

Here is the solution I came up with. First I used the FormsAuthentication_OnAuthenticate event instead of the Application_OnPostAuthenticateRequest event. I get the cookie to retrieve the authenticated users name and build a new claims principal with the claims I want to add. I do not add the roles as claims because the system adds them later in the authentication process and ends up duplicating them. This allows me to add custom claims to the principal for future processing in the application.

public void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs args)
{
    if (FormsAuthentication.CookiesSupported)
    {
        if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
        {
            try
            {
                FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(
                  Request.Cookies[FormsAuthentication.FormsCookieName].Value);

                SaClaimsSecurity security = new SaClaimsSecurity();
                //Do not add roles here because the security framework adds them
               //somewhere else in the chain and will duplicate roles
               ClaimsPrincipal principal = security.CreateClaimsPrincipalWithoutRoles(ticket.Name);
                args.User = principal;
            }
            catch (Exception e)
            {
                // Decrypt method failed.
            }
        }
    }
    else
    {
       throw new HttpException("Cookieless Forms Authentication is not " +
                                    "supported for this application.");
    }
}
于 2012-10-23T13:16:28.457 に答える