带有 ROLE_ANONYMOUS 的 AngularJS 和 Spring Security 仍然返回 401

Posted

技术标签:

【中文标题】带有 ROLE_ANONYMOUS 的 AngularJS 和 Spring Security 仍然返回 401【英文标题】:AngularJS & Spring Security with ROLE_ANONYMOUS still returns 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 之外,我们尝试添加但没有成功)。 【参考方案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"/>

【讨论】:

以上是关于带有 ROLE_ANONYMOUS 的 AngularJS 和 Spring Security 仍然返回 401的主要内容,如果未能解决你的问题,请参考以下文章

带有 FCM 推送通知的 Angular 服务工作者

带有 Razor 页面的 ASP .Net Core 与 UI 的 Angular [关闭]

使用带有 Angular2 和 Socket.io 的量角器运行 e2e 测试

部署 Spring Boot + Angular 应用程序时出现问题

TypeScript - 茉莉花 - Chutzpah - AngularJS

AngularDart 中带有验证和错误消息的材料输入