6

I'm following https://spring.io/guides/tutorials/spring-boot-oauth2/ and everything works so far. I actually even managed to hook up also Google Oauth as a second Auth provider. Now I'm trying to read out the infos from the token info endpoint in my backend to sync it with my local DB and adjust the output. But I'm somehow struggling to retrieve the information.

The tutorial creates at some point this endpoint:

@RequestMapping("/user")
public Principal user(Principal principal) {
    return principal;
}

when called, this is displaying (after successful login) correctly for me

{
    "authorities": [...],
    "details": {...},
    "authenticated": true,
    "userAuthentication": {
        "authorities": [...],
        "details": {
            "email": "foo@bar.com",
            "name": "Foo Bar",
            "id": "12345674890000"
        },
        "authenticated": true,
        "principal": "12345674890000",
        "credentials": "N/A",
        "name": "12345674890000"
    },
    "oauth2Request": {},
    "clientOnly": false,
    "credentials": "",
    "principal": "12345674890000",
    "name": "12345674890000"
}

so somehow spring boot security is picking up the right information. Now I'm trying to build an Interceptor (basic functionality is working, the interceptor is called on every request) to handle this information. I'm struggling to get e.g. the email address now. I found this answer, but its referring to an old version of spring boot, and just links to a new Interface, but I'm wondering if I need that (It also looks very complicated for the simple usecase I think I have). What would be the best approach to get the information from this /user endpoint in my spring app without actually calling my own endpoint to retrieve it?

the only thing i managed to pick up was via the SecurityContextHolder the principle id and other stuff which did not help me. I did not actually retrieve e.g. the email address.

Alex Bravo
  • 1,601
  • 2
  • 24
  • 40
Wolli
  • 748
  • 1
  • 8
  • 12

2 Answers2

7

Try to use SecurityContext:

SecurityContextHolder.getContext().getAuthentication().getPrincipal();

It will contains the real user object that is currently loggedin

Afridi
  • 6,753
  • 2
  • 18
  • 27
  • @Wolli have you tried the above? What do you get when you do this (in a Controller): Principal principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); Map details = ((OAuth2Authentication) principal).getUserAuthentication().getDetails(); logger.info("details = " + details); // id, email, name, link etc. – rich p May 30 '17 at 13:53
  • sry for the late answer, but both of those suggestions don't work because i get just a string object back from the `getPrincipal()` method ... any clue why that is? a lot of suggestions in the www say there should be a real user object, but always just have a string. i think there might be something else missing with my setup ... – Wolli Oct 01 '17 at 16:34
  • if i try to cast this String Principle to `UserDetails` Class (as mostly suggested), i get a CastException ... – Wolli Oct 01 '17 at 16:44
0

This may help

I am assuming you know the User and Role mapping. My User class extends UserDetails so I need to override some methods which mentioned below

Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();

Then call to SecurityContextHolder.getContext().getAuthentication() helps to return User object as below

User user = null;
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null
   && authentication.getPrincipal() != null
   && authentication.getPrincipal() instanceof User) {
        user = (User) authentication.getPrincipal();
    }

Now in user object you will get all info from User table if mappings are perfect. Like username, email, firstname, lastname etc.

Abhishek
  • 3,348
  • 3
  • 15
  • 34