【问题标题】:AngularJS & Spring Security with ROLE_ANONYMOUS still returns 401带有 ROLE_ANONYMOUS 的 AngularJS 和 Spring Security 仍然返回 401
【发布时间】:2015-07-07 17:19:33
【问题描述】:

我们正在构建一个 Angular Material 应用程序,使用 RESTful Spring MVC API,带有 Spring Security 和 OAUTH2。

出于测试目的,我们授予 ROLE_ANONYMOUS 访问 /users 端点的权限:

<intercept-url pattern="/users" method="POST" access="ROLE_ANONYMOUS"/>

但是当我们尝试通过 POST 发送 JSON 时,我们仍然会收到来自服务器的 401 响应。

  • 这不会发生在像 Postman 这样的非 Angular 客户端。
  • 如果我们禁用 Spring Security 过滤器,一切正常。
  • 对同一端点的 GET 请求也可以正常工作。

这是我们的 app.config:

  angular.module('App')
    .constant('RESOURCES', (function () {
                var resource = 'http://localhost:8080';
                return {
                  USERS: resource + '/users'
                }
              })());

还有做POST方法的工厂:

  app.factory('LoginUser', ['RESOURCES', '$resource', function (RESOURCES, $resource) {
    return $resource(RESOURCES.USERS, null, {
                       add: {method: 'POST'}
                     });
  }]);

以及控制器中的注册方法:

  function signup(user) {
    LoginUser.add({}, JSON.stringify(user));
  }

我们在Spring guide 之后的服务器中设置了 SimpleCORSFilter。

您可以在此处查看邮递员 POST 和 AngularJS POST 之间的比较:

标为红色的标头是我们必须在 Postman 中添加的自定义标头,以避免出现 415 不受支持的媒体类型。

我们尝试在 AngularJS 的 POST 请求中放置自定义标头,但它似乎不起作用:

.config(function ($httpProvider) {
    $httpProvider.defaults.headers.put['Content-Type'] = $httpProvider.defaults.headers.post['Content-Type'] =
        'application/json; charset=UTF-8';
});

【问题讨论】:

  • 如果我正确理解唯一不起作用的用例是当您需要在来自 Angular 的请求中进行身份验证时。因为它在您不需要身份验证(未拦截 GET 请求)或不使用 Angular 时有效。我会说您的角度前端没有正确管理身份验证。但不知道更多,我猜不出更多!
  • 嗨,谢尔盖!在全球范围内,WS 具有身份验证,但我们正在访问的端点具有 ROLE_ANONYMOUS 访问权限,因此我们认为不需要进行身份验证。当我们从 Postman 或 Java 客户端发出 POST 请求时,它会起作用,唯一不起作用的是 AngularJS。
  • 正如我所说,我无法猜测。您可以尝试使用 wireshark 之类的工具来窥探从 AngularJS 和 Postman 发送的请求的内容
  • 我们添加了 AngularJS 和 Postman 的请求,并没有发现任何实际问题(除了 Angular 中没有指定 content-type 之外,我们尝试添加但没有成功)。

标签: angularjs spring-mvc spring-security cors spring-security-oauth2


【解决方案1】:

好的,在查看屏幕截图后,我们注意到该方法是 OPTIONS 而不是 POST。

问题不在于标头(我们检查了太多以至于我们没有看到明显的标头),而在于 CORS 导致的飞行前请求 OPTIONS。这是nice article about it。我们的 Spring Security 是为 POST 方法配置的,但不是为 OPTIONS 配置的。我们改变了它,现在它就像一个魅力:

  <intercept-url pattern="/users" method="POST" access="ROLE_ANONYMOUS"/>
  <intercept-url pattern="/users" method="OPTIONS" access="ROLE_ANONYMOUS"/>

【讨论】:

    猜你喜欢
    • 2018-04-26
    • 2018-11-06
    • 2020-07-24
    • 2021-07-24
    • 2017-10-11
    • 2016-10-16
    • 1970-01-01
    • 2017-05-26
    • 1970-01-01
    相关资源
    最近更新 更多