Sam*_*Sam 5 asp.net jwt asp.net-web-api asp.net-core asp.net-core-2.0
我在ASP.NET Core 2.0 Web和API应用程序中使用混合身份验证.这意味着饼干和现在添加JWT token.
应用程序的Web部分使用cookie,在API部分中,我想使用JWT令牌.
我的问题是如何获得索赔JWT token?在我的网络控制器中,我可以简单地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)
};
});
}
Run Code Online (Sandbox Code Playgroud)
Era*_*cht 10
通常,JWT的声明会自动添加到ClaimsIdentity中.
资料来源:
https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/af5e5c2b0100e8348c63e2d2bb45612e2080841e/src/System.IdentityModel.Tokens.Jwt/JwtSecurityTokenHandler.cs#L1110).
所以你应该只能使用基础'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');
...
}
Run Code Online (Sandbox Code Playgroud)
从JWT令牌获取声明我从未遇到任何问题.但到目前为止我只使用了IdentityServer4.AccessTokenValidation.但在内部它使用Microsoft JWT Handler afaik.
无法发表评论,因为我的帖子太长,所以改为单独发帖。
如果您按照 ErazerBrecht 发布的指南/链接进行操作,则声明确实存储在 ClaimsPrincipal User 中。我创建了一个扩展方法来检索声明。
请注意,我使用枚举来注册我的声明。我使用字典将我的声明传递给生成令牌的方法,因此我的声明键应该始终是唯一的。
扩展方法:
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;
}
Run Code Online (Sandbox Code Playgroud)
称呼它为:
var userId = User.GetClaim(JwtClaim.UserId);
Run Code Online (Sandbox Code Playgroud)