Vous pouvez obtenir un jeton d'identification (JWT) lorsque vous vous connectez à l'aide de l'authentification Firebase. Par exemple, lors de l'authentification de connexion avec SPA, vous souhaiterez peut-être vous connecter à l'aide de Firebase avec un client (JavaScript), envoyer le jeton acquis au serveur et associer l'uid dans JWT à l'utilisateur géré par l'application. Je pense que oui.
Cette fois, j'écrirai principalement la méthode de vérification de JWT côté serveur (java + SpringBoot).
Cette fois, j'utiliserai Nuxt. Comment obtenir et envoyer des jetons.
Processus d'authentification (extrait)
async signin() {
try {
//Authentifiez-vous à l'aide de l'adresse e-mail et du mot de passe
await firebase.auth().signInWithEmailAndPassword(this.email, this.password)
//Obtenir un jeton d'identification (JWT)
const token = await firebase.auth().currentUser.getIdToken(true)
//Enregistrer dans le stockage local
localStorage.setItem('token', token)
//Transition vers la page après authentification
this.$router.push('/')
} catch (e) {
//Au moment d'une erreur d'authentification ou d'une erreur d'acquisition de jeton
console.log(e)
}
}
~/plugins/axios.js
export default function ({ $axios }) {
$axios.onRequest(config => {
const token = localStorage.getItem('token');
if (token) {
//S'il y a un jeton dans le stockage local, donnez-le à l'en-tête de la demande (autorisation)
config.headers.common['Authorization'] = "Bearer " + token;
}
})
}
Utilisez OnecePerRequestFilter de Spring Security.
De plus, les bibliothèques suivantes sont utilisées.
Nom de la bibliothèque | Utilisation |
---|---|
OkHttp | Client HTTP |
jjwt | Vérification JWT |
LoginFilter.java
@Component
public class LoginFilter extends OncePerRequestFilter {
//Enregistrez ObjectMapper en tant que bean à l'avance.
@Autowired
ObjectMapper objectMapper;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
//Définir les informations de connexion de l'utilisateur en contexte
SecurityContextHolder.getContext().setAuthentication(new PreAuthenticatedAuthenticationToken(
auth(request), null));
filterChain.doFilter(request, response);
}
//Obtenir les informations de connexion de l'utilisateur
private LoginUser auth(HttpServletRequest request) {
//Extraire JWT de l'en-tête de la demande
String token = getToken(request);
try {
//Vérifiez JWT, obtenez des réclamations
//Si la validation échoue, une exception est levée.
Jws<Claims> claim = Jwts.parser()
.setSigningKeyResolver(new GoogleSigningKeyResolver()) //Besoin de votre propre résolveur
.parseClaimsJws(token);
//Obtenez l'ID de la partie du corps de la réclamation
String uid = (String)claim.getBody().get("user_id");
//Obtenez uid et recherchez des informations sur les utilisateurs
User user = userService.findByUid(uid);
if(user == null){
throw new BadCredentialsException("L'utilisateur n'existe pas");
}
return new LoginUser(user);
} catch (Exception e) {
throw new BadCredentialsException("Jeton invalide");
}
}
//Obtenez le jeton de l'en-tête de la demande.
private String getToken(HttpServletRequest request) {
String token = request.getHeader("Authorization");
if (token == null || !token.startsWith("Bearer ")) {
return null;
}
return token.substring("Bearer ".length());
}
/**
*Nous vous retournerons la clé publique utilisée pour la signature.
*
* @author h.ono
*
*/
public class GoogleSigningKeyResolver extends SigningKeyResolverAdapter {
@Override
public Key resolveSigningKey(JwsHeader jwsHeader, Claims claims) {
try {
Map<String, Object> map = getJwks();
if (map.isEmpty()) {
return null;
}
String keyValue = (String) map.get(jwsHeader.getKeyId());
if (keyValue == null) {
return null;
}
//Point important
//Supprimez les étiquettes de début (BEGIN) et de fin (END).
keyValue = keyValue
.replaceAll("-----BEGIN CERTIFICATE-----\n", "")
.replaceAll("-----END CERTIFICATE-----\n", "");
InputStream in = new ByteArrayInputStream(Base64.decodeBase64(keyValue.getBytes("UTF-8")));
X509Certificate certificate = (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(in);
return certificate.getPublicKey();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
*Obtenez JWKS de Google.
*
* @return JWKS
*/
private Map<String, Object> getJwks() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://www.googleapis.com/robot/v1/metadata/x509/[email protected]")
.build();
try (Response response = client.newCall(request).execute()) {
return objectMapper.readValue(response.body().string(), new TypeReference<Map<String, Object>>() {
});
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
J'ai pu associer l'UID obtenu de Firebase à l'utilisateur qui possède l'application. J'ai fait beaucoup de recherches, mais la plupart de l'authentification a été effectuée côté client, j'ai donc eu du mal à arriver à une méthode comme celle-ci. .. ..
Lors de la vérification de JWT, j'ai également essayé java-jwt fourni par auth0, mais lors de l'obtention de la clé publique, Je n'ai pas pu l'obtenir car il ne prend pas en charge le format X.509.
Recommended Posts