簡體   English   中英

Spring Security Java配置混亂

[英]Spring Security java configuration confusion

為什么以下配置沒有提示登錄? 當我嘗試訪問/ public / user時 ,出現錯誤403(訪問被拒絕)。 但是,如果我取消注釋WebServiceSecurityConfiguration.configure注釋行,則會根據需要將我重定向到登錄頁面。 為什么antMatcher首先匹配不同的路徑,所以正確配置from-log需要這些行。 我猜這里有一些沖突,錯誤地配置了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";
    }
}

聲明添加后,登錄源再次起作用

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

作為WebServiceSecurityConfiguration.configure的第一個調用。 這是否意味着沒有它,配置將否定此特定配置之后配置的表單登錄? 另外,似乎antMatcher的位置可以是任意的,是這種情況嗎? 有人可以解釋一下那里到底發生了什么嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM