使用 AspNet Core 2.0 的 Google JWT 身份验证 [英] Google JWT Authentication with AspNet Core 2.0

查看:23
本文介绍了使用 AspNet Core 2.0 的 Google JWT 身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 google 身份验证集成到我的 ASP.NET Core 2.0 web api 中,但我不知道如何让它工作.

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.

我的 Startup.cs 中有此代码 ConfigureServices:

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"];
});

Configure(IApplicationBuilder app, IHostingEnvironment env):

 app.UseAuthentication();

当我导航到 Authorized 端点时,结果是 302 Found 因为大概它正在重定向到某个登录端点(我从未创建过).如果没有提供令牌,如何防止重定向并让 API 期待令牌并返回 401 ?

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.

正如 Tratcher 指出的那样,AddGoogle 中间件实际上并不用于 JWT 身份验证流程.在做了更多的研究之后,我意识到我最终想要的是这里描述的内容:https://developers.google.com/identity/sign-in/web/backend-auth

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

所以我的下一个问题是

  1. 我不能再依赖标准的 dotnet 核心 Jwt auth 中间件,因为我需要将谷歌令牌验证委托给谷歌库
  2. 该页面上没有将 C# google 验证器列为外部客户端库之一.

经过更多挖掘,我发现 JWT 验证支持已添加到 C# here 使用这个类和方法:Google.Apis.Auth.TaskValidateAsync(string jwt, GoogleJsonWebSignature.ValidationSettings validationSettings)

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)

接下来我需要弄清楚如何替换内置的 JWT 验证.从这个 SO 问题我想出了一种方法:ASP.NET Core JWT 承载令牌自定义验证

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

这是我的自定义 GoogleTokenValidator:

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;

        }
    }
}

并且在 Startup.cs 中,我还需要清除默认的 JWT 验证,并添加我的自定义验证:

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());
                }

也许有更简单的方法,但这是我降落的地方,它似乎工作正常!为了简单起见,我做了一些额外的工作,例如,检查我的用户的数据库中是否已经有一个用户与谷歌提供的声明相匹配,所以如果上面的代码不能 100% 工作,我深表歉意.我可能无意中删除了一些东西.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