Authentication is null on the SecurityContextHolder.getContext();

若如初见. 提交于 2021-01-27 07:20:42

问题


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 {
        http
            .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:

  1. Why security context does not contain authentication?
  2. Where does the principal come from if it is passed as a parameter to a method?

This is what the debug looks like inside


回答1:


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.




回答2:


Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); authentication.getPrincipal();

use nested call for getting authentication object and then getPrincipal(); will return current loggedin user details



来源:https://stackoverflow.com/questions/60288854/authentication-is-null-on-the-securitycontextholder-getcontext

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!