2017-10-15 1 views
1

Ich habe Schwierigkeiten, auf die /api/v1/web/** URIs zuzugreifen, die kein JWT-Token verwenden. Diese URI muss öffentlich sein. Ich weiß, dass dies in vielen Anwendungen ein gemeinsames Merkmal ist. Wie könnten wir sonst Passwortseiten erstellen, anmelden und zurücksetzen? Ich bin mir sicher, dass ich einen dummen Fehler mache, da ich nicht viel Erfahrung mit Spring Boot/Security habe.Spring Security: Warum. AuthorizeRequests(). AntMatchers ("/ api/v1/web/**"). PermitAll() funktioniert nicht?

Hier ist meine Web-Sicherheit Konfigurationscode:

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

Ich kann nur /api/v1/web/** zugreifen, wenn ich die JWT Authentifizierung umfassen, wenn nicht ich die folgende Ausnahme:

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

Hier mein TokenAuthentication ist :

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] 

Und wenn ich die Kommentare dieses Codes entfernen:

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

Ich kann nur SELECT-Abfragen unter /api/v1/web/** URIs ausführen, wenn ich versuche, einen Dienst zu nennen, die ein Objekt speichert (UPDATE oder INSERT) ich einen Transactional Fehler. Sehr seltsam, ich weiß.

Irgendeine Idee?

Dank

+0

Was ist Linie 61? Ist es 'String token = request.getHeader (headerString) .substring (7);'? Sie können 'substring' nicht auf' null' aufrufen. – dur

+0

Der letzte Fehler war, dass @dur. Ich kann es nicht glauben :(Zumindest könnte ich jetzt die Sicherheit mit 'antMatchers()' richtig konfigurieren und ich brauche die 'web.ignoring()' nicht mehr. Vielen Dank. –

+0

Könnten Sie bitte akzeptieren das Duplikat. Es ist wirklich nur eine 'NullPointerException'. Diese Frage hat keinen Wert für andere Benutzer. Es gibt keinen Schaden für Sie, weil Ihre Frage upvoted ist. – dur

Antwort

0

Mit der SO Jungs helfen, konnte ich erkennen, was ich falsch mache und hier ist meine letzte Lösung:

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

und in der TokenAuthenticationService Klasse, herausgegeben ich die getAuthentication Methode ersten Zeilen zu:

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

}

Nun ist meine Anwendung so konfiguriert, dass sie ordnungsgemäß auf öffentliche und private URIs zugreifen kann. Keine Notwendigkeit mehr web.ignoring().

Verwandte Themen