Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I am trying to add Facebook authorization using Spring Security in Spring Boot app. Currently, my problem is extracting data from Principal.
Here is my security config:
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure (HttpSecurity http) throws Exception {
.csrf().disable()
.antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/login**").permitAll()
.anyRequest().authenticated()
.and()
.logout()
.deleteCookies("JSESSIONID")
.clearAuthentication(true)
.logoutSuccessUrl("/").permitAll();
@Bean
public PrincipalExtractor facebookPrincipalExtractor(){
return new FacebookPrincipalExtractor();
and principal extractor:
public class FacebookPrincipalExtractor implements PrincipalExtractor {
@Autowired
UserService userService;
@Override
public Object extractPrincipal(Map<String, Object> map) {
String name = (String) map.get("name");
String id = (String) map.get("id");
User user = userService.findOne(id);
if (user == null) {
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication();
String token = ((OAuth2AuthenticationDetails) authentication.getDetails()).getTokenValue();
user = new User();
FacebookClient facebookClient = new DefaultFacebookClient(token, Version.VERSION_2_10);
JSONObject object = facebookClient.fetchObject("me", JSONObject.class);
// userService.createUser(object);
return user;
After login, the Map<String, Object> map
contains only the name and id. Call to securityContext.getAuthentication()
returns null
.
Moreover, if I create something similar to the endpoint and pass the Principal
there as a parameter, then this will work. Example:
@RequestMapping("/user")
public Principal user(Principal principal) {
return principal;
The principal
will contain all the necessary data.
In this regard, 2 questions:
Why security context does not contain authentication?
Where does the principal
come from if it is passed as a parameter to a method?
–
Although SecurityContextHolder.getContext()
is never null the authentication it contains is cleared once a request is completed. What this means is that if you try to access it during a process which goes through the spring web security it will be there. But as soon as the request finishes the following gets logged
SecurityContextHolder now cleared, as request processing completed
and the authentication is set to null. Any attempts to access it directly through the SecurityContext outside of an http request will result in a null.
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
authentication.getPrincipal();
use nested call for getting authentication object and then getPrincipal(); will return current loggedin user details
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.