Taras
Taras

Reputation: 469

How to get all attributes from java.security.Principal?

I learning Spring security and write simple web app with Spring Security 5 and OAuth2 Login. I want to get information from Principal (email, username e.t.c) but I can't find any method for it. Write some JSON-parser not a best idea because I pretty sure there is some method for obtaining user account details.

Config

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and().oauth2Login();
    }
}

Controller

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.security.Principal;

@Controller
public class HomeController {

    @GetMapping({"", "/"})
    @ResponseBody
    public Principal getHome(Principal principal) {
        return principal;
    }

}

Application.yml

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: xyz1
            client-secret: secret1
          facebook:
            client-id: xyz2
            client-secret: secret2
          github:
            client-id: xyz3
            client-secret: secret3

Upvotes: 2

Views: 4448

Answers (2)

hello_earth
hello_earth

Reputation: 1562

Through trial and error, and with Spring Boot 2.3.2 I found out that in THAT particular scenario (OAuth2 with Spring Boot) you have to cast the Authentication object you get on onAuthenticationSuccess method (and yes, that is the difference of my scenario, because I observed this object in my authentication success handler - but would this scenario be much different?) to OAuth2AuthenticationToken. If you actually pause execution and add Authentication object to the Watches, you will see that it's really that type. Now this object's getPrincipal() returns properly cast OAuth2User object, which has a method getAttributes(). I really wish it was easier to figure that out.

In fact, in MY scenario, OAuth2User object could be passed to my Controller method directly (and I am not sure if that annotation @AuthenticationPrincipal is necessary or proper..):

@Controller
@RequestMapping("/authorized")
public class AuthorizedController {

    @RequestMapping("/default")
    public String handle(@AuthenticationPrincipal OAuth2User principal,
            Model m) {
         // ...
    }
}

Upvotes: 1

Karan
Karan

Reputation: 1

Create a new object representing the subset of data you want to be returned from source, i.e, source of those details have multiple values therefore Use some List or set or map to store that data and represent it, As You mentioned you are working with OAuth2 :

 @RequestMapping("/user")
    public Authentication user(OAuth2Authentication authentication) {
        LinkedHashMap<String, Object> details = (LinkedHashMap<String, Object>) authentication.getUserAuthentication().getDetails();
        return details.get("email");
    }

Upvotes: 0

Related Questions