1. ホーム
  2. c#

[解決済み] ClaimsIdentity IsAuthenticatedが常にfalseになるのはなぜですか(web api Authorize filterの場合)?

2023-08-05 07:42:16

質問

Web API プロジェクトで、通常の認証プロセスをオーバーライドして、代わりにトークンをチェックするようにしています。コードは次のようなものです。

if ( true ) // validate the token or whatever here
{
    var claims = new List<Claim>();
    claims.Add( new Claim( ClaimTypes.Name, "MyUser" ) );
    claims.Add( new Claim( ClaimTypes.NameIdentifier, "MyUserID" ) );
    claims.Add( new Claim( ClaimTypes.Role, "MyRole" ) );

    var claimsIdentity = new ClaimsIdentity( claims );

    var principal = new ClaimsPrincipal( new[] { claimsIdentity } );
    Thread.CurrentPrincipal = principal;
    HttpContext.Current.User = principal;
}

そして、後で [Authorize] 属性をコントローラに適用すると、認証に失敗します。

デバッグコードで同じ動作を確認しています。

// ALWAYS FALSE!
if ( HttpContext.Current.User.Identity.IsAuthenticated ) {
    // do something
}

有効なClaimsIdentityを構築し、スレッドに割り当てたにもかかわらず、ユーザが認証されていないと判断されるのはなぜですか?

どのように解決すればよいですか?

この問題は、.Net 4.5 のブレークポイントに起因しています。説明されているように この記事 で説明されているように、単にクレーム ID を作成しても IsAuthenticated が真を返さなくなりました。代わりに、コンストラクタに何らかの文字列 (何でもかまいません) を渡す必要があります。

そこで、上記のコードのこの行を

var claimsIdentity = new ClaimsIdentity( claims );

これになる。

// exact string doesn't matter
var claimsIdentity = new ClaimsIdentity( claims, "CustomApiKeyAuth" );

そして、問題は解決されます。 更新しました。 Leoの他の回答を参照してください。正確なAuthenticationTypeの値は、あなたの認証パイプラインにある他のものによって重要であったりなかったりするかもしれません。

更新2: Robin van der Knaapがコメントで提案したように、1つの System.Security.Claims.AuthenticationTypes の値のいずれかが適切である可能性があります。

var claimsIdentity = new ClaimsIdentity( claims, AuthenticationTypes.Password );

// and elsewhere in your application...
if (User.Identity.AuthenticationType == AuthenticationTypes.Password) {
    // ...
}