Angular 1.4、POST、Spring Security、CORS

Posted

技术标签:

【中文标题】Angular 1.4、POST、Spring Security、CORS【英文标题】:Angular 1.4, POST, Spring Security, CORS 【发布时间】:2016-02-25 17:12:55 【问题描述】:

在我以前的帖子中,我尝试使用 POST 方法将带有列表的 JSON 从 angular 发送到 spring mvc。 现在它工作正常! 控制器:

@RequestMapping(value="/create/", method=RequestMethod.POST)
@ResponseBody
public StatusResponse create(@RequestBody EventsDTO events) throws TechnicalException 
return new StatusResponse();

角度:

 var _queryPost = function(url, data, defData) 

        $http(
          headers: 'Content-Type': 'application/json',
                    'Accept': 'application/json',
          method: 'POST',
          url: url,
          //params: data,
          data: data,
            withCredentials: true
        )
          .success(function (data, status, headers, config) 
            defData.$resolve(data);
            $log.info(data);
          )
          .error(function (data, status, headers, config) 
            defData.$reject(data);
          );

        return defData;
    ;

但要成功,我必须评论 Spring 安全性...... 当我使用 spring security 时,我得到了错误 401,POST 请求变成了 OPTIONS 请求。 在阅读了很多文档和帖子后,我明白了: 1-在发送 POST 请求之前完成第一个 OPTIONS 请求(这是一个检查) 2- 发生错误是因为“内容类型”值为“应用程序/json”。 允许的 Content-Type 值是“application/x-www-form-urlencoded”和其他我忘记但不是“application/json”的值

问题是,如果我在 Angular 中更改 Content-type 的值,我会收到错误 415....

我已经尝试了我发现的不同的东西,比如一些在 angular 中的添加:

$httpProvider.defaults.headers.common['X-XSRF-Token'] = $('meta[name=csrf-token]').attr('content')
$httpProvider.defaults.withCredentials = true;
$httpProvider.defaults.headers.common='Accept' : 'application/json';
$httpProvider.defaults.headers.post='Content-Type' : 'application/json';
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];

但我认为它不适用于角度版本 > 1.2(我使用 1.4) 这是我在 web.xml 中的 Spring 安全配置:

<!-- CORS related filter -->
<filter>
    <filter-name>CORS</filter-name>
    <filter-class>
      org.eclipse.jetty.servlets.CrossOriginFilter
    </filter-class>

    <init-param>
        <param-name>allowedOrigins</param-name>
        <param-value>*</param-value>
    </init-param>
   <init-param>
        <param-name>allowedMethods</param-name>
        <param-value>GET,POST,DELETE,PUT,HEAD,OPTIONS</param-value>
    </init-param>
    <init-param>
        <param-name>allowedHeaders</param-name>
        <param-value>
           origin, content-type, accept, authorization, 
              x-requested-with, access-token, x-xsrf-token
        </param-value>
    </init-param>
    <init-param>
        <param-name>supportsCredentials</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>CORS</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>


<!-- Spring Security Filters -->
<filter>
   <filter-name>springSecurityFilterChain</filter-name>
   <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

那么我该怎么做才能通过 Spring Security 传递我的 EventsDTO bean? 我必须更改 Angular 配置或 spring 安全配置吗?怎么做?

【问题讨论】:

【参考方案1】:

如果您不需要针对 CORS OPTION prefligh 请求执行任何特定操作(我相信您不需要),那么只需配置 CrossOriginFilter 即可回答,无需将其传递给主应用程序。据我了解,可以通过以下方式完成:

<init-param>
    <param-name>chainPreflight</param-name>
    <param-value>false</param-value>
</init-param>

或者,如果它不起作用,则为 OPTION 请求创建一个空的 Spring 控制器。

PS 应用程序不应对此类 OPTION 请求做出任何有意义的响应,它是一个 CORS 预检,因此只需使用 Access-Control-XXX 标头进行响应。这就是CrossOriginFilter 会做的事情。

【讨论】:

你喜欢香槟吗?它适用于 CrossOriginFilter 配置!非常感谢!!!!

以上是关于Angular 1.4、POST、Spring Security、CORS的主要内容,如果未能解决你的问题,请参考以下文章

Angular 和 Spring 启动 - POST 请求成为 OPTIONS

Angular 2,Spring Security:跨源 POST 不会发送 cookie

不支持 Spring 安全 Angular Post

spring boot angular 2 post方法403错误

Spring Boot + Angular 5 - http.post 空值

Spring Security 的 POST 响应标头中未设置 Angular 2 CSRF cookie