手动web身份验证后验证websocket会话

时间:2017-11-21 22:01:13

标签: spring authentication spring-security spring-websocket

我在SpringBoot上使用Spring Security和STOMP WebSocket。当我使用简单的登录表单时,使用此配置时,websocket上的Auth工作正常:

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
        .antMatchers("/webjars/**", "/resources/**").permitAll()
        .antMatchers("/register").anonymous()
        .anyRequest()
            .fullyAuthenticated()
            .and()
        .formLogin()
            .loginPage("/login")
            .successHandler(customLoginSuccessHandler)
        .failureUrl("/login?error")
            .permitAll()
            .and()
        .csrf().disable()
            .logout().logoutSuccessHandler(customLogoutSuccessHandler);
}


@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
@Override
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
    messages
            .nullDestMatcher().authenticated()
            .simpTypeMatchers(CONNECT).authenticated()
            .simpSubscribeDestMatchers(Channel.SYSTEM_ERROR.value()).permitAll()
            .simpDestMatchers("/app/publish*").hasRole("USER")
            .simpSubscribeDestMatchers("/user/**", "/topic/**", "/system/*").hasRole("USER")
            .anyMessage().denyAll();
}

但是当我想在RegisterController中注册新用户后手动验证客户端时:

@RequestMapping(value = "/register", method = RequestMethod.POST)
public String signup(@Valid @ModelAttribute SignupForm signupForm, Errors errors) {
    if (errors.hasErrors()) {
        return SIGNUP_VIEW_NAME;
    }
    User user = signupForm.createAccount();
    try {
        userService.persist(user);
    } catch (EntityExistsException ex) {
        errors.rejectValue("login", "user.exists");
        return SIGNUP_VIEW_NAME;
    }
    SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(user, null, Collections.singletonList(new SimpleGrantedAuthority("USER"))));

    return "redirect:/";
}

我对auth websocket有疑问。当我被重定向到websocket连接的页面时,我得到org.springframework.security.access.AccessDeniedException: Access is denied

1 个答案:

答案 0 :(得分:0)

因此。问题在于定义角色。在控制器中,当我定义new SimpleGrantedAuthority("USER")时,它应该是"ROLE_USER",因为Spring默认添加refix ROLLE_。当然,我们可以通过在WebSecurity配置中添加next来更改此默认行为

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/resources/**", "/favicon.ico");
        web.expressionHandler(new DefaultWebSecurityExpressionHandler() {
            @Override
            protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, FilterInvocation fi) {
                WebSecurityExpressionRoot root = (WebSecurityExpressionRoot) super.createSecurityExpressionRoot(authentication, fi);
                root.setDefaultRolePrefix(""); //remove the prefix ROLE_
                return root;
            }
        });
    }

。是的,假的错误但很常见。所以我会把它留在这里