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

     2023-02-27     273

关键词:

【中文标题】从经过 SAML 验证的 UI 验证 AJAX API 调用【英文标题】:Authenticating AJAX API calls from the UI which is SAML authenticated 【发布时间】:2017-06-05 22:37:15 【问题描述】:

我们的应用程序有 2 个部分。

用 Java 8 编写的后端,使用 Jersey 2.0 公开不同的 REST 端点。 UI 是使用 React 和其他节点模块构建的单页应用程序。

Web 界面使用 Okta 支持的 SAML 2.0 身份验证作为身份提供者。后端创建 HTTP Session 并在 cookie 中发送 JSESSIONID。

现在 UI 调用 REST 端点来显示数据。我们需要在我们的 REST API 中添加一个身份验证层,我在 Authenticating rest endpoints and the UI using Okta 上提出了一个单独的问题。

我在这里的具体问题是我可以从 UI 传递什么作为对这些 API 调用的身份验证方式,因为 UI 确实经过身份验证并且 HTTP 会话仍然有效。因此,我不需要创建单独的 OAuth 2.0 令牌将其传递给 UI,以便 UI 可以将其传递回后端。 OAuth 2.0 流程对使用我们的 REST 端点的外部客户端有意义。

更新 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> 

我不确定如何执行 SecurityContextPersistenceFilter。我应该为我的/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 会话时,它可以从请求中获取会话使用request.getSession(false),尽管当 JS 调用 API 时情况并非如此。它变成了一个完全不同的用户代理。

更新 3

根据@Vladimír Schäfer 的建议,我可以稍微更改上面的 JS 代码以将 cookie 发送为 .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】:

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

如果您在处理 Jersey 呼叫时执行过滤器SecurityContextPersistenceFilter,您将能够使用以下方法访问安全上下文:

SecurityContextHolder.getContext().getAuthentication();

SecurityContextPersistenceFilter 使用其配置的存储库来获取 Authentication 对象并将其存储在 SecurityContextHolder 中。看看它默认使用的HttpContextRepository。在那里你会发现存储的安全上下文是密钥SPRING_SECURITY_CONTEXT下的HttpSession,所以你也可以直接获取它。

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

【讨论】:

