In this tutorial, you will learn how to use @AuthenticationPrincipal annotation to get the Jwt object containing the details of a provided in HTTP Request access token.
For video lessons on how to secure your Spring Boot application with OAuth 2.0. and Spring Security 5, please checkout my complete video course OAuth 2.0. in Spring Boot applications.
When we send a request containing an access token in the Authorization header, behind the scenes, Spring Framework will do a lot of work and if all is good, the result of that work will be an Authentication object from which we can get the details of Jwt token and the currently authenticated Principal user.
To get the Jwt token claims in a single Jwt Java object, we can use a special annotation called @AuthenticationPrincipal. The @AuthenticationPrincipal annotation will bind the details of the currently authenticated principal into a special Jwt object.
@GetMapping("/tokenClaims") public Map<String, Object> getPrincipalUser(@AuthenticationPrincipal Jwt jwt) { return Collections.singletonMap("principal", jwt); }
Now when we access to Jwt object, we can get an entire JWT access token value by calling the getTokenValue() method.
String token = jwt.getTokenValue();
The Jwt token object provides us with many useful methods to get all sorts of information about the Jwt token. We can get any Jwt claim by calling a specific getter method on the Jwt object itself, or we run the above method and get them all in a single response containing the following JSON document.
{ "principal": { "tokenValue": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJTeG5BaTBQVFlka284d2xDdjRCLUlLaEJGeGZHWm5WSHhrUk1WckYxaE5FIn0.eyJleHAiOjE1OTYxMTMwMTAsImlhdCI6MTU5NjExMjcxMCwiYXV0aF90aW1lIjoxNTk2MTEyNjk1LCJqdGkiOiI0YzJlNjIwNy05NjE0LTQ3ODQtOTZhNS05MDFiZjExNDc0ODIiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvYXBwc2RldmVsb3BlcmJsb2ciLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNWYzZmI0ODAtZjg2Yy00NTE0LThkMjMtY2E4OGQ2NmM2MjUzIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoicGhvdG8tYXBwLWNvZGUtZmxvdy1jbGllbnQiLCJzZXNzaW9uX3N0YXRlIjoiMzY4MTM4ZDAtMzVmMS00ODI1LWJhNDYtZjNiMDA4OTkzMzhjIiwiYWNyIjoiMSIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwibmFtZSI6IlNlcmdleSBLYXJnb3BvbG92IiwicHJlZmVycmVkX3VzZXJuYW1lIjoic2VyZ2V5LmthcmdvcG9sb3YiLCJnaXZlbl9uYW1lIjoiU2VyZ2V5IiwiZmFtaWx5X25hbWUiOiJLYXJnb3BvbG92IiwiZW1haWwiOiJzZXJnZXkua2FyZ29wb2xvdkBnbWFpbC5jb20ifQ.MNm42UT56TMo_AVcpII9SkQbdTK1_diDhX9iRVXr3AjNCPSYlmG_ysmgfkr-p3waDWomTnM8ZYOwsllZLdctHuKyZZMKP2MQmI_LwLztuHQLZw7uYC4IJK4ZhXBtKSiWiz1Zc4EjipIwU0SHidvIbe42A46_pS7GEEMALDZZNYoVzHX5MBkfJsRR9O2s0L36y6VVypuCU0UMhboNcXCwlOWh1U4v_HaE-pL6_9v48G6vruohaJxunGaIMuMnA6IxVW4C31-mSidLdu1il4grd8H5XFK6A70ZZxCnNl1PO5nalH8WDIviK6t6dkrir-GP-ptwM0DtSXqJU1CW77g94g", "issuedAt": "2020-07-30T12:38:30Z", "expiresAt": "2020-07-30T12:43:30Z", "headers": { "kid": "SxnAi0PTYdko8wlCv4B-IKhBFxfGZnVHxkRMVrF1hNE", "typ": "JWT", "alg": "RS256" }, "claims": { "sub": "5f3fb480-f86c-4514-8d23-ca88d66c6253", "resource_access": { "account": { "roles": [ "manage-account", "manage-account-links", "view-profile" ] } }, "email_verified": false, "iss": "http://localhost:8080/auth/realms/appsdeveloperblog", "typ": "Bearer", "preferred_username": "sergey.kargopolov", "given_name": "Sergey", "aud": [ "account" ], "acr": "1", "realm_access": { "roles": [ "offline_access", "uma_authorization" ] }, "azp": "photo-app-code-flow-client", "auth_time": 1596112695, "scope": "openid email profile", "name": "Sergey Kargopolov", "exp": "2020-07-30T12:43:30Z", "session_state": "368138d0-35f1-4825-ba46-f3b00899338c", "iat": "2020-07-30T12:38:30Z", "family_name": "Kargopolov", "jti": "4c2e6207-9614-4784-96a5-901bf1147482", "email": "[email protected]" }, "id": "4c2e6207-9614-4784-96a5-901bf1147482", "subject": "5f3fb480-f86c-4514-8d23-ca88d66c6253", "notBefore": null, "issuer": "http://localhost:8080/auth/realms/appsdeveloperblog", "audience": [ "account" ] } }
As you can see, we can get any claim that the Jwt object contains.