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
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM