我在我的Startup.cs ConfigureServices中有这个代码:
services.AddIdentity<ApplicationUser,IdentityRole>() .AddDefaultTokenProviders(); services.AddAuthentication() .AddGoogle(googleOptions => { googleOptions.ClientId = Configuration["Authentication:Google:ClientId"]; googleOptions.ClientSecret = Configuration["Authentication:Google:ClientSecret"]; });
这在Configure(IApplicationBuilder app,IHostingEnvironment env)中:
app.UseAuthentication();
当我导航到授权端点时,结果是302 Found,因为可能是它重定向到某个登录端点(我从未创建过).如何阻止重定向,只是让API期望一个令牌,如果没有提供令牌,则返回401?
解决方法
正如Tratcher所指出的,AddGoogle中间件实际上并不适用于JWT身份验证流程.经过更多的研究,我意识到我最终想要的是这里描述的内容:
https://developers.google.com/identity/sign-in/web/backend-auth
所以我的下一个问题是
>我不能再依赖标准的dotnet核心Jwt auth中间件,因为我需要将谷歌令牌验证委托给谷歌图书馆
>没有C#google验证器列为该页面上的外部客户端库之一.
经过更多挖掘,我发现使用此类和方法将JWT验证支持添加到C#here:
Google.Apis.Auth.Task< GoogleJsonWebSignature.Payload> ValidateAsync(string jwt,GoogleJsonWebSignature.ValidationSettings validationSettings)
接下来我需要弄清楚如何替换内置的JWT验证.从这个问题我想出了一个方法:
ASP.NET Core JWT Bearer Token Custom Validation
这是我的自定义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,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; } } }
在Startup.cs中,我还需要清除默认的JWT验证,并添加我的自定义验证:
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()); }
也许有一个更简单的方法,但这是我降落的地方,它似乎工作正常!我做了额外的工作,为了简单起见,我离开了这里,例如,检查我的用户的数据库中是否已有用户与谷歌提供的声明匹配,所以如果上面的代码不是100%工作,我很抱歉我可能无意中删除了一些东西.