使用AspNet Core 2.0的Google JWT身份验证 [英] Google JWT Authentication with AspNet Core 2.0
问题描述
我正在尝试将Google身份验证集成到我的ASP.NET Core 2.0 web api中,并且无法弄清楚如何让它正常工作。
我有这段代码在我的Startup.cs ConfigureServices
中:
services.AddIdentity< ApplicationUser, IdentityRole>()
.AddDefaultTokenProviders();
services.AddAuthentication()
.AddGoogle(googleOptions =>
{
googleOptions.ClientId =配置[身份验证:Google:ClientId];
googleOptions.ClientSecret =配置[身份验证:Google:ClientSecret];
});
在 Configure(IApplicationBuilder应用程序,IHostingEnvironment env)
app.UseAuthentication();
当我导航到授权
端点时,结果是一个 302 Found
,因为它可能是重定向到某个登录端点(我从未创建过)。如何防止重定向,并让API期待令牌并在没有提供令牌的情况下返回 401
?
正如Tratcher指出的那样出, AddGoogle
中间件实际上并不适用于JWT身份验证流程。在做了更多的研究之后,我意识到我最终需要的是这里描述的内容:
https://developers.google.com/identity/sign-in/web/backend-auth
所以我的下一个问题
- 我不能依赖标准的dotnet核心Jwt auth中间件,因为我需要将谷歌令牌验证委托给谷歌库 li>
- 没有将C#google验证程序列为该页面上的外部客户端库之一。
在进一步挖掘之后,我发现JWT验证支持已添加到C#此处使用此类和方法:
Google.Apis.Auth.Task< GoogleJsonWebSignature.Payload> ValidateAsync(string jwt,GoogleJsonWebSignature.ValidationSettings validationSettings)
接下来我需要弄清楚如何替换内置的JWT验证。从这个SO问题中我想出了一种方法:
ASP .NET核心JWT持票人令牌自定义验证
以下是我的自定义GoogleTokenValidator:
public class GoogleTokenValidator:ISecurityTokenValidator
{
private readonly JwtSecurityTokenHandler _tokenHandler;
$ b $ public GoogleTokenValidator()
{
_tokenHandler = new JwtSecurityTokenHandler();
}
public bool CanValidateToken =>真正;
public int MaximumTokenSizeInBytes {get;组; } = TokenValidationParameters.DefaultMaximumTokenSizeInBytes;
public bool CanReadToken(string securityToken)
{
return _tokenHandler.CanReadToken(securityToken);
$ b $公共ClaimsPrincipal ValidateToken(字符串securityToken,TokenValidationParameters validationParameters,out SecurityToken validatedToken)
{
validatedToken = null;
var payload = GoogleJsonWebSignature.ValidateAsync(securityToken,new GoogleJsonWebSignature.ValidationSettings())。 //这里是我委托给Google验证
var claims = new List< Claim>
{
新Claim(ClaimTypes.NameIdentifier,payload.Name),
新Claim(ClaimTypes.Name,payload.Name),
新索赔(JwtRegisteredClaimNames.FamilyName,payload。 FamilyName),
新索赔(JwtRegisteredClaimNames.GivenName,payload.GivenName),
新索赔(JwtRegisteredClaimNames.Email,payload.Email),
新索赔(JwtRegisteredClaimNames.Sub,payload.Subject) ,
新索赔(JwtRegisteredClaimNames.Iss,payload.Issuer),
};
尝试
{
var principle = new ClaimsPrincipal();
principle.AddIdentity(new ClaimsIdentity(claims,AuthenticationTypes.Password));
退货原则;
}
catch(Exception e)
{
Console.WriteLine(e);
throw;
$ / code>
Startup.cs
,我还需要清除默认的JWT验证,并添加我自定义的一个:
<$ p $
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options .DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(o =>
{
o.SecurityTokenValidators.Clear();
o .SecurityTokenValidators.Add(new GoogleTokenValidator());
}
方式,但这是我登陆的地方,它似乎工作正常!我做了额外的工作,我为了简单而离开这里,例如le,检查用户的数据库中是否已有用户与Google提供的索赔相匹配,因此,如果上述代码不能100%正常工作,我可能已经无意中删除了某些内容,我很抱歉。
I am trying to integrate google authentication in my ASP.NET Core 2.0 web api and I cannot figure out how to get it to work.
I have this code in my Startup.cs ConfigureServices
:
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddDefaultTokenProviders();
services.AddAuthentication()
.AddGoogle(googleOptions =>
{
googleOptions.ClientId = Configuration["Authentication:Google:ClientId"];
googleOptions.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
});
And this in Configure(IApplicationBuilder app, IHostingEnvironment env)
:
app.UseAuthentication();
When I navigate to an Authorized
endpoint, the result is a 302 Found
because presumably it is redirecting to some login endpoint (which I never created). How do I prevent the redirection and just have the API expect a token and return a 401
if no token is provided?
Posting my ultimate approach for posterity.
As Tratcher pointed out, the AddGoogle
middleware is not actually for a JWT authentication flow. After doing more research, I realized that what I ultimately wanted is what is described here:
https://developers.google.com/identity/sign-in/web/backend-auth
So my next problems were
- I could not rely on the standard dotnet core Jwt auth middleware anymore since I need to delegate the google token validation to google libraries
- There was no C# google validator listed as one of the external client libraries on that page.
After more digging, I found this that JWT validation support was added to C# here using this class and method:
Google.Apis.Auth.Task<GoogleJsonWebSignature.Payload> ValidateAsync(string jwt, GoogleJsonWebSignature.ValidationSettings validationSettings)
Next I needed to figure out how to replace the built in JWT validation. From this SO questions I came up with an approach: ASP.NET Core JWT Bearer Token Custom Validation
Here is my custom GoogleTokenValidator:
public class GoogleTokenValidator : ISecurityTokenValidator
{
private readonly JwtSecurityTokenHandler _tokenHandler;
public GoogleTokenValidator()
{
_tokenHandler = new JwtSecurityTokenHandler();
}
public bool CanValidateToken => true;
public int MaximumTokenSizeInBytes { get; set; } = TokenValidationParameters.DefaultMaximumTokenSizeInBytes;
public bool CanReadToken(string securityToken)
{
return _tokenHandler.CanReadToken(securityToken);
}
public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
{
validatedToken = null;
var payload = GoogleJsonWebSignature.ValidateAsync(securityToken, new GoogleJsonWebSignature.ValidationSettings()).Result; // here is where I delegate to Google to validate
var claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, payload.Name),
new Claim(ClaimTypes.Name, payload.Name),
new Claim(JwtRegisteredClaimNames.FamilyName, payload.FamilyName),
new Claim(JwtRegisteredClaimNames.GivenName, payload.GivenName),
new Claim(JwtRegisteredClaimNames.Email, payload.Email),
new Claim(JwtRegisteredClaimNames.Sub, payload.Subject),
new Claim(JwtRegisteredClaimNames.Iss, payload.Issuer),
};
try
{
var principle = new ClaimsPrincipal();
principle.AddIdentity(new ClaimsIdentity(claims, AuthenticationTypes.Password));
return principle;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
}
And in Startup.cs
, I also needed to clear out the default JWT validation, and add my custom one:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(o =>
{
o.SecurityTokenValidators.Clear();
o.SecurityTokenValidators.Add(new GoogleTokenValidator());
}
Maybe there is an easier way, but this is where I landed and it seems to work fine! There was additional work I did that I left out of here for simplicity, for example, checking if there is already a user in my user's DB that matches the claims provided by google, so I apologize if the code above does not 100% work since I may have removed something inadvertently.
这篇关于使用AspNet Core 2.0的Google JWT身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!