当前位置: 首页 > 知识库问答 >
问题:

从经过SAML验证的UI验证AJAX API调用

穆旭尧
2023-03-14

我们的申请有两个部分。

  • 在Java8中编写的后端,它使用泽西2.0公开了不同的RESTendpoint。
  • 使用React和其他节点模块构建的单页应用程序UI。

Web界面使用Okta支持的SAML2.0身份验证作为身份提供者。后端创建HTTP会话并在cookie中发送JSESSIONID。

现在,UI调用其余endpoint来显示数据。我们需要在RESTAPI中添加一个身份验证层,我在这里问了另外一个问题,即使用Okta对RESTendpoint和UI进行身份验证。

这里我的问题是,我可以通过什么从UI传递给这些API调用作为身份验证的手段,因为UI确实经过身份验证,HTTP会话仍然有效。因此,我不需要创建一个单独的OAuth 2.0令牌,将其传递给UI,以便UI可以将其传递回后端。OAuth2.0流对于使用RESTendpoint的外部客户机是有意义的。

更新1

这是我的securityContext的摘录。定义两种身份验证方案的xml:

<!-- Authenticating REST APIs -->
<security:http pattern="/rest/**" use-expressions="false">
    <security:intercept-url pattern="/nltools/**" access="IS_AUTHENTICATED_FULLY" />
    <security:custom-filter before="BASIC_AUTH_FILTER" ref="authValidationFilter" />
    <security:http-basic/>
</security:http>

<!-- SAML processing endpoints -->
<security:http pattern="/saml/**" entry-point-ref="samlEntryPoint">
    <security:custom-filter before="FIRST" ref="metadataGeneratorFilter" />
    <security:custom-filter before="CSRF_FILTER" ref="samlFilter" />
    <security:custom-filter after="BASIC_AUTH_FILTER" ref="samlFilter" />
</security:http>

<!-- Secured pages with SAML as entry point -->
<security:http entry-point-ref="samlEntryPoint" use-expressions="false">
    <security:csrf />
    <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
    <security:custom-filter before="FIRST" ref="metadataGeneratorFilter" />
</security:http>

<security:authentication-manager alias="authenticationManager">
    <security:authentication-provider ref="httpBasicAuthenticationProvider" />
    <!-- Register authentication manager for SAML provider -->
    <security:authentication-provider ref="samlAuthenticationProvider"/>
    <!-- Register authentication manager for administration UI --> 
    <security:authentication-provider>
        <security:user-service id="adminInterfaceService">
            <security:user name="admin" password="admin" authorities="ROLE_ADMIN"/>
        </security:user-service>
    </security:authentication-provider>
</security:authentication-manager> 

我不确定我如何执行SecurityContextPeristengFilter。我应该覆盖并为我的/rest/**模式添加其中一个过滤器吗?

更新2

下面是调用后端的JS代码(React):

  return Promise.resolve().then(() => {
      return request.post('/rest/v1/projects')
       .send(data)
       .then((success) => {
          console.log('success!', success);
          var projectName = success.body.name;
          var projectId = success.body.id;
          
          self.props.dispatch( projectActions.addNewProject(
            projectId,
            projectName
          ));
        
          self.props.dispatch( appActions.displayGoodRequestMessage( projectName + " Saved") ); 
          self.props.dispatch( projectActions.fetchProject( projectId ) ); 
          self.props.router.push('/projects');

      }

现在JS代码可以选择发送与这个域相关的所有cookie,这样后端就可以获得JSESSION ID cookie,然而,JS没有这样做,我认为这样做是不对的。

另一方面,如果我执行https://mydomain/rest/v1/projects在浏览器中,只要我登录,我就会得到结果,因为这次当我的筛选器检查有效的HTTP会话时,它可以通过请求从请求中获取会话。getSession(false),但当JS调用API时,情况并非如此。它变成了一个完全不同的用户代理。

更新3

根据@Vladimír Schäfer的建议,我可以稍微更改上面的JS代码,以的形式发送cookies。withCredentials()

  return Promise.resolve().then(() => {
      return request.post('/rest/v1/projects')
       .withCredentials()
       .send(data)
       .then((success) => {
          console.log('success!', success);
          var projectName = success.body.name;
          var projectId = success.body.id;
          
          self.props.dispatch( projectActions.addNewProject(
            projectId,
            projectName
          ));
        
          self.props.dispatch( appActions.displayGoodRequestMessage( projectName + " Saved") ); 
          self.props.dispatch( projectActions.fetchProject( projectId ) ); 
          self.props.router.push('/projects');

      }

共有1个答案

杜君浩
2023-03-14

只要REST API是前端使用Spring Security进行身份验证的同一应用程序的一部分,它就可以访问JSESSIONID,从而访问Spring Security的上下文,其中包含关于已验证用户的所有信息。因此,不需要任何额外的身份验证机制。

如果在处理Jersey调用时执行filterSecurityContextPersistenceFilter,则可以使用以下方法访问安全上下文:

SecurityContextHolder.getContext().getAuthentication();

SecurityContextPeristextFilter使用其配置的存储库来获取身份验证对象并将其存储在SecurityContextHolder中。看看它默认使用的HttpContextRepository。在那里,您会发现安全上下文存储在密钥SPRING_SECURITY_CONTEXT下的Http会话,因此您也可以直接获取它。

当然,您也可以使用Spring Security性在REST API上强制执行身份验证和授权,就像在前端所做的那样——然后一切都将为您处理。

 类似资料:
  • 我知道SAML是如何用于单点登录(SSO)的。也就是说,从SP重定向到IDP,并从SAML响应/断言获取用户身份。 我的问题是-SAML 2.0规范是否定义了如何将用户名和密码作为SAML请求xml的一部分进行身份验证?请注意,我不是在谈论单点登录,只是想要用户名/密码的身份验证。 谢谢,

  • 我试图遵循以下规范来验证SAML响应的签名:https://www.w3.org/tr/xmldsig-core/#sec-pkcs1 下面是我的工作流程:我得到SAML响应。我去掉签名信封,我把它规范化,我检查摘要,然后我检查签名。我能够成功地计算转换的SAML响应的SHA1摘要,并对其进行验证。然而,RSA-SHA1签名检查仍然无法实现。 SAML响应包含签名方法算法:http://www.w

  • 我应该在Jupyter中实现SAML身份验证(Okta)。我试过搜索,但什么也没找到。也许有人知道答案。谢谢你的帮助。

  • 接口说明 验证验证码 如需调用,请访问 开发者文档 来查看详细的接口使用说明 该接口仅开放给已获取SDK的开发者 如开启https功能,请求地址的协议应改为https,如:https://www.example.com/wish3dearth/api/access/v1.0.0/getLicenseInfo API地址 GET /authcenter/api/verify/v1.0.0/check

  • 我有一个h:inputText、h:selectonemenu和commandbuton。Inputtext是必填字段,我已将其定义为immediate=“true”。然后,当我单击按钮时,我想将selectonemenu的当前值传递给托管bean。但它的passig为空。如何管理此验证,以便它允许我在托管bean中获取selectOneMenu的值。。 我的代码是...

  • 我尝试了很多解决方案,但都是徒劳的。这就是我按照https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf的指导方针所做的: > 台阶 对auth请求进行放气,然后对其进行base64编码,最后对其进行Url编码。我们称之为AR Url编码RelayState。我们称之为RS Url编码签名算法字符串。我们称之为S