Firebaseによって行われた認証を処理するシンプルなAPIを開発しています-後でAndroidクライアントで使用するために。
そのため、FirebaseコンソールでFacebookおよびGoogleのサインインメソッドを有効にし、それを使用してログインメソッドをテストできるサンプルhtmlページを作成しました。この次の関数はボタンによって呼び出されます。
function loginFacebook() {
var provider = new firebase.auth.FacebookAuthProvider();
var token = "";
firebase.auth().signInWithPopup(provider).then(function (result) {
var token = result.credential.accessToken;
var user = result.user;
alert("login OK");
user.getToken().then(function (t) {
token = t;
loginAPI();
});
}).catch(function (error) {
var errorCode = error.code;
var errorMessage = error.message;
alert(errorCode + " - " + errorMessage);
});
}
次に、トークンを使用して、jQueryからの単純なajax呼び出しでAPIに送信します。
function loginAPI()
{
$.ajax({
url: "http://localhost:58041/v1/Users/",
dataType: 'json',
type: 'GET',
beforeSend: function (xhr) {
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Authorization", "Bearer " + token);
},
error: function (ex) {
console.log(ex.status + " - " + ex.statusText);
},
success: function (data) {
console.log(data);
return data;
}
});
}
次のステップ:APIバックエンド-.NET Coreで作成された。
スタートアップの下で、JwtBearer Auth(パッケージMicrosoft.AspNetCore.Authentication.JwtBearer
):
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
IncludeErrorDetails = true,
Authority = "https://securetoken.google.com/PROJECT-ID",
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = "https://securetoken.google.com/PROJECT-ID",
ValidateAudience = true,
ValidAudience = "PROJECT-ID",
ValidateLifetime = true,
},
});
そして、ここにコントローラーコードがあります-[Authorize]
属性:
[Authorize]
[Route("v1/[controller]")]
public class UsersController : Controller
{
private readonly ILogger _logger;
private readonly UserService _userService;
public UsersController(ILogger<UsersController> logger, UserService userService)
{
_logger = logger;
_userService = userService;
}
[HttpGet]
public async Task<IList<User>> Get()
{
return await _userService.GetAll();
}
}
APIレスポンスは200 OK(HttpContext.User.Identity.IsAuthenticated
はController内のtrue
ですが、そうすべきではないと思います。私の問題は、これが安全であることを完全に確信していないことです。
JWTトークンの署名部分をどのようにチェックしていますか? x509またはRS256アルゴリズムに言及しているコードサンプルをたくさん見ましたが、どこに適合しますか? IssuerSigningKey
クラスのTokenDecryptionKey
またはTokenValidationParameters
を使用して、何らかの証明書または秘密キーをチェックするべきではありませんか?私は何が欠けていますか?
問題に関する関連する知識源:
FirebaseはRSA256非対称キー暗号システムを使用します。つまり、公開キーと秘密キーがあります。 トークンへの署名は秘密鍵で行われ、トークンの検証は公開鍵で行われます。
次の図は、トークン署名がどのように行われるかを示しています。
サインインして安全なエンドポイントにアクセスする際には、次の手順が必要です。
JwtBearerMiddleware
はhttps://securetoken.google.com/my-firebase-project/.well-known/openid-configuration
を呼び出し、Googleの現在の公開キーにアクセスできます。公開鍵非対称暗号システムを使用している場合、公開鍵は秘密として保持されませんが、重要なことは公開されています。Authorization
ヘッダーにトークンを入れます。この時点で、パイプラインのJwtBearerMiddleware
はこのトークンをチェックし、有効かどうか(Googleの秘密キーで署名されているかどうか)を確認します。ここで重要なことは、検証を行うために、Apiが秘密キーにアクセスする必要がないことです。そのためには公開鍵のみが必要です。検証後、ミドルウェアはHttpContext.User
、およびそれに応じてHttpContext.User.Identity.IsAuthenticated
を取り込みます。RSA Wikipedia page でこの概念のさらに簡単な説明を見つけることができます。また、 私のブログ投稿 でFirebase + ASP.NETに関する詳細情報を見つけることができます。
バックエンド側には、あなたのためのトリックを行うNugetパッケージがあります:
インストールパッケージAspNetCore.Firebase.Authentication
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseFirebaseAuthentication("https://securetoken.google.com/MYPROJECTNAME", "MYPROJECTNAME");
}
対象者、発行者、署名、妥当性の検証を行います
NuGetパケットは、古いASP NET Core 1.x認証メカニズムを使用しています
認証が変更されました: https://docs.Microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x