見つけました!サンプルコードのリフレッシュトークンを使用して、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"で認証/署名する方法があります。私は試しましたが、動作させることができませんでした。
こんにちは、私は非常に似たようなことをしようとしていますが、それぞれの更新時にカスタムクレームの1つを更新するような、「コンテキスト」を切り替える必要があります。しかし、最新の有効期限を除いて、リフレッシュトークンはあまり効果がないようです。私はuserInfoClientにカスタムパラメータを渡す方法を理解できないので、ProfileServiceから同じカスタム要求を取得します。何かヒント?ありがとう – Whoever