Je développe une API simple qui gère l'authentification faite par Firebase - à utiliser plus tard avec les clients Android.
Donc, dans la console Firebase, j'ai activé les méthodes de connexion Facebook et Google et créé un exemple de page html que je peux utiliser pour tester la méthode de connexion - cette fonction suivante est appelée par un bouton:
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);
});
}
ensuite j'utilise le token et l'envoie à mon API avec un simple appel ajax de jQuery ici:
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;
}
});
}
Prochain arrêt: le backend API - écrit avec .NET Core.
Sous le démarrage, j'ai configuré l'authentification JwtBearer (package 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,
},
});
Et voici le code du contrôleur - avec le [Authorize]
attribut:
[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();
}
}
La réponse de l'API est 200 OK (HttpContext.User.Identity.IsAuthenticated
est true
dans le Controller), mais je pense que non. Mon problème est que je ne suis pas entièrement sûr que ce soit sécurisé.
Comment cela vérifie-t-il la partie signature du jeton JWT? J'ai vu beaucoup d'échantillons de code mentionnant l'algorithme x509 ou RS256, où vont-ils avec cela? Ne devrait pas vérifier une sorte de certificat ou de clé privée avec le IssuerSigningKey
ou TokenDecryptionKey
de la classe TokenValidationParameters
? Qu'est-ce qui me manque?
Sources de connaissances pertinentes sur la question:
Firebase utilise le RSA256 cryptosystème à clé asymétrique, ce qui signifie qu'il possède une clé publique et une clé privée. Signature un jeton se produit avec la clé privée, tandis que vérification d'un jeton se produit avec la clé publique.
Le diagramme suivant illustre comment la signature de jeton se produit.
Lors de la connexion et de l'accès à un point de terminaison sécurisé, les étapes suivantes sont impliquées.
JwtBearerMiddleware
appelle https://securetoken.google.com/my-firebase-project/.well-known/openid-configuration
, où il peut accéder aux clés publiques actuelles de Google. Il est important que lorsque nous utilisons un système de cryptage asymétrique à clé publique, la la clé publique ne soit pas gardée secrète, mais elle est publiée à la vue de tous.Authorization
. À ce stade, le JwtBearerMiddleware
dans le pipeline vérifie ce jeton et vérifie s'il est valide (s'il a été signé avec la clé privée de Google). La chose importante à réaliser ici est que pour faire la vérification, notre Api n'a pas besoin d'avoir accès à la clé privée. Seule la clé publique est nécessaire pour cela. Après vérification, le middleware remplit HttpContext.User
, et HttpContext.User.Identity.IsAuthenticated
en conséquence.Vous pouvez trouver une description encore plus simple de ce concept sur la page Wikipedia RSA , et plus d'informations sur Firebase + ASP.NET dans mon article de blog .
Pour le côté backend, il existe un package Nuget qui fait l'affaire pour vous:
Install-Package AspNetCore.Firebase.Authentication
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseFirebaseAuthentication("https://securetoken.google.com/MYPROJECTNAME", "MYPROJECTNAME");
}
Il fait l'audience, l'émetteur, la signature et la validation de la validité
Le paquet NuGet utilise l'ancien mécanisme d'authentification ASP NET Core 1.x
L'authentification a été modifiée: https://docs.Microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x