REST - 创建会话

时间:2017-08-16 10:05:18

标签: spring spring-security

我编写使用Spring Security的应用程序。下面我写了我的TokenFilter和WebSecurityConfig。 我的问题是SecurityContext包含登录用户的时间有多长? 下一个问题:我的安全配置会话是无状态还是没有? SecurityContext是否替换为Session?

我的申请是否符合无国籍原则?

public class TokenFilter extends OncePerRequestFilter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private TokenHelper tokenHelper;

    private String tokenHeader = "Auth";

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest,
                                    HttpServletResponse httpServletResponse,
                                    FilterChain filterChain) throws ServletException, IOException {
        final String authToken = httpServletRequest.getHeader(this.tokenHeader);

        final String username = tokenHelper.getUsernameFromToken(authToken);

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            final UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);

            if (tokenHelper.validateToken(authToken, userDetails)) {
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                        userDetails,
                        null,
                        userDetails.getAuthorities()
                );
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }

        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
}

安全配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UnauthorizedHandler unauthorizedHandler;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder
                .userDetailsService(this.userDetailsService)
                .passwordEncoder(this.passwordEncoder);
    }

    @Autowired
    public BCryptPasswordEncoder passwordEncoder;

    @Autowired
    public TokenFilter tokenFilter;

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .csrf().disable()
                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler)
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.POST, "/login").permitAll()
                .anyRequest().authenticated();

        httpSecurity.addFilterBefore(
                tokenFilter,
                UsernamePasswordAuthenticationFilter.class
        );

        httpSecurity.headers().cacheControl();
    }
}

1 个答案:

答案 0 :(得分:1)

2666 9953 2666 9953 1171 2666 1252 2666 1171 1171 9953 1171 2666 1171 仅用于访问SecurityContext个实例。

您的请求之间可能存储

Authentication。这个逻辑(存储然后恢复新请求)在SecurityContext中实现,然后将此存储逻辑委托给SecurityContextPersistenceFilter

当您使用SecurityContextRepository时,会使用SessionCreationPolicy.STATELESS(它是NullSecurityContextRepository的实现);它实际上并不存储SecurityContextRepository任何地方,它总是'恢复'一个新的(空)SecurityContext

SecurityContext还禁止Spring Security在任何构成其机器的bean中创建http会话。

因此,当您使用SessionCreationPolicy.STATELESS时,永远不会创建会话,并且肯定不会用于存储SessionCreationPolicy.STATELESS。您的每个请求都有一个全新的安全上下文(其中没有SecurityContext),因此您的每个请求都将执行完整的身份验证。