【问题标题】:PermitAll not working in Spring SecurityPermitAll 在 Spring Security 中不起作用
【发布时间】:2017-08-20 09:41:20
【问题描述】:

我有两个规则,第一个来自 oauth/** 的每个 url 应该没有安全性,其他 url 必须安全。但现在所有 url 都是安全的,包括来自 oauth/** 的 url。 这是我的安全配置规则。

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        // JWT dont need CSRF
        httpSecurity.csrf().disable().exceptionHandling().and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests()
                .antMatchers("oauth/**").permitAll().and()
                .addFilterBefore(new JwtAuthenticationTokenFilter(), BasicAuthenticationFilter.class);

        // disable page caching
        httpSecurity.headers().cacheControl();
    }

}

当我请求进入我的 JwtAuthenticationTokenFilter 的 url http://localhost:8080/oauth/fb 时,我希望这个 url 不要进入这个过滤器。

【问题讨论】:

    标签: spring spring-security spring-oauth2


    【解决方案1】:

    您可以使用 WebSecurity 参数覆盖配置方法。

    @Override
    public void configure(final WebSecurity web) throws Exception
    {
        web.ignoring().antMatchers("oauth/**");
    }
    

    在提供文档中建议的静态内容(例如 css/* js/*)时应该使用此方法,但是我找不到另一种方法来允许在 Spring Security 中使用自定义过滤器进行 URL 映射。

    【讨论】:

    • 这很可悲。它应该改变。
    【解决方案2】:
    <security:http pattern="/support/**" security="none"/>
    

    您可能需要编写与上述 XML 配置等效的 Java。基本上,您正在为上述模式设置一个没有安全性的新过滤器链。

    【讨论】:

    • 我用的是spring boot,我不使用XML来配置。
    【解决方案3】:

    我遇到了类似的问题。我的安全配置:

    // ... imports
    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        private final UserDetailsService userDetailsService;
        private final PasswordEncoder passwordEncoder;
        private final JwtFilter jwtFilter;
    
        @Autowired
        public SecurityConfig(@Qualifier("userDetailsServiceImpl") UserDetailsService userDetailsService,
                              PasswordEncoder passwordEncoder,
                              JwtProvider jwtProvider) {
            this.userDetailsService = userDetailsService;
            this.passwordEncoder = passwordEncoder;
            this.jwtFilter = new JwtFilter(jwtProvider);
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .csrf().disable()
                    .httpBasic().disable()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and()
                    .authorizeRequests()
                    .antMatchers(HttpMethod.POST, "/auth/**").permitAll()
                    .and()
                    .authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                    .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
        }
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(daoAuthenticationProvider());
        }
    
        protected DaoAuthenticationProvider daoAuthenticationProvider() {
            DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
            provider.setUserDetailsService(userDetailsService);
            provider.setPasswordEncoder(passwordEncoder);
            return provider;
        }
    }
    

    还有我的安全过滤器:

    // ... imports
    public class JwtFilter extends GenericFilterBean {
        public static final String AUTHORIZATION_HEADER = "Authorization";
        public static final String TOKEN_PREFIX = "Bearer ";
        public static final int TOKEN_START_POSITION = 7;
    
        private final JwtProvider jwtProvider;
    
        @Autowired
        public JwtFilter(JwtProvider jwtProvider) {
            this.jwtProvider = jwtProvider;
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
                throws IOException, ServletException {
            String token = getTokenFromRequest((HttpServletRequest) servletRequest);
            if (token != null && jwtProvider.validateToken(token)) {
                Map<String, Object> properties = jwtProvider.getUserPropertiesFromToken(token);
                UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
                        properties.get("login"),
                        null,
                        (Set<GrantedAuthority>) properties.get("authirities"));
                SecurityContextHolder.getContext().setAuthentication(auth);
            }
            filterChain.doFilter(servletRequest, servletResponse);
        }
    
        private String getTokenFromRequest(HttpServletRequest request) {
            String bearer = request.getHeader(AUTHORIZATION_HEADER);
            if (bearer != null && bearer.startsWith(TOKEN_PREFIX)) {
                return bearer.substring(TOKEN_START_POSITION);
            }
            return null;
        }
    }
    

    我的代码对我不起作用的原因是我在过滤器中跳过了 filterChain.doFilter(servletRequest, servletResponse); 行,即我没有将请求和响应传递给链中的下一个实体。

    【讨论】:

      猜你喜欢
      • 2016-02-16
      • 2018-01-31
      • 2019-09-27
      • 2020-10-02
      • 2018-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-14
      相关资源
      最近更新 更多