【问题标题】:Angular 6 Spring Boot POST IssueAngular 6 Spring Boot POST 问题
【发布时间】:2019-04-02 21:54:22
【问题描述】:

我正在尝试设置一个与本地 Spring Boot REST 应用程序对话的 Angular 6 应用程序。

我终于能够登录并使用 GET 请求,这似乎使用了正确的 cookie。有 2 个 cookie,一个 JSESSION cookie 和一个 XSRF cookie。问题是我从任何 POST 请求中得到 403 响应。我非常有信心,这更多是我的 Spring 设置的问题。

Spring 安全配置:

@Configuration
public class CORSConfig implements WebMvcConfigurer {

@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**")
        .allowedOrigins("http://localhost:4200")
        .allowCredentials(true)
        .allowedHeaders("*")
        .allowedMethods("GET", "POST", "*")
        .exposedHeaders("Set-Cookie","Authorization");
}

还有

@Override
protected void configure(HttpSecurity http) throws Exception {
     http
        .cors()
     .and()
        .httpBasic()
     .and()
        .authorizeRequests()
          .antMatchers("/", "/main", "/user", "/runtime.js","/polyfills.js",
                  "/main.js", "/styles.js", "/vendor.js").permitAll()
          .anyRequest().authenticated()
     .and()
        .csrf()

.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
     .and().sessionManagement().maximumSessions(1).and()
          .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);

}

请注意,除“/user”之外的 antMatchers 实际上并未在此设置中使用。这些文件正在使用 ng serve 在本地提供。

我的角度设置:

