Reputation: 469
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
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
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