ASP.Net Core Webアプリケーションを作成し、UseOpenIdConnectAuthentication
を使用してIdentityServer3に接続しています。 ASP.Net MVC 5サンプルをエミュレートするIdentity Serverから受け取ったクレームを変換して、「 確かに必要のない低レベルのプロトコルクレーム 」を削除しようとしています。 MVC 5では、SecurityTokenValidated通知のハンドラーを追加して、必要なクレームのみを持つものとAuthenticationTicket
を交換します。
ASP.Net Coreでは、同等のことを行うには、OnTokenValidated
内のOpenIdConnectEvents
を処理する必要があると思いました。ただし、その段階では、追加のスコープ情報が取得されているようには見えません。 OnUserInformationReceived
を処理する場合、追加情報は存在しますが、プリンシパルではなくユーザーに保存されます。
他のイベントはどれも、認証が完了した後に保持することに興味がないクレームを永久に削除する明白な場所のようには見えません。どんな提案もありがたく受けました!
プロセスの早い段階で変換するというLeastPrivilegeの提案が好きです。提供されたコードは完全には機能しません。このバージョンは次のことを行います。
var oidcOptions = new OpenIdConnectOptions
{
...
Events = new OpenIdConnectEvents
{
OnTicketReceived = e =>
{
e.Principal = TransformClaims(e.Ticket.Principal);
return Task.CompletedTask;
}
}
};
これは、Principal
ではなくTicket
を置き換えます。私の他の回答のコードを使用して、新しいPrincipal
を作成できます。同時にTicket
を置き換えることもできますが、それが必要かどうかはわかりません。
ですから、私の質問にほぼ答える方法を提案してくれたLeastPrivilegeとAdemに感謝します...コードだけを少し調整する必要がありました。全体として、クレームを早期に変換するというLeastPrivilegeの提案を好みます。
OnSigningIn
のSignInScheme
イベントを実装できます。次に例を示します。
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
AuthenticationScheme = "OpenIdCookies",
AutomaticAuthenticate = true,
Events = new CookieAuthenticationEvents()
{
OnSigningIn = async (context) =>
{
ClaimsIdentity identity = (ClaimsIdentity)context.Principal.Identity;
identity.Claims = identity.Claims.Where(...);
}
}
});
var oidcOptions = new OpenIdConnectOptions
{
AuthenticationScheme = "oidc",
SignInScheme = "OpenIdCookies"
};
//.. set other options
app.UseOpenIdConnectAuthentication(oidcOptions);
返信ありがとうAdem ...問題の大部分を解決しました...唯一の問題はそのアイデンティティです。クレームは読み取り専用プロパティです。ただし、新しいプリンシパルの作成は機能することがわかりました。
Events = new CookieAuthenticationEvents()
{
OnSigningIn = (context) =>
{
ClaimsIdentity identity = (ClaimsIdentity)context.Principal.Identity;
var givenName = identity.FindFirst(Constants.ClaimTypes.GivenName);
var familyName = identity.FindFirst(Constants.ClaimTypes.FamilyName);
var sub = identity.FindFirst(Constants.ClaimTypes.Subject);
var claimsToKeep = new List<Claim> {givenName, familyName, sub};
var newIdentity = new ClaimsIdentity(claimsToKeep, identity.AuthenticationType);
context.Principal = new ClaimsPrincipal(newIdentity);
return Task.FromResult(0);
}
}
これが正しいアプローチであるかどうかはわかりませんが、機能しているようです。
私は個人的に、実際の認証が行われるミドルウェアでクレーム変換を行うことを好みます。
そのために、OIDCミドルウェアでOnTicketReceivedイベントを使用できます。
var oidcOptions = new OpenIdConnectOptions
{
AuthenticationScheme = "oidc",
SignInScheme = "cookies",
Authority = Clients.Constants.BaseAddress,
ClientId = "mvc.hybrid",
ClientSecret = "secret",
ResponseType = "code id_token",
SaveTokens = true,
TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = JwtClaimTypes.Name,
RoleClaimType = JwtClaimTypes.Role,
},
Events = new OpenIdConnectEvents
{
OnTicketReceived = e =>
{
ClaimsPrincipal p = TransformClaims(e.Ticket.Principal);
e.Ticket = new AuthenticationTicket(
p,
e.Ticket.Properties,
e.Ticket.AuthenticationScheme);
return Task.CompletedTask;
}
}
};