Spring Security java配置混淆

时间:2017-01-07 15:07:36

标签: java spring security spring-security configuration

为什么不通过以下配置提示登录?当我尝试访问 / public / user 时,我收到错误403(访问被拒绝)。但是,如果我在WebServiceSecurityConfiguration.configure取消注释这些注释行,我会根据需要重定向到登录页面。为什么要正确配置登录时需要这些行,因为antMatcher首先匹配不同的路径。我想有一些冲突,错误配置AuthenticationEntryPoint,但我真的不知道这是怎么回事。我想要实现的是配置两个安全链,一个用于登录路径以获取JWT令牌,另一个用于Web服务以针对令牌进行身份验证。一切都与那些没有注释的线条完美配合,但我偶然注意到形式 - 登录在没有它们的情况下停止工作,并且我很困惑为什么会这样。

@Configuration
@Profile("javasecurity")
@Order(11)
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private TokenHandler tokenHandler;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user").password("password").authorities(new SimpleGrantedAuthority("ROLE_USER")).and()
            .withUser("admin").password("password").authorities(
                    new SimpleGrantedAuthority("ROLE_USER"),
                    new SimpleGrantedAuthority("ROLE_ADMIN")).and()
            .withUser("guest").password("guest").authorities(new SimpleGrantedAuthority("ROLE_GUEST"));
    }

    @Override
    @Bean
    public UserDetailsService userDetailsServiceBean() throws Exception {
        return super.userDetailsServiceBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/public/**")
                .permitAll()
            .and()
                .formLogin()
                .successHandler(authenticationSuccessHandler())
                .and()
                .logout();
    }

    @Bean
    public AuthenticationSuccessHandler authenticationSuccessHandler() {
        return new AuthenticationSuccessHandler() {

            public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                    Authentication authentication) throws IOException, ServletException {
                tokenHandler.setToken(response, authentication.getName());
                response.getWriter().println("User authenticated and cookie sent");
                response.flushBuffer();
            }
        };
    }

    @Configuration
    @Profile("javasecurity")
    @Order(10)
    public static class WebServiceSecurityConfiguration extends WebSecurityConfigurerAdapter {

        @Autowired
        private TestAuthenticationFilter testAuthenticationFilter;

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                .antMatchers("/secured/**")
                    .authenticated();
//              .and()
//              .antMatcher("/secured/**")
//                  .securityContext().securityContextRepository(new NullSecurityContextRepository())
//                  .and()
//                  .addFilterAt(testAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
        }
    }

-

@Component("TestAuthenticationFilter")
public class TestAuthenticationFilter extends GenericFilterBean {

    @Autowired
    private TokenHandler tokenHandler;

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("TestAuthenticationFilter doFitler");
        attemptAuthentication((HttpServletRequest) request);
        chain.doFilter(request, response);
        clearAuthentication();
        System.out.println("doFitler end");
    }

    public void attemptAuthentication(HttpServletRequest request) {
        try {
            UserDetails user = tokenHandler.loadUserFromToken(request);
            UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, user.getPassword());
            SecurityContextHolder.getContext().setAuthentication(auth);
        } catch (Exception e) {
            // Do nothing
        }
    }

    public void clearAuthentication() {
        SecurityContextHolder.getContext().setAuthentication(null);
    }

    @Configuration
    public static class DisableFilterRegistration {

        @Autowired
        private TestAuthenticationFilter filter;

        @Bean
        public FilterRegistrationBean disablerBean() {
            FilterRegistrationBean bean = new FilterRegistrationBean(filter);
            bean.setEnabled(false);
            return bean;
        }
    }

}

-

@Component("TokenHandler")
public class TokenHandler {

    @Autowired(required = false)
    private UserDetailsService userDetailsService;

    public void setToken(HttpServletResponse response, String username) {
        response.addCookie(new Cookie("user", username));
    }

    public UserDetails loadUserFromToken(HttpServletRequest request) throws BadCredentialsException {

        Cookie[] cookies = request.getCookies();
        Cookie token = null;
        for (Cookie c : cookies) {
            if (c.getName().equals("user")) {
                token = c;
                break;
            }
        }

        if (token == null)
            return null;

        else 
            return userDetailsService.loadUserByUsername(token.getValue());
    }
}

-

@RestController
@RequestMapping("/public")
public class PublicController {

    @GetMapping("/norole")
    public String noRole() {
        return "no role";
    }

    @GetMapping("/user")
    @PreAuthorize("hasRole('ROLE_USER')")
    public String roleUser() {
        return "role_user";
    }
}

-

@RestController
@RequestMapping("/secured")
public class SecuredController {

    @GetMapping("/user")
    @PreAuthorize("hasRole('ROLE_USER')")
    public String roleUser() {
        return "role_user";
    }

    @GetMapping("/admin")
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    public String roleAdmin() {
        return "role_admin";
    }

    @GetMapping("/norole")
    public String noRole() {
        return "no role";
    }
}

1 个答案:

答案 0 :(得分:-1)

在声明添加

后,登录功能再次起作用
http.antMatcher("/secured/**")

作为WebServiceSecurityConfiguration.configure中的第一个电话。这是否意味着如果没有它,配置会否定表单登录,在此特定配置之后配置?此外,似乎antMatcher的位置可以是任意的,是这种情况吗?有人可以解释那里发生的事情吗?