spring-security Spring安全getAuthentication()返回空值

z9gpfhce  于 2022-11-11  发布在  Spring
关注(0)|答案(3)|浏览(414)

我尝试从我的Sping Boot + AngularJS应用程序返回当前登录的用户,但是SecurityContextHolder.getContext().getAuthentication()返回空值。
安全配置:

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
            .withUser("test").password("test").roles("USER", "ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .formLogin().and()
            .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).and()
            .authorizeRequests()
            .antMatchers("/index.html", "/login.html", "/").permitAll()
            .anyRequest().authenticated().and()
            .addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
            .csrf().csrfTokenRepository(csrfTokenRepository());
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/bower_components/**");
        web.ignoring().antMatchers("/js/**");
        web.ignoring().antMatchers("/css/**");
        web.ignoring().antMatchers("/api/user");
    }

    private static CsrfTokenRepository csrfTokenRepository() {
        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
        repository.setHeaderName("X-XSRF-TOKEN");
        return repository;
    }
}

控制器:

@RequestMapping(value="/user", method = RequestMethod.GET)
@ResponseBody
public User user() {
    User user = new User();
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    if (auth != null) {
        String name = auth.getName();
        user.setUsername(name);
    }
    return user;
}
eyh26e7m

eyh26e7m1#

假设您显示的控制器被Map到上下文/api/user,那么原因是因为您在安全配置中添加了web.ignoring().antMatchers("/api/user");这一行,这意味着对该控制器的所有请求都不受保护,因此也没有SecurityContext。
摘录自忽略方法的Javadoc:
匹配的HttpServletRequest上将无法使用Spring Security提供的Web安全性(包括SecurityContext)。

a1o7rhls

a1o7rhls2#

另一个原因可能是你已经启动了另一个线程到请求资源的原始线程,这也发生在parallelStream().foreach中。

lp0sw83n

lp0sw83n3#

如果您想从Spring Security配置中包含的组件类获取Authentication对象,可以使用以下命令。

Authentication auth = SecurityContextHolder.getContext().getAuthentication()

对于所有其他情况,如果您想要获取Authentication对象,可以使用HttpServletRequest来获取它,Spring上下文中的任何类都可以使用HttpServletRequest

Object sc = request.getSession().getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
if (!(sc instanceof SecurityContext)) {
    // Something strange is happening
}
Authentication authentication = ((SecurityContext) sc).getAuthentication();

相关问题