【问题标题】:Spring Security: Why .authorizeRequests().antMatchers("/api/v1/web/**").permitAll() is not working? [duplicate]Spring Security:为什么 .authorizeRequests().antMatchers("/api/v1/web/**").permitAll() 不起作用? [复制]
【发布时间】:2018-03-27 03:36:02
【问题描述】:

我正在努力使用不使用 JWT 令牌访问 /api/v1/web/** URI。此 URI 必须是公开的。我知道这是许多应用程序中的常见功能,否则,我们如何创建登录、登录和重置密码页面?所以,我确信我犯了一些愚蠢的错误,因为我对 Spring Boot / Security 没有太多经验。

这是我的网络安全配置代码:

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

如果我包含 JWT 身份验证,我只能访问/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]

如果我删除这段代码的 cmets:

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

我只能在/api/v1/web/** URI 下执行 SELECT 查询,如果我尝试调用保存对象的服务(UPDATE 或 INSERT),我会收到事务错误。很奇怪,我知道。

有什么想法吗?

谢谢

【问题讨论】:

  • 第 61 行是什么?是String token = request.getHeader(headerString).substring(7);吗?你不能在null上打电话给substring
  • 最后一个错误是@dur。我不敢相信 :( 至少现在我可以正确配置安全性,使用antMatchers(),我不再需要使用web.ignoring()。非常感谢。
  • 您能否接受副本。它实际上只是一个NullPointerException。这个问题对其他用户没有价值。对您没有任何伤害,因为您的问题已被投票。

标签: java spring-boot spring-security jwt


【解决方案1】:

在 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()

【讨论】:

    猜你喜欢
    • 2018-01-31
    • 1970-01-01
    • 2019-09-27
    • 1970-01-01
    • 1970-01-01
    • 2017-10-11
    • 2016-02-16
    • 1970-01-01
    • 2020-04-16
    相关资源
    最近更新 更多