我已经用我的 securityContext.xml 的摘录更新了我的问题。我不确定我是否理解您的意思是执行 SecurityContextPeristenceFilter。 我从您的问题中推测您没有使用 Spring Security 对您的 REST 进行身份验证。但你是。您的 REST 调用已经需要身份验证,您的前端将按原样发送 JSESSIONID,您无需再做任何事情 - 除非您想让您自己的应用程序之外的第 3 方访问 REST API(例如 OAuth发挥作用)。 感谢您迄今为止的意见。我再次使用调用 REST API 的 Javascript 代码摘录更新了我的问题。就您而言,将来当我想切换到 OAUTH2 时,我确实希望 REST 端点暴露在外面。 只需让 React 发送 cookie。这样做并没有错,这些 API 请求与浏览器在从一个页面切换到另一个页面时所做的正常调用没有什么不同,在这种情况下发送 cookie 会产生安全隐患。 谢谢。不过我还有一个问题。如果您注意到我添加了&lt;security:http-basic/&gt; 作为我的 REST API 调用的安全性。我添加了一个过滤器authValidationFilter 进行身份验证。但是,作为&lt;security:http-basic/&gt; 的一部分,我需要为AuthenticationManager 提供单独的AuthenticationProvider。我真的希望我的过滤器能够进行身份验证。现在如果我不给&lt;security:http-basic/&gt;,那么Spring 会抱怨它找不到入口点。怎么能解决呢?因为明天我想添加 OAuth 而我不想添加 /saml/** 过滤器链。

仅接受来自经过身份验证的用户的某些 ajax 请求

】仅接受来自经过身份验证的用户的某些ajax请求【英文标题】:Onlyacceptingcertainajaxrequestsfromauthenticatedusers【发布时间】:2010-09-0603:12:54【问题描述】:确保只接受经过身份验证的用户对某些页面的某些ajax调用的最佳做法是什么... 查看详情

如何创建 SAMLAuthenticationToken 并将其发送到 SAML 身份验证提供程序

】如何创建SAMLAuthenticationToken并将其发送到SAML身份验证提供程序【英文标题】:HowtocreatetheSAMLAuthenticationTokenandsendittotheSAMLauthenticationprovider【发布时间】:2015-08-2716:05:46【问题描述】:我已经在我的应用程序中配置了SAML扩展,并... 查看详情

使用 SAML 对 Spring Boot 应用程序进行身份验证的问题

】使用SAML对SpringBoot应用程序进行身份验证的问题【英文标题】:IssueusingSAMLforauthenticationwithspringbootapp【发布时间】:2018-04-1619:07:36【问题描述】:我目前正在阅读thisarticle,了解如何使用SpringBoot应用程序设置SAML。我按照所有步... 查看详情

使用基于 SAML 的基本身份验证进行身份验证?

】使用基于SAML的基本身份验证进行身份验证?【英文标题】:AuthenticateusingSAML-basedBasicAuthentication?【发布时间】:2015-08-1219:55:40【问题描述】:我有一个用例,其中Web应用程序需要让用户以两种不同的方式进行身份验证,但通过... 查看详情

saml2.0浅入深出《一》

...据格式,专门支持身份联合,使身份提供商(IdP)能够将经过身份验证的身份及其他属性无缝且安全的传递给服务提供商(SP)。服务提供商首先要和身份提供商建立信任,通过SAML协议传递认证信息要访问服务提供商的用户必须... 查看详情

我如何才能完全信任 SAML IDP?

...-2815:13:17【问题描述】:我的Web应用程序允许通过SAML身份验证进行SSO,我现在正在进行开发。这个想法是绕过我的应用程序的本地身份验证,并且一旦用户使用SAMLIDP进行身份验证,就会自动进行身份验证。我们将从提供商那里... 查看详情

基于 SAML 断言授权的 SAML2 身份验证

】基于SAML断言授权的SAML2身份验证【英文标题】:SAML2AuthenticationwithauthorizationbasedonSAMLassertions【发布时间】:2022-01-1703:21:12【问题描述】:我正在使用spring-security-saml2-service-provider针对SAMLIdP对我的SpringBootwebapp进行身份验证-这很... 查看详情

ASP.Net Core SAML 身份验证

】ASP.NetCoreSAML身份验证【英文标题】:ASP.NetCoreSAMLauthentication【发布时间】:2016-05-1911:00:33【问题描述】:我正在尝试将SAML2.0身份验证添加到ASP.NetCore解决方案。我找不到关于这个主题的任何文档,所以我不确定从哪里开始。那... 查看详情

不同的 SAML 令牌验证调用具体有啥作用?

】不同的SAML令牌验证调用具体有啥作用?【英文标题】:WhatdodifferentSAMLtokenvalidationcallsspecificallydo?不同的SAML令牌验证调用具体有什么作用?【发布时间】:2011-08-1708:10:35【问题描述】:我正在尝试验证由我们基于WIF的自定义STS... 查看详情

如何从 Instagram API 检索经过验证的用户? [关闭]

】如何从InstagramAPI检索经过验证的用户?[关闭]【英文标题】:HowCanIretrieveverifiedusersfromInstagramAPI?[closed]【发布时间】:2022-01-2304:47:28【问题描述】:如何从InstagramAPI获得经过验证的名人或用户?InstagramBasicDisplayAPI能否提供经过... 查看详情

基于 SAML 的 SSO 用于身份验证和 LDAP 用于授权 - Spring Boot Security

】基于SAML的SSO用于身份验证和LDAP用于授权-SpringBootSecurity【英文标题】:SAMLbasedSSOforAuthenticationandLDAPforauthorization-SpringBootSecurity【发布时间】:2020-09-2721:06:21【问题描述】:将Gsuite与CloudIdentity专业版结合使用a)将GSuite初始化为iDP... 查看详情

如何在不重置 tomcat 会话超时的情况下执行经过身份验证的 AJAX 请求?

】如何在不重置tomcat会话超时的情况下执行经过身份验证的AJAX请求?【英文标题】:HowdoIexecuteanauthenticatedAJAXrequestwithoutresettingthetomcat\'ssessiontimeout?【发布时间】:2011-06-1713:59:45【问题描述】:我有一个现有的GrailsWeb应用程序正... 查看详情

带有 Django 身份验证的 SAML

】带有Django身份验证的SAML【英文标题】:SAMLwithDjangoauthentication【发布时间】:2014-05-0507:03:41【问题描述】:我正在使用托管在AWS上的Django和nginx。我正在尝试使用他们的idp与一所大学集成以进行SAML身份验证。关于SO有很多过时... 查看详情

经过身份验证的服务不支持跨域 javascript 回调。通过 SSL 代理对 WCF 服务的 AJAX 查询

】经过身份验证的服务不支持跨域javascript回调。通过SSL代理对WCF服务的AJAX查询【英文标题】:Crossdomainjavascriptcallbackisnotsupportedinauthenticatedservices.AJAXquerytoWCFserviceviaSSLproxy【发布时间】:2013-11-2712:09:06【问题描述】:我有一个WCF/... 查看详情

如何验证 HTTP 重定向绑定的 SAML 签名

】如何验证HTTP重定向绑定的SAML签名【英文标题】:HowtoverifyaSAMLsignatureforHTTP-redirectbinding【发布时间】:2017-05-1821:51:17【问题描述】:我通过HTTP重定向接收SAML请求,绑定SAML请求的内容如下所示"SigAlg"=>"http://www.w3.org/2000/09/xmldsi... 查看详情

无法针对架构验证 SAML 2.0 断言

】无法针对架构验证SAML2.0断言【英文标题】:unabletovalidateSAML2.0assertionagainstschema【发布时间】:2015-06-2920:16:49【问题描述】:我正在使用SpringSAML,但在使用SAML断言时遇到问题(来自Wikipediaarticle的示例断言<saml:Assertionxmlns:saml=... 查看详情

java示例代码_在不重置tomcat'的情况下执行经过身份验证的AJAX请求;s会话超时

java示例代码_在不重置tomcat'的情况下执行经过身份验证的AJAX请求;s会话超时 查看详情

SAML 重新验证用户会话

】SAML重新验证用户会话【英文标题】:SAMLrevalidateusersession【发布时间】:2016-06-1413:04:10【问题描述】:我们正在使用spring-security和PingOne作为IdP来实施SAML。我们有一个问题,当用户使用SSO登录应用程序,然后在IdP上被禁用/删除... 查看详情