2017-11-16 12 views
0

アイデンティティ・サーバー4を使用している.netコア・アプリケーションは、アプリケーションでの認可のための多数の非標準クレームを作成しています。これらの非標準的な主張の中には、アプリケーションがデータベースによってどのように動作し、設定されるかに直接影響を与えるものがあります。ユーザーがUIで何らかのアクションを実行する場合は、それらのクレームをリセットする必要があります。.NET Core 2/Identity Server 4 - すべてのクレームをリフレッシュ

ここで見つけた更新トークンをハイブリッドフローで使用すると、私の質問https://github.com/IdentityServer/IdentityServer4.Samples/blob/release/Clients/src/MvcHybrid/Controllers/HomeController.csは、ユーザー情報エンドポイントを呼び出して更新されたクレームリストを取得しますか?ログアウトしてログインし直さなくてもログインをリセットすることもできます。または、クレームプリンシパルを手動で更新する必要がありますか?

私は多くの場合、プリンシパルを手動で更新する必要はなく、IS4には重労働をさせる必要はありません。私は、トークンをリフレッシュすることができたと私はそれがIS4を呼び出し、IS4コードでクレームをリセットだことがわかり、それは実際にはないユーザープロファイルを取得していない上記のコードを使用して

EDIT

クライアント側のクレームを更新します。トークンがログアウトには大きすぎるので、私はトークンにクレームを保存することができないので、オプションで "GetClaimsFromUserInfoEndpoint"が有効になっています。とにかく、プログラムでUserProfileをリセットしていますか?

答えて

0

見つけました!サンプルコードのリフレッシュトークンを使用して、Cookieを認証した後で、Cookieにサインインする前に、手動でUserInfoエンドポイントを呼び出して更新されたクレームリストを取得する必要があります。

var disco = await DiscoveryClient.GetAsync(this.applicationSettings.IdentityServerAuthority); 
if (disco.IsError) throw new Exception(disco.Error); 

var userInfoClient = new UserInfoClient(disco.UserInfoEndpoint); 
var tokenClient = new TokenClient(disco.TokenEndpoint, this.applicationSettings.IdentityServerAuthorityClient, this.applicationSettings.IdentityServerAuthorityPassword); 
var rt = await this.httpContext.HttpContext.GetTokenAsync("refresh_token"); 
var tokenResult = await tokenClient.RequestRefreshTokenAsync(rt); 

if (!tokenResult.IsError) 
{ 
    var old_id_token = await this.httpContext.HttpContext.GetTokenAsync("id_token"); 
    var new_access_token = tokenResult.AccessToken; 
    var new_refresh_token = tokenResult.RefreshToken; 

    var tokens = new List<AuthenticationToken>(); 
    tokens.Add(new AuthenticationToken { Name = OpenIdConnectParameterNames.IdToken, Value = old_id_token }); 
    tokens.Add(new AuthenticationToken { Name = OpenIdConnectParameterNames.AccessToken, Value = new_access_token }); 
    tokens.Add(new AuthenticationToken { Name = OpenIdConnectParameterNames.RefreshToken, Value = new_refresh_token }); 

    var expiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResult.ExpiresIn); 
    tokens.Add(new AuthenticationToken { Name = "expires_at", Value = expiresAt.ToString("o", CultureInfo.InvariantCulture) }); 
    var info = await this.httpContext.HttpContext.AuthenticateAsync("Cookies"); 
    //get the updated user profile (claims) 
    var response = await userInfoClient.GetAsync(new_access_token); 
    info.Properties.StoreTokens(tokens); 

    //merge the new claims with the current principal 
    var currentIdentity = info.Principal.Identity as ClaimsIdentity; 
    var distinctClaimTypes = response.Claims.Select(x => x.Type).Distinct(); 
    foreach (var claimType in distinctClaimTypes) 
    { 
     var currentCount = currentIdentity.Claims.Count(x => x.Type == claimType); 
     if (currentCount > 0) 
     { 
      //remove the claims from the current 
      var currentClaims = currentIdentity.Claims.Where(x => x.Type == claimType).ToList(); 
      foreach (var currentClaim in currentClaims) 
      { 
       currentIdentity.RemoveClaim(currentClaim); 
      } 
     } 

     //add the new claims 
     currentIdentity.AddClaims(response.Claims.Where(x => x.Type == claimType)); 
    } 

    //update the cookies with the new principal and identity 
    await this.httpContext.HttpContext.SignInAsync("Cookies", info.Principal, info.Properties); 

    return true; 
} 

おそらく "oidc"で認証/署名する方法があります。私は試しましたが、動作させることができませんでした。

+0

こんにちは、私は非常に似たようなことをしようとしていますが、それぞれの更新時にカスタムクレームの1つを更新するような、「コンテキスト」を切り替える必要があります。しかし、最新の有効期限を除いて、リフレッシュトークンはあまり効果がないようです。私はuserInfoClientにカスタムパラメータを渡す方法を理解できないので、ProfileServiceから同じカスタム要求を取得します。何かヒント?ありがとう – Whoever

関連する問題