Spring 启动和 Okta SAML2

tar*_*oyf 2 okta spring-security-saml2

我喜欢使用 spring-security-saml2-service-provider 的想法 - 来自文档: https ://docs.spring.io/spring-security/reference/5.6.0-RC1/servlet/saml2/index.html spring-security-saml2-core 的它看起来少了很多样板,但是当我从 Okta 管理应用程序发送应用程序嵌入链接时,我收到 400 响应。通过调试看来

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestResolver.resolve(request);
        if (authenticationRequest == null) {
            filterChain.doFilter(request, response);..}
Run Code Online (Sandbox Code Playgroud)

无法解析传入的请求,但我不确定它是否相关。我的 yml 配置:

 security:
    saml2:
      relyingparty:
        registration:
          okta:
            identityprovider:
              entity-id: http://www.okta.com/exk1juy5xrR5BsW44697
              verification.credentials:
                - certificate-location: "classpath:saml/okta.cert"
              singlesignon.url: https://trial-8410773.okta.com/app/trial-8410773_templatemanager_2/exk1juy5xrR5BsW44697/sso/saml
              singlesignon.sign-request: false
              assertingparty.metadata-uri: https://trial-8410773.okta.com/app/trial-8410773_templatemanager_2/exk1juy5xrR5BsW44697/sso/saml/metadata
Run Code Online (Sandbox Code Playgroud)

我的 Okta 配置:

GENERAL
Single Sign On URLhttp://localhost:8080/api/v1/saml2/SSO
Requestable SSO URLsURLIndex
http://localhost:8080/api/v1/saml2/SSO0Recipient URLhttp://localhost:8080/api/v1/saml2/SSODestination URLhttp://localhost:8080/api/v1/saml2/SSOAudience Restrictionhttp://localhost:8080/saml/metadata
Run Code Online (Sandbox Code Playgroud)

我还提供了 saml 身份验证的端点:

@RequestMapping(SsoAuthenticationController.BASE_NAME)
public interface SsoAuthenticationController {

    final String BASE_NAME = "/v1/saml2/SSO";

    @GetMapping("/")
    public ResponseEntity<HttpStatus> index( Saml2AuthenticatedPrincipal principal) ;
}
Run Code Online (Sandbox Code Playgroud)

实际安全配置:

http.cors()
        .and()
        .csrf()
        .disable()
        .authorizeRequests()
        .antMatchers(SECURITY_WHITELIST)
        .permitAll()
        .anyRequest()
        .authenticated()
        /*.and()
        .httpBasic()
        .and()
        .exceptionHandling()
        .authenticationEntryPoint(authenticationEntryPoint).and().sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)*/
        .and()
        .saml2Login(Customizer.withDefaults());
Run Code Online (Sandbox Code Playgroud)

这是 Google Chrome 的 Saml 拦截器日志: https ://pastebin.com/Be3NZe5B

有任何想法吗?

Mat*_*ble 5

我最近使用 Okta 创建了一个 Spring Boot 3 + SAML 示例。希望这些说明有所帮助。

\n

使用start.spring.io创建 Spring Boot 应用程序。选择以下选项:

\n
    \n
  • 项目:摇篮
  • \n
  • Spring Boot:3.0.0(快照)
  • \n
  • 依赖项:Spring WebSpring SecurityThymeleaf
  • \n
\n

添加src/main/java/com/example/demo/HomeController.java以填充经过身份验证的用户的信息。

