2015-10-26 34 views
-1
public class AuthenticationFilter extends GenericFilterBean { 

SecureService secureService; 

public AuthenticationFilter(SecureService secureService) { 
    this.secureService=secureService; 
} 

@Override 
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 
    HttpServletRequest httpServletRequest=(HttpServletRequest)servletRequest; 
    Authentication authentication=secureService.getAuthentication(httpServletRequest); 
    if(authentication!=null) { 
     SecurityContextHolder.getContext().setAuthentication(authentication); 
     filterChain.doFilter(servletRequest, servletResponse); 
     SecurityContextHolder.getContext().setAuthentication(null); 
    } 
} 

} 


@Configuration 
@EnableWebSecurity 
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter { 

@Autowired 
SecureService secureService; 
@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http.addFilterBefore(new AuthenticationFilter(secureService), BasicAuthenticationFilter.class) 
      .authorizeRequests() 
      .antMatchers(HttpMethod.GET, "/businesses/**").permitAll() 
      .antMatchers(HttpMethod.GET, "https://stackoverflow.com/users/login").permitAll() 
      .antMatchers(HttpMethod.POST, "https://stackoverflow.com/users/").permitAll() 
      .antMatchers(HttpMethod.GET, "/reviews/").permitAll() 
      .antMatchers(HttpMethod.GET, "/reviews/search").permitAll() 
      .antMatchers(HttpMethod.GET, "/reviews/**").permitAll() 
      .antMatchers("/").permitAll().and() 
      .authorizeRequests().anyRequest().authenticated(); 
} 
    @Bean 
    public AuthenticationManager authenticationManager() throws Exception { 
     return super.authenticationManagerBean(); 
    } 
} 

這個配置有什麼問題?我跟着這個link寫URL認證。但是我的應用一直阻止所有請求,忽略代碼中指定的所有匹配器。我搜索了一下,有人說規則的順序很重要。但即使我改變了訂單,AuthenticationFilter一直被調用,並保持阻止所有請求這個彈簧安全配置爲什麼會阻塞所有路徑?

+1

那是你告訴它做什麼,最後一行覆蓋之前的... –

+0

@ M.Deinum這是不正確的。過濾器被一個接一個讀取。所以如果這些過濾器之前沒有匹配任何其他將需要驗證。 –

+0

只是要確定..你用@Configuration註釋了你的配置? –

回答

0

問題是您中斷了過濾器鏈。按照以下步驟操作,它應該可以工作。

@Override 
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 
    HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; 

     Authentication authentication = secureService.getAuthentication(httpServletRequest); 
     if (authentication != null) { 
      SecurityContextHolder.getContext().setAuthentication(authentication); 

     } 

     filterChain.doFilter(servletRequest, servletResponse); 
     SecurityContextHolder.getContext().setAuthentication(null); 
    } 

另一件事是,你扔一個UserNotFoundException你SecureService內如果HttpServlerRequest不包含身份驗證。 在這種情況下,你認爲在AuthenticationFilter中看起來爲空?

public Authentication getAuthentication(HttpServletRequest httpServletRequest) { 
    final String token=httpServletRequest.getHeader(Headers.AUTH_HEADER_NAME); 
    if(token!=null){ 
     final User user=parseToken(token); 
     if(user!=null){ 
      return new UserAuthentication(user); 
     } 
    } 
    return null; 
} 

,如果你想保持UserNotFoundException那麼只有改變doFilterMethod以下:所以在SecureService如果沒有認證存在返回null

@Override 
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 
    HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; 

    try { 
     Authentication authentication = secureService.getAuthentication(httpServletRequest); 
     if (authentication != null) { 
      SecurityContextHolder.getContext().setAuthentication(authentication); 
     } 
    }catch(UserNotFoundException e){ 
    }finally { 
     filterChain.doFilter(servletRequest, servletResponse); 
     SecurityContextHolder.getContext().setAuthentication(null); 
    } 

} 
+0

我添加'AuthenticationFilter'類。我使用這個自定義過濾器是因爲我想使用JWT令牌認證而不是會話控制。 –

+0

我試過這個解決方案。還是行不通。 'getAuthentication(httpServletRequest)'方法拋出異常,因爲它從不需要提供標記的不必要的URL中調用,導致在方法 –

+0

中拋出的UserNotFoundException不會發生在我身上。我只是改變了你的代碼的doFilter方法,一切正常。當發送請求到'http:// localhost:8080/business /'時,當向http:// localhost:8080發送請求時,答案是'{「data':[],」msg「:null}用戶/ 1'我得到了一個403響應,除非我沒有從你的登錄端點獲得一個有效的令牌(也適用於我)。你可以推你當前的版本,所以我可以看看差異 –