添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
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?
  • can you put a debugger or log, I doubt you are even getting inside extractPrincipal method – silentsudo Feb 19, 2020 at 10:19

    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.