\n
package com.example.demo;\n\nimport org.springframework.security.core.annotation.AuthenticationPrincipal;\nimport org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.ui.Model;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@Controller\npublic class HomeController {\n\n    @RequestMapping("/")\n    public String home(@AuthenticationPrincipal Saml2AuthenticatedPrincipal principal, Model model) {\n        model.addAttribute("name", principal.getName());\n        model.addAttribute("emailAddress", principal.getFirstAttribute("email"));\n        model.addAttribute("userAttributes", principal.getAttributes());\n        return "home";\n    }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n

创建一个src/main/resources/templates/home.html文件来呈现用户的信息。

\n
<!DOCTYPE html>\n<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"\n      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity6">\n<head>\n    <title>Spring Boot and SAML</title>\n    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>\n</head>\n<body>\n\n<h1>Welcome</h1>\n<p>You are successfully logged in as <span sec:authentication="name"></span></p>\n<p>Your email address is <span th:text="${emailAddress}"></span>.</p>\n<p>Your authorities are <span sec:authentication="authorities"></span>.</p>\n<h2>All Your Attributes</h2>\n<dl th:each="userAttribute : ${userAttributes}">\n    <dt th:text="${userAttribute.key}"></dt>\n    <dd th:text="${userAttribute.value}"></dd>\n</dl>\n\n<form th:action="@{/logout}" method="post">\n    <button id="logout" type="submit">Logout</button>\n</form>\n\n</body>\n</html>\n
Run Code Online (Sandbox Code Playgroud)\n

创建一个src/main/resources/application.yml文件来包含您的元数据 URI。

\n
spring:\n  security:\n    saml2:\n      relyingparty:\n        registration:\n            assertingparty:\n              metadata-uri: <your-metadata-uri>\n
Run Code Online (Sandbox Code Playgroud)\n

然后,更改build.gradle为使用thymeleaf-extras-springsecurity6而不是thymeleaf-extras-springsecurity5添加 Spring Security SAML 的依赖项:

\n
implementation \'org.thymeleaf.extras:thymeleaf-extras-springsecurity6\'\nimplementation \'org.springframework.security:spring-security-saml2-service-provider\'\n
Run Code Online (Sandbox Code Playgroud)\n

要从 Okta 获取元数据 URI,请登录您的帐户并转到应用程序>创建应用程序集成。选择SAML 2.0并单击下一步。将您的应用程序命名为类似的名称Spring Boot SAML,然后单击Next

\n

使用以下设置:

\n
    \n
  • 单点登录 URL:http://localhost:8080/login/saml2/sso/okta
  • \n
  • 使用此作为收件人 URL 和目标 URL:\xe2\x9c\x85(默认值)
  • \n
  • 受众 URI:http://localhost:8080/saml2/service-provider-metadata/okta
  • \n
\n

然后单击“下一步”。选择以下选项:

\n
    \n
  • 我是 Okta 客户,正在添加内部应用程序
  • \n
  • 这是我们创建的内部应用程序
  • \n
\n

选择完成

\n

Okta 将创建您的应用程序,并且您将被重定向到其“登录”选项卡。向下滚动到SAML 签名证书,然后转至SHA-2 >操作>查看 IdP 元数据。您可以右键单击并复制此菜单项的链接或打开其 URL。将生成的链接复制到剪贴板。它应该类似于以下内容:

\n
implementation \'org.thymeleaf.extras:thymeleaf-extras-springsecurity6\'\nimplementation \'org.springframework.security:spring-security-saml2-service-provider\'\n
Run Code Online (Sandbox Code Playgroud)\n

转到应用程序的“分配”选项卡并将访问权限分配给“所有人”组。

\n

将您的元数据 URI 粘贴到您的application.yml文件中。./gradlew bootRun使用您最喜欢的浏览器启动并打开应用程序http://localhost:8080。您应该被重定向到登录。

\n

  • 我发现发生这种情况是因为首先发生了对网站图标的请求。我使用 Firefox 时并没有发生这种情况。有关更多信息,请参阅 https://github.com/spring-projects/spring-security/issues/11657。我今天还发表了一篇博客文章,可能会有所帮助:https://developer.okta.com/blog/2022/08/05/spring-boot-saml (2认同)
  • 没有理由保持会话无状态。如果您在 Spring Boot 中的服务器端进行所有身份验证,则可以使用良好的老式会话 cookie 来保持与客户端的会话。这就是我们在 JHipster (https://jhipster.tech) 中所做的,因为它是最安全的。如果要扩展,请使用 Redis。https://developer.okta.com/blog/2020/12/14/spring-session-redis (2认同)