验证Google JWT

时间:2018-05-29 20:32:28

标签: asp.net-core .net-core asp.net-core-mvc jwt google-authentication

我正在尝试从我的.net核心webapi应用程序验证google jwt bearer令牌,并不断收到401s。我已通过jwt.io验证该令牌有效。我正在尝试实现这里提供的解决方案, google-jwt-authentication-with-aspnet-core-2-0

任何人都可以看到我的代码出了什么问题吗?

以下是我的代码:

Startup.cs

public void ConfigureServices(IServiceCollection services)
    {
        // Configure SnapshotCollector from application settings
        services.Configure<SnapshotCollectorConfiguration>(Configuration.GetSection(nameof(SnapshotCollectorConfiguration)));

        // Add SnapshotCollector telemetry processor.
        services.AddSingleton<ITelemetryProcessorFactory>(sp => new SnapshotCollectorTelemetryProcessorFactory(sp));

        conString = Microsoft
        .Extensions
        .Configuration
        .ConfigurationExtensions
        .GetConnectionString(this.Configuration, "DefaultConnection");

        services.AddDbContext<GotNextDBContext>(
            options =>
            options.UseSqlServer(conString));



        services.AddTransient<ILocationService, LocationService>();
        services.AddTransient<ICompanyService, CompanyService>();
        services.AddTransient<IUserLocationLogService, UserLocationLogService>();
        services.AddTransient<IUserService, UserService>();
        services.AddTransient<ILanguageService, LanguageService>();
        services.AddTransient<IGenderService, GenderService>();
        services.AddTransient<ISportService, SportService>();
        services.AddTransient<IMeasurementService, MeasurementService>();


        var clientIds = new List<string>();
        clientIds.Add("[myClientId]");
        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(clientIds: clientIds ));
        });

        services.AddRouting();
        services.AddAutoMapper();

        services.AddAntiforgery(options =>
        {

            options.Cookie.Name = "X-CSRF-TOKEN-GOTNEXT-COOKIE";                
            options.HeaderName = "X-CSRF-TOKEN-GOTNEXT-HEADER";
            options.SuppressXFrameOptionsHeader = false;
        });

        var serviceProvider = services.BuildServiceProvider();

        var context = serviceProvider.GetService<GotNextDBContext>();



    }

GoogleTokenValidator.cs

public class GoogleTokenValidator : ISecurityTokenValidator
{
    private readonly JwtSecurityTokenHandler _tokenHandler;
    private readonly IEnumerable<string> _clientIds;


    public GoogleTokenValidator()
    {
        _tokenHandler = new JwtSecurityTokenHandler();
    }
    public GoogleTokenValidator(IEnumerable<string> clientIds)
    {
        _tokenHandler = new JwtSecurityTokenHandler();
        _clientIds = clientIds;

    }

    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() { Audience = _clientIds }).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));
            return principle;
        }
        catch (Exception e)
        {

            Console.WriteLine(e);
            throw;

        }
    }
}

}

我正在使用Xamarin Forms中的belowHttpClient调用来访问端点。

using (var client = new HttpClient() { BaseAddress = new Uri("https://gotnext.azurewebsites.net/api/user/post/") })
            {
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                client.DefaultRequestHeaders.Add(verificationToken.tokenName, verificationToken.token);
                //client.DefaultRequestHeaders.Add("X-ZUMO-AUTH", googleUser.GoogleAuthToken);
                client.DefaultRequestHeaders.Add("Bearer", googleUser.GoogleIdToken);
                var json = JsonConvert.SerializeObject(newUser);
                var content = new StringContent(json, Encoding.UTF8, "application/json");



                response = client.PostAsync(client.BaseAddress, content).Result;

            }

2 个答案:

答案 0 :(得分:0)

您添加到ClaimsIdentity的{​​{1}}没有ClaimsPrincipal设置,因此AuthenticationType始终为false(source)。

IsAuthenticated

您可以将身份验证类型设置为任何值,只要它不为空。

答案 1 :(得分:0)

逐步在本地抛出代码,此行:return new ClaimsPrincipal(new ClaimsIdentity(声明为“ Google”));正在返回经过身份验证的身份。但是它 仍在返回401。我感觉我已经很近了!!

我也在我的Web应用程序中对Google进行身份验证(我从那里走了:enter link description here),并且花了很多时间来研究所有这些。 在您的解决方案中,只需添加以下内容:

1)

//at "ConfigureServices" in "Startup.cs":
services.AddAuthorization(options =>
        {
            options.DefaultPolicy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme)
                .RequireAuthenticatedUser()
                .Build();
        });

2)上面怎么说也要

return new ClaimsPrincipal(new ClaimsIdentity(claims, "Google"));