SecurityContextHolder.getContext()上的身份验证为null;

时间:2020-02-18 20:21:02

标签: java spring-boot facebook-graph-api spring-security

我正在尝试在Spring Boot应用程序中使用Spring Security添加Facebook授权。目前,我的问题是从Principal中提取数据。

这是我的安全配置:

Thing x = (Thing) storage.getItem(0);

和主要提取器:

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();
    }
}

登录后,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; } } 仅包含名称和ID。调用Map<String, Object> map返回securityContext.getAuthentication()

此外,如果我创建类似于端点的内容并将null作为参数传递到那里,那么它将起作用。示例:

Principal

@RequestMapping("/user") public Principal user(Principal principal) { return principal; } 将包含所有必要的数据。

在这方面,有两个问题:

  1. 为什么安全上下文不包含身份验证?
  2. principal作为参数传递给方法的来源是什么?

这是调试内部的样子

enter image description here

2 个答案:

答案 0 :(得分:2)

这个答案可能有点晚了,但是我实际上是支持者之一,因为我有一个非常相似的问题。我发现,尽管SecurityContextHolder.getContext() never null,但请求完成后,其包含的身份验证将被清除。这意味着,如果您尝试在通过Spring Web安全性的过程中访问它它将存在。但是,一旦请求完成,就会记录以下内容

SecurityContextHolder现在已清除,因为请求处理已完成

,并且身份验证设置为null。任何在http请求之外通过SecurityContext直接访问它的尝试都将导致 null

答案 1 :(得分:-1)

身份验证身份验证= SecurityContextHolder.getContext()。getAuthentication(); authentication.getPrincipal();

使用嵌套调用获取身份验证对象,然后使用getPrincipal();将返回当前已登录的用户详细信息