Angular XSRF控制器响应为null

问题描述

我不太确定如何进一步调试此问题。我已经根据网上发现的内容为Web服务和表示层实现了模板。话虽如此,该实施未按预期工作。我要做的就是将登录凭据发送到后端,该后端将使用该凭据并将数据保存到数据库中。现在,尽管它从未到达控制器,但仍然到达Spring Security的过滤器,但我得到的响应为null。如果我没有将Spring Security软件包加载到应用程序中,那么所有功能都将按预期工作。我很困惑为什么我得到一个无效的答复。我的过滤器中没有一个返回空值。我怀疑它来自Spring Security,但错误未登录控制台以提供帮助。

技术堆栈:
表示层:Angular 8
Web服务:Spring Boot

演示层

  login(url: string,credentials: FormGroup): any {
    return this.httpClient.post(url,null)
      .pipe(catchError(this.errorHandler));
  }

Http拦截器

constructor(private cookieService: CookieService) { }

 intercept(req: HttpRequest<any>,next: HttpHandler): Observable<HttpEvent<any>> {
    let newHeaders: HttpHeaders = req.headers;

    let xsrfToken = this.cookieService.get("XSRF-TOKEN");
    if (xsrfToken != null && xsrfToken !== undefined) {
      newHeaders = newHeaders.append("X-XSRF-TOKEN",xsrfToken);
    } else {
      newHeaders = newHeaders.append("X-XSRF-TOKEN","UNKN0WNT0K3N");
    }

    newHeaders = newHeaders.append("Cache-control","no-cache,no-store,must-revalidate");
    newHeaders = newHeaders.append("Pragma","no-cache");
    newHeaders = newHeaders.append("Expires","0");

    const authRequest = req.clone({headers: newHeaders,withCredentials: true});
    return next.handle(authRequest);
  }

网络安全配置

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    RequestMatcher csrfRequestMatcher = new RequestMatcher() {
        private AntPathRequestMatcher[] requestMatchers = {
                new AntPathRequestMatcher("/admin/**")
        };

        @Override
        public boolean matches(HttpServletRequest servletRequest) {
            for (AntPathRequestMatcher rm : requestMatchers) {
                if (rm.matches(servletRequest)) {
                    return true;
                }
            }
            return false;
        }
    };

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf()
                .requireCsrfProtectionMatcher(csrfRequestMatcher)
                .csrfTokenRepository(csrfTokenRepository())
                .and()
                    .addFilterAfter(new CsrfHeaderFilter(),CsrfFilter.class)
                    .authorizeRequests()
            .and()
                .authorizeRequests()
                    .antMatchers("/login").permitAll()
            .and()
                .logout()
                    .invalidateHttpSession(true)
                    .deleteCookies("JSESSIONID")
                    .permitAll();
    }

    private CookieCsrfTokenRepository csrfTokenRepository() {
        CookieCsrfTokenRepository cookieRepository = new CookieCsrfTokenRepository();
        cookieRepository.setHeaderName("X-XSRF-TOKEN");
        cookieRepository.setCookieName("XSRF-TOKEN");

        cookieRepository.setCookiePath("/");
        cookieRepository.setCookieHttpOnly(false);
        return cookieRepository;
    }
}

标准CSRF Coo​​kie类

public class CsrfHeaderFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request,HttpServletResponse response,FilterChain chain) throws ServletException,IOException {
        CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());

         if (csrf != null) {
            Cookie cookie = WebUtils.getCookie(request,"XSRF-TOKEN");
            String token = csrf.getToken();

            if (cookie == null || (token != null && !token.equals(cookie.getValue()))) {
                cookie = new Cookie("XSRF-TOKEN",token);
                cookie.setPath("/");
                response.addCookie(cookie);
            }
        }

        chain.doFilter(request,response);
    }
}

Cors标头类

@Component
public class CorsHeaders extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest servletRequest,HttpServletResponse servletResponse,IOException {
        String header = servletRequest.getHeader("Origin");

        if (header != null && !header.isEmpty()) {
            servletResponse.addHeader("Access-Control-Allow-Origin",header);
            servletResponse.addHeader("Access-Control-Allow-Methods","GET,POST,PUT,OPTIONS,DELETE");
            servletResponse.addHeader("Access-Control-Allow-Credentials","true");
            servletResponse.addHeader("Access-Control-Allow-Headers","Pragma,cache-control,expires,Content-Type,x-xsrf-token,xsrf-token");
        }
    }
}

出于完整性考虑:登录URI方法

@RestController
@CrossOrigin(origins = "*",maxAge = 3600)
@RequestMapping(path = "/account/portal")
public class AccountController {
{
   .
   .
   .

    @PostMapping(path = "/login")
    public @ResponseBody boolean login() {
        if (user != null && !user.getUsername().equals("") && !user.getPassword().equals(""))
            return managementService.loginUser(user.getUsername());

        return false;

    }

    .
    .
    .
}

让我知道您还有什么需要更好地理解我的问题。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...