2017-07-21 5 views
2

Ich habe eine Spring JWT-Autorisierungsanwendung erstellt. JWT enthält einige benutzerdefinierte Ansprüche. Auf der Seite eines Ressourcenservers frage ich mich, wo ich den JWT-Token analysieren sollte, um diese Behauptungen zu sammeln und zu überprüfen. Soll ich das in einem Controller oder in einem Filter tun? Was ist die beste Praxis? Vielleicht hast du ein Beispiel?Spring Framework - Wo kann JWT für benutzerdefinierte Ansprüche analysiert werden?

+0

Sie über den Zweck dieser benutzerdefinierten Ansprüche erarbeiten kann? Standardmäßig sucht Spring Security nach dem Berechtigungsanspruch, den Sie mit Rollen oder anderen Berechtigungen füllen können, und schützt dann Methoden und Endpunkte mit der Annotation @ PreAuthorize. –

+1

Ich denke, Ihre benutzerdefinierten Ansprüche im JWT-Token müssen Ihrer Anwendung bekannt sein. Im Idealfall sollte es Teil Ihres Filters sein, um die Authentifizierungswerte zu extrahieren und im Spring Security-Kontext festzulegen. Von wo, würde es von Auth Manager genommen werden, um zu überprüfen. Später können alle Dinge von Spring security selbst erledigt werden, wie @punkrocker27ka vorgeschlagen hat. Werfen Sie einen Blick auf meine Implementierung für die Idee: https://github.com/deepak-java/jwt-spring-boot –

+0

@ punkrocker27ka Ich brauche benutzerdefinierte Ansprüche, um einige Geschäftslogik abdecken, sind Standardansprüche nicht genug. Deepak Singh dankt für die Implementierung, die mir helfen wird! – dplesa

Antwort

3

Sie können eine Kombination aus Jackson Object Mapper und Spring Security-Klassen verwenden, nämlich JWt, JwtHelper und Authentication. Sie können die Authentifizierung mithilfe des statischen Kontextobjekts von Spring Security abrufen und dann das Token analysieren, das Sie mithilfe von JwtHelper erhalten.

ObjectMapper objectMapper = new ObjectMapper(); 
Authentication authentication = 
SecurityContextHolder.getContext().getAuthentication(); 
Map<String, Object> map = 
objectMapper.convertValue(authentication.getDetails(), Map.class); 

// create a token object to represent the token that is in use. 
Jwt jwt = JwtHelper.decode((String) map.get("tokenValue")); 

// jwt.getClaims() will return a JSON object of all the claims in your token 
// Convert claims JSON object into a Map so we can get the value of a field 
Map<String, Object> claims = objectMapper.readValue(jwt.getClaims(), Map.class); 
String customField = (String) claims.get("you_custom_field_name"); 

Ich würde vorschlagen das Debuggen und einen Haltepunkt in der dritten Zeile im Code oben setzen. Zeigen Sie zu diesem Zeitpunkt das Authentifizierungsobjekt an. Ich könnte einige nützliche Details haben, die Sie später brauchen.

Dies kann alles auf dem Controller erfolgen. Ich bin nicht sicher, wie man den Filter dazu benutzt.

+0

Das fühlt sich hässlich an, aber es funktioniert (danke @Chillz). Es gibt eine 'PrincipalExtractor'-Klasse, die aussieht wie etwas, das man verwenden kann (bloß benutzerdefinierte Instanz als Bean anzeigen), aber ich konnte das bisher nicht funktionieren. – demaniak

+0

@demaniak du bist willkommen! – Chillz

1

können Sie auch springframework.boot.json.JsonParser verwenden:

JsonParser parser = JsonParserFactory.getJsonParser(); 
Map<String, ?> tokenData = parser.parseMap(JwtHelper.decode(token).getClaims()); 

> tokenData.get("VALID_KEY"); 
0

Ich verwende diese:

private Claim getClaim(String claimKey) { 
    Authentication token = SecurityContextHolder.getContext().getAuthentication(); 
    try { 
     DecodedJWT jwt = JWT.decode(token.getCredentials().toString()); 
     return jwt.getClaim(claimKey); 
    } catch (JWTVerificationException ex) { 
     ex.printStackTrace(); 
     return null; 
    } 
} 
Verwandte Themen