1

我有一个使用@azure/msal-browser. 我在 Azure 中有一个“应用程序注册”,用于验证用户是否是我们 AD 的一部分以及是否允许他/她访问该网页。这工作正常。用户需要先进行身份验证才能访问网页。

网页本身对 REST API 执行多个 AJAX 调用,这只不过是启用了 Spring Web 的 Spring Boot 应用程序。这个后端是不安全的......但(!)。

目标:

我想保护后端,以便只有在您拥有有效的访问令牌时才能查询 REST API。前端将在Authentication: Bearer XXX向后端执行调用时添加令牌。

我在这里查看了示例:https ://github.com/Azure/azure-sdk-for-java/tree/master/sdk/spring/azure-spring-boot-samples我看到了 4 个选项:

  • azure-spring-boot-sample-active-directory-resource-server-by-filter-stateless
  • azure-spring-boot-sample-active-directory-resource-server-by-filter
  • azure-spring-boot-sample-active-directory-resource-server-obo
  • azure-spring-boot-sample-active-directory-resource-server

前两个似乎有点过时,因为如果我在本地运行它们,我会收到所有已弃用的警告。但是这些例子中的哪一个会涵盖我的用例?

总结:

我想要 ...

  • ...在前端授权用户使用msal-browser
  • ...只需将访问令牌添加为标头即可从前端(嗯,执行 AJAX 调用的客户端浏览器)向后端执行请求
  • ...后端自动验证令牌,如果有效,后端返回数据

感谢您的任何反馈!

4

2 回答 2

1

@Jochen Hebbrecht,

我是 azure-spring-boot-starter-active-directory 的开发人员。

我认为你应该选择最后一个:azure-spring-boot-sample-active-directory-resource-server。

此外,现在我建议您选择另一种解决方案:使用 spring-security-oauth2-resource-server 而不是 azure-spring-boot-starter-active-directory。

以下是示例:https ://github.com/Azure-Samples/azure-spring-boot-samples/tree/0eb5046b48298c9bd681133f4746b9b263becdc9/AzureActiveDirectory/OAuth2

样品03-resource-server是你想要的,我想。您可以一一浏览这些示例,以获取有关如何保护 REST API 的更多信息。

如果您有任何问题,请在此处创建问题:https ://github.com/Azure-Samples/azure-spring-boot-samples/issues/new

cc:@Jean-François Fabre,我更新了之前的答案,但我无法取消删除之前的答案。所以我创建了一个新的。

于 2021-10-29T00:17:10.743 回答
0

我之前也有同样的想法,这是我的解决方案。

在前端,使用微软提供的 msal.js 实现登录模块并通过它生成访问令牌。然后在请求标头中发送带有 Bearer 令牌的 ajax 请求。在我的 springboot 后端应用程序中,请参考此示例以添加过滤器以验证传入请求中是否包含有效的访问令牌。过滤器需要检查请求标头中是否有令牌,然后对其进行解码并检查令牌是否已过期,如果需要,是否具有正确的范围。

这里有另一个任务,我们需要为后端 api 设置范围。这需要在 azure ad 中公开 api(创建 azure ad 应用程序并去公开 api 刀片以执行下一步操作)。您可以参考this了解详细信息。这里请注意,这里暴露的api是生成access token时的输入参数(我们需要设置scope参数,暴露的api就是将这个api权限添加到用于生成access token的azure ad app后的作用域)。

在这些操作之后,过滤器可以检查令牌是否包含您之前自定义的范围。我认为这是验证令牌最重要的。

过滤器代码:https ://stackoverflow.com/a/66097364/14574199

由于前端 - 后端模型,您可能需要为您的 springboot 应用程序使用 CORS 过滤器,如下所示:

package com.example.demo;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Order(Integer.MIN_VALUE)
@Component
public class CorsFilter implements Filter {
    @Override
      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
          throws IOException, ServletException {
        HttpServletResponse res = (HttpServletResponse) response;
        res.addHeader("Access-Control-Allow-Credentials", "true");
        res.addHeader("Access-Control-Allow-Origin", "*");
        res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
        res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN,Authorization");
        if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) {
          response.getWriter().println("ok");
          return;
        }
        chain.doFilter(request, response);
      }
      @Override
      public void destroy() {
      }
      @Override
      public void init(FilterConfig filterConfig) throws ServletException {
      }
}
于 2021-05-04T14:54:44.947 回答