@Injectable()
export class AuthenticationInterceptor implements HttpInterceptor{

intercept(req: HttpRequest<any>, next: HttpHandler): 
Observable<HttpEvent<any>>
{
    const xhr = req.clone({
        headers: req.headers.set('X-Requested-With', 'XMLHttpRequest'),
        withCredentials: true
      });
      return next.handle(xhr);
}

这个调用现在可以工作了:

getExercise(id:Number): Observable<Exercise>
{
    return this.http.get<Exercise>(environment.baseUrl + '/api/exercise/' + id);
}

但是这个,POST,不会。

saveExercise(exercise: Exercise): Observable<Exercise>
{
   return this.http.post<Exercise>(environment.baseUrl + 
   '/newExercise',exercise);
}

GET 的 Spring Security 日志:

DEBUG 18776 --- [nio-8080-exec-1] o.s.b.w.s.f.OrderedRequestContextFilter  : Bound request context to thread: org.apache.catalina.connector.RequestFacade@29dbd699
DEBUG 18776 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /api/exercise/2 at position 1 of 14 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
DEBUG 18776 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /api/exercise/2 at position 2 of 14 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
DEBUG 18776 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
DEBUG 18776 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
DEBUG 18776 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /api/exercise/2 at position 3 of 14 in additional filter chain; firing Filter: 'HeaderWriterFilter'
DEBUG 18776 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /api/exercise/2 at position 4 of 14 in additional filter chain; firing Filter: 'CorsFilter'
DEBUG 18776 --- [nio-8080-exec-1] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@2de4577a
DEBUG 18776 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
DEBUG 18776 --- [nio-8080-exec-1] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
DEBUG 18776 --- [nio-8080-exec-1] o.s.b.w.s.f.OrderedRequestContextFilter  : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@29dbd699
DEBUG 18776 --- [nio-8080-exec-4] o.s.b.w.s.f.OrderedRequestContextFilter  : Bound request context to thread: org.apache.catalina.connector.RequestFacade@29dbd699
DEBUG 18776 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /api/exercise/2 at position 1 of 14 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
DEBUG 18776 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /api/exercise/2 at position 2 of 14 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
DEBUG 18776 --- [nio-8080-exec-4] w.c.HttpSessionSecurityContextRepository : Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@84a2a85a: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@84a2a85a: Principal: com.op.movement.model.ApplicationUserDetails@7b5de4fa; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Not granted any authorities'
DEBUG 18776 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /api/exercise/2 at position 3 of 14 in additional filter chain; firing Filter: 'HeaderWriterFilter'
DEBUG 18776 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /api/exercise/2 at position 4 of 14 in additional filter chain; firing Filter: 'CorsFilter'
DEBUG 18776 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /api/exercise/2 at position 5 of 14 in additional filter chain; firing Filter: 'CsrfFilter'
DEBUG 18776 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /api/exercise/2 at position 6 of 14 in additional filter chain; firing Filter: 'LogoutFilter'
DEBUG 18776 --- [nio-8080-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /api/exercise/2' doesn't match 'POST /logout
DEBUG 18776 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /api/exercise/2 at position 7 of 14 in additional filter chain; firing Filter: 'ConcurrentSessionFilter'
DEBUG 18776 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /api/exercise/2 at position 8 of 14 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
DEBUG 18776 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /api/exercise/2 at position 9 of 14 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
DEBUG 18776 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /api/exercise/2 at position 10 of 14 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
DEBUG 18776 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /api/exercise/2 at position 11 of 14 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
DEBUG 18776 --- [nio-8080-exec-4] o.s.s.w.a.AnonymousAuthenticationFilter  : SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@84a2a85a: Principal: com.op.movement.model.ApplicationUserDetails@7b5de4fa; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Not granted any authorities'
DEBUG 18776 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /api/exercise/2 at position 12 of 14 in additional filter chain; firing Filter: 'SessionManagementFilter'
DEBUG 18776 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /api/exercise/2 at position 13 of 14 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
DEBUG 18776 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /api/exercise/2 at position 14 of 14 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
DEBUG 18776 --- [nio-8080-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/api/exercise/2'; against '/'
DEBUG 18776 --- [nio-8080-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/api/exercise/2'; against '/main'
DEBUG 18776 --- [nio-8080-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/api/exercise/2'; against '/user'
DEBUG 18776 --- [nio-8080-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/api/exercise/2'; against '/runtime.js'
DEBUG 18776 --- [nio-8080-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/api/exercise/2'; against '/polyfills.js'
DEBUG 18776 --- [nio-8080-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/api/exercise/2'; against '/main.js'
DEBUG 18776 --- [nio-8080-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/api/exercise/2'; against '/styles.js'
DEBUG 18776 --- [nio-8080-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/api/exercise/2'; against '/vendor.js'
DEBUG 18776 --- [nio-8080-exec-4] o.s.s.w.a.i.FilterSecurityInterceptor    : Secure object: FilterInvocation: URL: /api/exercise/2; Attributes: [authenticated]
DEBUG 18776 --- [nio-8080-exec-4] o.s.s.w.a.i.FilterSecurityInterceptor    : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@84a2a85a: Principal: com.op.movement.model.ApplicationUserDetails@7b5de4fa; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Not granted any authorities
DEBUG 18776 --- [nio-8080-exec-4] o.s.s.access.vote.AffirmativeBased       : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@74ead523, returned: 1
 DEBUG 18776 --- [nio-8080-exec-4] o.s.s.w.a.i.FilterSecurityInterceptor    : Authorization successful
DEBUG 18776 --- [nio-8080-exec-4] o.s.s.w.a.i.FilterSecurityInterceptor    : RunAsManager did not change Authentication object
DEBUG 18776 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /api/exercise/2 reached end of additional filter chain; proceeding with original chain
Getting exercise by ID: 2
DEBUG 18776 --- [nio-8080-exec-4] org.hibernate.SQL                        : select exercise0_.id as id1_0_0_, exercise0_.instructions as instruct2_0_0_, exercise0_.name as name3_0_0_ from operation_movement.exercises exercise0_ where exercise0_.id=?
DEBUG 18776 --- [nio-8080-exec-4] org.hibernate.SQL                        : select goaltypes0_.exercise_id as exercise1_1_0_, goaltypes0_.goal_types_id as goal_typ2_1_0_, goaltype1_.id as id1_2_1_, goaltype1_.name as name2_2_1_ from operation_movement.exercises_goal_types goaltypes0_ inner join operation_movement.goaltypes goaltype1_ on goaltypes0_.goal_types_id=goaltype1_.id where goaltypes0_.exercise_id=?
DEBUG 18776 --- [nio-8080-exec-4] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@2de4577a
DEBUG 18776 --- [nio-8080-exec-4] o.s.s.w.a.ExceptionTranslationFilter     : Chain processed normally
DEBUG 18776 --- [nio-8080-exec-4] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
DEBUG 18776 --- [nio-8080-exec-4] o.s.b.w.s.f.OrderedRequestContextFilter  : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@29dbd699

返回 403 响应的 POST 的 Spring 日志:

DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /newExercise at position 1 of 14 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /newExercise at position 2 of 14 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
 DEBUG 18776 --- [nio-8080-exec-7] w.c.HttpSessionSecurityContextRepository : Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@84a2a85a: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@84a2a85a: Principal: com.op.movement.model.ApplicationUserDetails@7b5de4fa; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Not granted any authorities'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /newExercise at position 3 of 14 in additional filter chain; firing Filter: 'HeaderWriterFilter'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /newExercise at position 4 of 14 in additional filter chain; firing Filter: 'CorsFilter'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /newExercise at position 5 of 14 in additional filter chain; firing Filter: 'CsrfFilter'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.csrf.CsrfFilter         : Invalid CSRF token found for http://localhost:8080/newExercise
 DEBUG 18776 --- [nio-8080-exec-7] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@2de4577a
 DEBUG 18776 --- [nio-8080-exec-7] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
 DEBUG 18776 --- [nio-8080-exec-7] o.s.b.w.s.f.OrderedRequestContextFilter  : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@29dbd699
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 1 of 14 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 2 of 14 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
 DEBUG 18776 --- [nio-8080-exec-7] w.c.HttpSessionSecurityContextRepository : Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@84a2a85a: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@84a2a85a: Principal: com.op.movement.model.ApplicationUserDetails@7b5de4fa; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Not granted any authorities'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 3 of 14 in additional filter chain; firing Filter: 'HeaderWriterFilter'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 4 of 14 in additional filter chain; firing Filter: 'CorsFilter'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 5 of 14 in additional filter chain; firing Filter: 'CsrfFilter'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 6 of 14 in additional filter chain; firing Filter: 'LogoutFilter'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/logout'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 7 of 14 in additional filter chain; firing Filter: 'ConcurrentSessionFilter'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 8 of 14 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 9 of 14 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 10 of 14 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 11 of 14 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.s.w.a.AnonymousAuthenticationFilter  : SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@84a2a85a: Principal: com.op.movement.model.ApplicationUserDetails@7b5de4fa; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Not granted any authorities'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 12 of 14 in additional filter chain; firing Filter: 'SessionManagementFilter'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 13 of 14 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 14 of 14 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/main'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/user'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/runtime.js'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/polyfills.js'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/main.js'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/styles.js'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/vendor.js'
 DEBUG 18776 --- [nio-8080-exec-7] o.s.s.w.a.i.FilterSecurityInterceptor    : Secure object: FilterInvocation: URL: /error; Attributes: [authenticated]
 DEBUG 18776 --- [nio-8080-exec-7] o.s.s.w.a.i.FilterSecurityInterceptor    : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@84a2a85a: Principal: com.op.movement.model.ApplicationUserDetails@7b5de4fa; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Not granted any authorities
 DEBUG 18776 --- [nio-8080-exec-7] o.s.s.access.vote.AffirmativeBased       : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@74ead523, returned: 1
 DEBUG 18776 --- [nio-8080-exec-7] o.s.s.w.a.i.FilterSecurityInterceptor    : Authorization successful
 DEBUG 18776 --- [nio-8080-exec-7] o.s.s.w.a.i.FilterSecurityInterceptor    : RunAsManager did not change Authentication object
 DEBUG 18776 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error reached end of additional filter chain; proceeding with original chain
 DEBUG 18776 --- [nio-8080-exec-7] o.s.s.w.a.ExceptionTranslationFilter     : Chain processed normally
 DEBUG 18776 --- [nio-8080-exec-7] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed

【问题讨论】:

  • 尝试“POST、PUT、GET、OPTIONS、DELETE”而不是(“GET”、“POST”、“*”)
  • 可能是因为您发布到 /newExercise 并且在 authenticatedRequests 中没有提到吗?
  • 还使用 @order(Ordered.HIGHEST_PRECEDENCE) 注释您的 CORSConfig 类
  • 感谢您的回复!不过,这些解决方案似乎无法解决问题。使用完整的操作列表实际上以某种方式破坏了 OPTIONS 请求。我在想这与过滤器顺序有关,但设置 CORSConfig 顺序似乎并没有解决它...
  • @Taranjit Kang - 不,如果您指的是代码 .authorizeRequests() .antMatchers("/", "/main", "/user", "/runtime. js","/polyfills.js", "/main.js", "/styles.js", "/vendor.js").permitAll() .anyRequest().authenticated() -------这基本上是在告诉 spring security 这些资源已经被授权,并且可以被任何人加载。所有其他请求都应经过身份验证。并且 /newExercise 应该经过身份验证。

标签: java angular spring spring-boot


【解决方案1】:

对于任何有同样问题的人,做

csrf().disable() 

会解决这个问题,虽然我不知道为什么。在使用 cookie 时,似乎 Spring CSRF 和 CORS 会以某种方式发生冲突......

如果我不得不猜测,下面的工作并没有按预期工作

.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())

这很奇怪,因为它直接引用了 Angular:

A CsrfTokenRepository that persists the CSRF token in a cookie named "XSRF-TOKEN" and
reads from the header "X-XSRF-TOKEN" following the conventions of AngularJS. When 
using with AngularJS be sure to use withHttpOnlyFalse().

以上似乎是真的 - 我看到 CSRF 令牌是由浏览器设置和发送的,但 Spring 不接受它是有效的。 (见上面的日志)

Invalid CSRF token found for http://localhost:8080/newExercise


Request Cookies                         
JSESSIONID  31AD5A7891F8BB83072BFC040AABBB35        
XSRF-TOKEN  579db734-412c-4ce8-82a2-20aa097e47f

目前,禁用 CSRF 将适用于开发,但有一个真实的用例可以从单独的服务器为我的 Angular 应用程序提供服务,这是唯一应该能够向我的 spring 服务器发出请求的服务器。希望其他信息可以帮助某人,如果我找到它,我会尝试在这里发布一个真实的答案。

【讨论】:

  • 这只是 Angular 6 的问题吗?
  • @john 我不确定 - angular 6 是我唯一满意的版本。我实际上根本不确定这是角度的问题。这可能是春季问题。
  • 奇怪...这里 .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse 只适用于 GET 操作...
【解决方案2】:

尝试将您的.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) 替换为csrfTokenRepositoryCsrfFilter

 .csrfTokenRepository(csrfTokenRepository()).and()
    .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);

full answer

@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().and().authorizeRequests()
    .antMatchers("/send-pin").permitAll() 
    .antMatchers("/check-pin").permitAll()
    .antMatchers("/index.html", "/", "/login", "/someotherrurl") 
    .permitAll().anyRequest().authenticated().and().csrf()
    .csrfTokenRepository(csrfTokenRepository()).and()
    .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);

【讨论】:

    猜你喜欢
    • 2020-09-08
    • 2019-01-24
    • 2017-04-13
    • 2020-04-27
    • 2019-05-05
    • 2021-08-02
    • 2018-10-30
    • 2019-04-24
    • 2019-05-11
    相关资源
    最近更新 更多