2017-10-15 120 views
1

我很努力地使用沒有JWT令牌的/api/v1/web/** URI。這個URI必須是公開的。我知道這是很多應用程序中的一個常見功能,否則,我們如何創建登錄,登錄和重置密碼頁面?所以,我確信我犯了一些愚蠢的錯誤,因爲我對Spring Boot/Security沒有太多的經驗。Spring Security:爲什麼.authorizeRequests()。antMatchers(「/ api/v1/web/**」)。permitAll()不工作?

這裏是我的web安全配置代碼:

@Configuration 
@EnableWebSecurity 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

@Autowired 
private CustomAuthenticationProvider customAuthenticationProvider; 

@Autowired 
@Override 
protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
    auth.authenticationProvider(this.customAuthenticationProvider); 
} 

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    // disable caching 
     http.headers().cacheControl(); 

     /*ROUTING SECURITY*/ 
    http.csrf().disable() // disable csrf for our requests. 
     .cors() 
     .and() 
     .authorizeRequests() 
      .antMatchers("/api/v1/web/**").permitAll() 

      .antMatchers("/api/v1/users/**").hasAnyAuthority("USERS_LIST,USERS_CREATE,USERS_EDIT,USERS_DELETE") 
      .antMatchers("/api/v1/locals/**").hasAnyAuthority("LOCALS_LIST,LOCALS_CREATE,LOCALS_EDIT,LOCALS_DELETE") 
      .antMatchers("/api/v1/utils/**").hasAnyAuthority("UTILS") 

     .anyRequest().authenticated() 
     .and() 
     // We filter the api/login requests 
     .addFilterBefore(new JWTLoginFilter("/api/v1/login", authenticationManager()), UsernamePasswordAuthenticationFilter.class) 
     // And filter other requests to check the presence of JWT in header 
     .addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); 
} 

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

這裏是我的TokenAuthentication:

public class TokenAuthenticationService { 

private final String secret = "secret_string"; 
private final String tokenPrefix = "Bearer "; 
private final String headerString = "Authorization"; 

public void addAuthentication(HttpServletResponse response, Authentication authentication) { 

    GregorianCalendar expiration = new GregorianCalendar(); 
    expiration.add(GregorianCalendar.HOUR_OF_DAY, 5); 
    //expiration.add(GregorianCalendar.SECOND, 10); 

    List<UserAuthority> authorities = new ArrayList<UserAuthority>(); 
    for(GrantedAuthority authority : authentication.getAuthorities()) { 
     authorities.add(new UserAuthority(authority.getAuthority())); 
    } 

    AuthenticatedUser authenticatedUser = new AuthenticatedUser((String)authentication.getPrincipal(), authorities); 
    String dataToGenerateToken; 
    try { 
     dataToGenerateToken = new ObjectMapper().writeValueAsString(authenticatedUser); 
     // We generate a token now 
     String generatedToken = Jwts.builder() 
      .setSubject(dataToGenerateToken) 
      .setExpiration(expiration.getTime()) 
      .signWith(SignatureAlgorithm.HS512, secret) 
      .compact(); 
     response.addHeader(headerString, tokenPrefix + generatedToken); 
     response.addHeader("Access-Control-Expose-Headers", "Authorization"); 
     response.getWriter().write(dataToGenerateToken); 
    } catch (JsonProcessingException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    }   
} 

public Authentication getAuthentication(HttpServletRequest request) { 
    String token = request.getHeader(headerString).substring(7); 
    if (token != null) { 
     // parse the token. 
     String userData = Jwts.parser() 
      .setSigningKey(secret) 
      .parseClaimsJws(token) 
      .getBody() 
      .getSubject(); 
     if (userData != null) // we managed to retrieve a user 
     { 
      AuthenticatedUser authenticatedUser; 
      try { 
       authenticatedUser = new ObjectMapper().readValue(userData, AuthenticatedUser.class); 
       return authenticatedUser; 
      } catch (JsonParseException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (JsonMappingException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 
    return null; 
} 
} 

我只能訪問/api/v1/web/**,如果我包括智威湯遜認證,如果不是我得到下面的異常:

java.lang.NullPointerException: null 
at br.com.bilheteriarapida.admin.security.jwt.TokenAuthenticationService.getAuthentication(TokenAuthenticationService.java:61) ~[classes/:na] 
at br.com.bilheteriarapida.admin.security.jwt.JWTAuthenticationFilter.doFilter(JWTAuthenticationFilter.java:24) ~[classes/:na] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:96) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) [tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) [tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) [tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) [tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) [tomcat-embed-core-8.5.14.jar:8.5.14] 
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.14.jar:8.5.14] 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_51] 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_51] 
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.14.jar:8.5.14] 
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_51] 

如果我刪除了這段代碼的註釋:

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

我只能執行SELECT查詢下/api/v1/web/**的URI,如果我嘗試打電話節省對象(UPDATE或INSERT)我得到一個錯誤交易服務。非常奇怪,我知道。

有什麼想法?

感謝

+0

第61行是什麼?它是'String token = request.getHeader(headerString).substring(7);'?你不能在'null'上調用'substring'。 – dur

+0

最後一個錯誤是@dur。我不敢相信:(至少現在我可以使用'antMatchers()'正確配置安全性,而且我不需要再使用'web.ignoring()',但是非常感謝。 –

+0

您能否接受這個問題實際上只是一個'NullPointerException',這個問題對其他用戶沒有任何價值,對你沒有任何壞處,因爲你的問題已經被解決了。 – dur

回答

0

隨着SO人的幫助,我能實現我在做什麼錯了,這裏是我的最終解決方案:

@Configuration 
@EnableWebSecurity 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

@Autowired 
private CustomAuthenticationProvider customAuthenticationProvider; 

@Autowired 
@Override 
protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
    auth.authenticationProvider(this.customAuthenticationProvider); 
} 

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    // disable caching 
     http.headers().cacheControl(); 

     /*ROUTING SECURITY*/ 
    http.csrf().disable() // disable csrf for our requests. 
     .cors() 
     .and() 
      .authorizeRequests() 
      .antMatchers("/api/v1/web/**").permitAll() 
     .and() 
      .authorizeRequests() 
      .antMatchers("/api/v1/users/**").hasAnyAuthority("USERS_LIST,USERS_CREATE,USERS_EDIT,USERS_DELETE") 
      .antMatchers("/api/v1/locals/**").hasAnyAuthority("LOCALS_LIST,LOCALS_CREATE,LOCALS_EDIT,LOCALS_DELETE") 
      .antMatchers("/api/v1/utils/**").hasAnyAuthority("UTILS") 
      .anyRequest().authenticated() 
     .and() 
      .addFilterBefore(new JWTLoginFilter("/api/v1/login", authenticationManager()), UsernamePasswordAuthenticationFilter.class) 
      .addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); 
     }  
} 

,並在TokenAuthenticationService類,我編輯了getAuthentication方法第一線於:

public Authentication getAuthentication(HttpServletRequest request) { 
String token = request.getHeader(headerString); 
if (token != null) { 
    token = token.substring(7); 
.... 

}

現在,我的應用程序已經配置好,可以正確訪問公共和私人URI。不需要web.ignoring()了。

相關問題