• Spring Security permitAll开放页面权限 解除token验证的问题


    在SpringBoot中的SpringSecurity的配置类中,http.permitAll()与web.ignoring()的区别?

    虽然这两个都是继承WebSecurityConfigurerAdapter后重写的方法,但是http.permitAll不会绕开springsecurity的过滤器验证,相当于只是允许该路径通过过滤器,而web.ignoring是直接绕开spring security的所有filter,直接跳过验证。

    permitAll配置实例

    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests()
                    .antMatchers("/css/**", "/js/**","/fonts/**").permitAll()
                    .anyRequest().authenticated();
        }
    }

    web ignore配置实例

    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().antMatchers("/css/**");
            web.ignoring().antMatchers("/js/**");
            web.ignoring().antMatchers("/fonts/**");
        }
    }

    二者区别

    顾名思义,WebSecurity主要是配置跟web资源相关的,比如css、js、images等等,但是这个还不是本质的区别,关键的区别如下:

    • ignore是完全绕过了spring security的所有filter,相当于不走spring security,所以ignore只适合配置静态资源的过滤,不适合api的过滤,过滤api就调用不了api了
    • permitall没有绕过spring security,其中包含了登录的以及匿名的。

    关于springboot security自定义拦截器 使用 permitAll() 之后仍然会走过滤器的解决方法

    前言
    依然是我负责的认证模块,出现了业务上的问题,想要使某些接口不走过滤链,但是再security上配置

    .antMatchers("/**").permitAll()


    之后,前端访问进来,依然会走我的 token 过滤器

    public class JWTAuthorizationFilter extends BasicAuthenticationFilter {
    ...
    }


    解决方法一
    尝试过,在获取到token为空的时候,判断一下请求地址是不是某些不需要token的接口,例如 短信验证码接口

    // 如果请求头中没有token信息则直接放行了

    if (null == authorization || ("").equals(authorization)
    || ("null").equals(authorization)|| userType == null) {
    if(request.getServletPath().equals("/login/verificationCode")){
    chain.doFilter(request, response);
    return;
    }
    this.responseMsg(RestResult.failure(ErrorCode.SYS_ERROR),response);
    return;
    }


    这样子做看起来是可以解决问题,但是也引起了其他问题,例如后期的扩展太麻烦,我需要不断的往if里面塞东西,就觉得很傻*,于是有了第二种想法。

    解决方法二
    配置某些接口直接不进入过滤链,在security的config中配置

    @Override
    public void configure(WebSecurity web) {
    //解决静态资源被拦截的问题
    web.ignoring().antMatchers("/login/verificationCode","/images/**");
    }


    如此,比上一个方法好了不止一点点。

    Spring Security permitAll开放页面权限 解除token验证的问题

    使用Spring Security做权限认证,通常有些页面需要开放某些页面不需要权限验证,比喻登录页面,注册页面等,也就是无论你什么权限(包括访客)都能访问到页面,要让某个页面设置所有权限都能访问也很简单

    1.Spring Security设置开放某个页面访问权限

    @Configuration
    public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            //开放接口
            http.authorizeRequests()
                    .antMatchers("/fileCallback").permitAll()
                    .anyRequest()
                    .authenticated();
        }
    
    }

    2.已经开放权限的页面token验证问题

    按照上面设置了某个页面可以开放访问,但是问题是:如果访问这个页面还是带了token,或者header 中 携带 Authorization Bearer xxxx,就会验证这个token,如果验证失败,不好意思虽然开放了访问权限,但是token验证失败,还是不能访问,所以设置了开放权限相当于没有设置,那么怎么解决?

    3.解决方法

    其实这也怪不得spring security,你都携带验证信息了,表示你需要框架验证你的权限

    那么我们只能去掉这个验证信息

    spring-security的认证为一系列过滤器链。我们只需定义一个比OAuth2AuthenticationProcessingFilter更早的过滤器拦截指定请求,去除header中的Authorization Bearer xxxx即可

    添加PermitAuthenticationFilter类
    添加PermitAuthenticationFilter类拦截指定请求,清空header中的Authorization Bearer xxxx

    @Component("permitAuthenticationFilter")
    @Slf4j
    public class PermitAuthenticationFilter extends OncePerRequestFilter {
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    
            log.info("当前访问的地址:{}", request.getRequestURI());
            if ("/permitAll".equals(request.getRequestURI())) {
    
                request = new HttpServletRequestWrapper(request) {
                    private Set<String> headerNameSet;
    
                    @Override
                    public Enumeration<String> getHeaderNames() {
                        if (headerNameSet == null) {
                            // first time this method is called, cache the wrapped request's header names:
                            headerNameSet = new HashSet<>();
                            Enumeration<String> wrappedHeaderNames = super.getHeaderNames();
                            while (wrappedHeaderNames.hasMoreElements()) {
                                String headerName = wrappedHeaderNames.nextElement();
                                if (!"Authorization".equalsIgnoreCase(headerName)) {
                                    headerNameSet.add(headerName);
                                }
                            }
                        }
                        return Collections.enumeration(headerNameSet);
                    }
    
                    @Override
                    public Enumeration<String> getHeaders(String name) {
                        if ("Authorization".equalsIgnoreCase(name)) {
                            return Collections.<String>emptyEnumeration();
                        }
                        return super.getHeaders(name);
                    }
    
                    @Override
                    public String getHeader(String name) {
                        if ("Authorization".equalsIgnoreCase(name)) {
                            return null;
                        }
                        return super.getHeader(name);
                    }
                };
    
            }
            filterChain.doFilter(request, response);
    
        }
    }

    添加PermitAllSecurityConfig配置
    添加PermitAllSecurityConfig配置用于配置PermitAuthenticationFilter

    @Component("permitAllSecurityConfig")
    public class PermitAllSecurityConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain,HttpSecurity> {
    
        @Autowired
        private Filter permitAuthenticationFilter;
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.addFilterBefore(permitAuthenticationFilter, OAuth2AuthenticationProcessingFilter.class);
        }
    }

    修改MerryyouResourceServerConfig,增加对制定路径的授权

    @Override
        public void configure(HttpSecurity http) throws Exception {
    
            // @formatter:off
            http.formLogin()
                    .successHandler(appLoginInSuccessHandler)//登录成功处理器
                    .and()
                    .apply(permitAllSecurityConfig)
                    .and()
                    .authorizeRequests()
                    .antMatchers("/user").hasRole("USER")
                    .antMatchers("/forbidden").hasRole("ADMIN")
                    .antMatchers("/permitAll").permitAll()
                    .anyRequest().authenticated().and()
                    .csrf().disable();
    
            // @formatter:ON
        }
  • 相关阅读:
    Shrink / VACUUM Database Sample Code C#
    (转)Export .NET MSChart to Excel/PDF Using Report Viewer 2010
    VS2010中使用《WeifenLuo.WinFormsUI.Docking.dll》,类型 Universe 无法解析程序集
    Binding to a ComboBox using a DataTable and Linq
    elementui 点击Switch开关弹出对话框确认后再改变switch开关状态
    c# 获取ip和mac
    mysql 允许ip访问
    jdk下载
    vue video 动态地址 不能自动播放
    c# 取右侧固定N个字符,不足用0填充
  • 原文地址:https://www.cnblogs.com/panchanggui/p/14975963.html
Copyright © 2020-2023  润新知