【问题标题】:Spring Security java configuration confusionSpring Security java配置混乱
【发布时间】:2017-05-22 05:29:44
【问题描述】:

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

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

【问题讨论】:

    标签: java spring security spring-security configuration


    【解决方案1】:

    Login-from 在声明添加后再次起作用

    http.antMatcher("/secured/**")
    

    作为WebServiceSecurityConfiguration.configure 中的第一个调用。这是否意味着没有它,配置会否定表单登录,它是在此特定配置之后配置的?另外,antMatcher 的位置似乎可以任意,是这样吗?有人可以解释那里实际发生了什么吗?

    【讨论】:

      猜你喜欢
      • 2014-05-27
      • 2017-07-17
      • 2018-07-24
      • 2017-01-21
      • 1970-01-01
      • 1970-01-01
      • 2016-10-24
      • 2014-12-30
      • 2016-12-17
      相关资源
      最近更新 更多