【发布时间】:2018-11-08 14:08:37
【问题描述】:
我正在尝试从我的 .net 核心 webapi 应用程序验证 google jwt 不记名令牌并不断收到 401。我已经通过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;
}
【问题讨论】:
-
只是出于兴趣,您为什么使用 Google 发布的 JWT?为什么不让 Google 验证您的用户,然后发布您自己的令牌。这是您的 API,而不是 Google。您的应用程序中是否确实需要这样做,或者您是否只认为这是基于您链接到的 SO 问题的方式?
-
@Brad 我对通过社交帐户进行身份验证还很陌生。我认为这是正确的方法。有没有更好的办法?
-
就个人而言,我使用IdentityServer4。这是所有身份验证方法的一个很好的解决方案,并且他们有社交登录的示例。
-
@Brad 查看 IdentityServer4,它似乎是一个更简单且功能齐全的解决方案。我真的找不到任何关于如何将其添加到现有解决方案的文档。是不是就像添加一个新的 IdentityServer 项目并将端口设置为 5000 一样简单?
-
我提供的链接是文档。它包含设置指南,并且在 Github 上有完整的解决方案示例。
标签: asp.net-core .net-core asp.net-core-mvc jwt google-authentication