ASP.NET Core 2.0 WebおよびAPIアプリで混合認証を使用しています。両方のCookieを意味し、現在JWT token
。
アプリのWebパーツはCookieを使用し、APIパーツではJWTトークンを使用します。
私の質問は、どのようにしてJWT token
? Webコントローラーでは、単にHttpContext.User;
Cookieに保存されているクレームを取得します。使用するAPIメソッドでそれをどのように処理しますかJWT token
?
AuthenticationBuilderは次のとおりです。
public static void MyAuthenticationConfig(IServiceCollection services, IConfiguration configuration)
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = "myApp_cookie";
options.DefaultChallengeScheme = "myApp_cookie";
})
.AddCookie("myApp_cookie", options =>
{
options.AccessDeniedPath = "/Unauthorized";
options.LoginPath = "/Login";
})
.AddCookie("social_auth_cookie")
.AddOAuth("LinkedIn", options =>
{
options.SignInScheme = "social_auth_cookie";
options.ClientId = "my_client_id";
options.ClientSecret = "my_secret";
options.CallbackPath = "/linkedin-callback";
options.AuthorizationEndpoint = "https://www.linkedin.com/oauth/v2/authorization";
options.TokenEndpoint = "https://www.linkedin.com/oauth/v2/accessToken";
options.UserInformationEndpoint = "https://api.linkedin.com/v1/people/~:(id,first-name,last-name,email-address,picture-url,picture-urls::(original))";
options.Scope.Add("r_basicprofile");
options.Scope.Add("r_emailaddress");
options.Events = new OAuthEvents
{
OnCreatingTicket = OnCreatingTicketLinkedInCallBack,
OnTicketReceived = OnTicketReceivedCallback
};
})
.AddFacebook(options =>
{
options.SignInScheme = "social_auth_cookie";
options.AppId = "my_app_is";
options.AppSecret = "my_secret";
options.Events = new OAuthEvents
{
OnCreatingTicket = OnCreatingTicketFacebookCallback,
OnTicketReceived = OnTicketReceivedCallback
};
})
.AddGoogle(options =>
{
options.SignInScheme = "social_auth_cookie";
options.ClientId = "my_id.apps.googleusercontent.com";
options.ClientSecret = "my_secret";
options.CallbackPath = "/google-callback";
options.Events = new OAuthEvents
{
OnCreatingTicket = OnCreatingTicketGoogleCallback,
OnTicketReceived = OnTicketReceivedCallback
};
})
.AddJwtBearer("JwtBearer", jwtBearerOptions =>
{
jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("my_secret")),
ValidateIssuer = true,
ValidIssuer = "my-api",
ValidateAudience = true,
ValidAudience = "my-client",
ValidateLifetime = true,
ClockSkew = TimeSpan.FromMinutes(5)
};
});
}
通常、JWTのクレームはClaimsIdentityに自動的に追加されます。
そのため、ベースの「Controller」クラスの「User」プロパティを使用することができるはずです。
public async Task<IActionResult> Get()
{
// TODO Move 'Claims' extraction code to an extension method
var address = User.Claims.Where('GET THE NEEDED CLAIM');
...
}
JWTトークンからクレームを取得するのに問題はありませんでした。ただし、これまでIdentityServer4.AccessTokenValidationのみを使用していました。しかし内部的には、Microsoft JWT Handler afaikを使用しています。
私の投稿が長くなるのでコメントできなかったので、代わりに別の投稿を作成しました。
ErazerBrechtが投稿したガイド/リンクをたどると、クレームは実際にClaimsPrincipalユーザーに保存されます。クレームを取得する拡張メソッドを作成しました。
クレームを登録するために列挙を使用していることに注意してください。辞書を使用して、トークンを生成するメソッドにクレームを渡すため、クレームキーは常に一意である必要があります。
拡張メソッド:
public static string GetClaim(this ClaimsPrincipal claimsPrincipal, JwtClaim jwtClaim)
{
var claim = claimsPrincipal.Claims.Where(c => c.Type == jwtClaim.ToString()).FirstOrDefault();
if (claim == null)
{
throw new JwtClaimNotFoundException(jwtClaim);
}
return claim.Value;
}
次のように呼び出します:
var userId = User.GetClaim(JwtClaim.UserId);