Google認証をASP.NETCore 2.0 Web APIに統合しようとしていますが、それを機能させる方法がわかりません。
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
_を返すようにするにはどうすればよいですか?
後世のための私の究極のアプローチを投稿します。
Tratcherが指摘したように、AddGoogle
ミドルウェアは実際にはJWT認証フロー用ではありません。さらに調査を行った後、私が最終的に望んでいたのは、ここで説明されているものであることに気付きました: https://developers.google.com/identity/sign-in/web/backend-auth
だから私の次の問題は
さらに掘り下げた後、このクラスとメソッドを使用して、JWT検証サポートがC#に追加されたことがわかりました ここ :Google.Apis.Auth.Task<GoogleJsonWebSignature.Payload> ValidateAsync(string jwt, GoogleJsonWebSignature.ValidationSettings validationSettings)
次に、組み込みのJWT検証を置き換える方法を理解する必要がありました。これからSO質問私はアプローチを思いついた: 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, 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検証をクリアし、カスタム検証を追加する必要もありました。
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());
}
もっと簡単な方法があるかもしれませんが、これは私が着陸した場所であり、うまく機能しているようです!簡単にするためにここから省略した追加の作業がありました。たとえば、ユーザーのDBに、Googleが提供するクレームに一致するユーザーが既に存在するかどうかを確認するため、上記のコードが100%機能しない場合はお詫びします。不注意で何かを削除した可能性があります。
Google OpenID Connectトークンの検証を処理するために NuGetパッケージ を公開しました。
このパッケージは、 Microsoft.AspNetCore.Authentication.JwtBearer のMicrosoftのJWT検証および認証ハンドラーに依存しており、ホストされたドメインに関する検証がいくつか追加されています。
UseGoogle
に単一のパブリック拡張メソッドJwtBearerOptions
が含まれており、他の依存関係なしでGoogle OpenIDConnectトークンを検証するようにハンドラーを構成できます。
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(jwt => jwt.UseGoogle(
clientId: "<client-id-from-Google-API-console>",
hostedDomain: "<optional-hosted-domain>"));
ソースを確認したい場合は、それを見つけることができます ここ 。