2017-10-15 2 views
1

J'ai du mal à accéder aux URIs /api/v1/web/** en utilisant aucun jeton JWT. Cette URI doit être publique. Je sais que c'est une fonctionnalité courante dans de nombreuses applications, sinon, comment pourrions-nous créer une connexion, nous connecter et réinitialiser les pages de mot de passe? Donc, je suis sûr que je fais une erreur idiote car je n'ai pas beaucoup d'expérience avec Spring Boot/Security.Sécurité de printemps: pourquoi .authorizeRequests(). AntMatchers ("/ api/v1/web/**"). PermitAll() ne fonctionne pas?

Voici ma sécurité web code config:

@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/**"); 
//  } 
} 

Voici mon 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; 
} 
} 

Je ne peut accéder /api/v1/web/** si j'inclure l'authentification JWT, sinon je reçois l'exception suivante :

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] 

Et si je retire les commentaires de ce code:

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

Je ne peux exécuter des requêtes SELECT sous /api/v1/web/** URIs, si je tente d'appeler un service qui permet de gagner un objet (UPDATE ou INSERT) Je reçois une erreur transactionnelles. Très bizarre, je sais.

Une idée?

Merci

+0

Qu'est-ce que la ligne 61? Est-ce 'String token = request.getHeader (headerString) .substring (7);'? Vous ne pouvez pas appeler 'substring' sur' null'. – dur

+0

La dernière erreur était que @dur. Je ne peux pas croire :(Au moins maintenant, je pourrais configurer la sécurité correctement, en utilisant 'antMatchers()' et je n'ai plus besoin d'utiliser le 'web.ignoring()' .. Merci beaucoup –

+0

Pourriez-vous s'il vous plaît accepter le doublon C'est vraiment juste un 'NullPointerException' Cette question n'a aucune valeur pour les autres utilisateurs.Il n'y a pas de mal pour vous, parce que votre question est upvoted. – dur

Répondre

0

Avec le SO gars aider, je pouvais réaliser ce que je faisais mal et voici ma solution finale:

@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); 
     }  
} 

et dans la classe TokenAuthenticationService, je modifier la méthode getAuthentication premières lignes à:

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

}

Maintenant, mon application est bien configurée pour accéder correctement aux URI publics et privés. Plus besoin de web.ignoring().