SecurityContextHolder.getContext()上的身份验证为null; [英] Authentication is null on the SecurityContextHolder.getContext();

查看:139
本文介绍了SecurityContextHolder.getContext()上的身份验证为null;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to add Facebook authorization using Spring Security in Spring Boot app. Currently, my problem is extracting data from Principal.

这是我的安全配置:

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

登录后, Map< String,Object>地图仅包含名称和ID.调用 securityContext.getAuthentication()返回 null .

After login, the Map<String, Object> map contains only the name and id. Call to securityContext.getAuthentication() returns null.

此外,如果我创建与端点类似的东西并在其中传递 Principal 作为参数,那么它将起作用.示例:

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. 为什么安全上下文不包含身份验证?
  2. 主要作为参数传递给方法的地方从哪里来?
  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

推荐答案

尽管 SecurityContextHolder.getContext()永远为 null完全的.这意味着,如果您尝试在通过Spring Web安全性的过程中访问它,则它将在那里.但是,一旦请求完成,就会记录以下内容

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现在已清除,因为请求处理已完成

SecurityContextHolder now cleared, as request processing completed

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

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.

这篇关于SecurityContextHolder.getContext()上的身份验证为null;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