java - 无法从 ADFS 服务器获取 SAML 响应

标签 java spring saml adfs

我们有 ADFS 服务器(Windows Server 2012 R2)。 需要在自定义应用程序中添加授权(lib spring-security-saml2-core)。

身份验证步骤:

1) 创建 SAML AuthRequest 并发送到 ADFS 服务器

2)用户自动重定向到服务器的登录页面,输入正确的凭据

3) 服务器没有响应。日志中的错误:

The Federation Service encountered an error while processing the SAML authentication request. 

附加数据 异常详细信息:

Microsoft.IdentityModel.Protocols.XmlSignature.SignatureVerificationFailedException: ID4037: The key needed to verify the signature could not be resolved from the following security key identifier 'SecurityKeyIdentifier
    (
    IsReadOnly = False,
    Count = 1,
    Clause[0] = Microsoft.IdentityServer.Tokens.MSISSecurityKeyIdentifierClause
    )
'. Ensure that the SecurityTokenResolver is populated with the required key.
   at Microsoft.IdentityModel.Protocols.XmlSignature.EnvelopedSignatureReader.ResolveSigningCredentials()
   at Microsoft.IdentityModel.Protocols.XmlSignature.EnvelopedSignatureReader.OnEndOfRootElement()
   at Microsoft.IdentityModel.Protocols.XmlSignature.EnvelopedSignatureReader.Read()
   at System.Xml.XmlReader.ReadEndElement()
   at Microsoft.IdentityServer.Protocols.Saml.SamlProtocolSerializer.ReadAuthnRequest(XmlReader reader)
   at Microsoft.IdentityServer.Protocols.Saml.HttpSamlBindingSerializer.ReadProtocolMessage(String encodedSamlMessage)
   at Microsoft.IdentityServer.Protocols.Saml.Contract.SamlContractUtility.CreateSamlMessage(MSISSamlBindingMessage message)
   at Microsoft.IdentityServer.Web.Protocols.Saml.SamlProtocolManager.Issue(HttpSamlRequestMessage httpSamlRequestMessage, SecurityTokenElement onBehalfOf, String sessionState, String relayState, String& newSamlSession, String& samlpAuthenticationProvider, Boolean isUrlTranslationNeeded, WrappedHttpListenerContext context, Boolean isKmsiRequested)

有人可以帮忙解决这个错误吗? 如何获得回复?

我们使用这篇文章来配置证书和jks文件:https://docs.microfocus.com/SM/9.61/Hybrid/Content/security/tasks/configure_saml_setup_relationship_between_idm_adfs.htm

安全 XML:

   <!-- ADFS filter -->
   <bean id="adfsAuthenticationProcessingFilter"
      class="com.webapp.filter.ADFSAuthenticationProcessingFilter">
    <property name="authenticationManager" ref="samlAuthenticationManager"/>
    <property name="authenticationSuccessHandler" ref="logAuthenticationSuccessHandler"/>
    <property name="authenticationFailureHandler" ref="authenticationFailureHandler"/>
    <property name="sessionAuthenticationStrategy" ref="sessionFixationProtectionStrategy"/>
    <property name="SAMLProcessor" ref="processor"/>
    <property name="contextProvider" ref="contextProvider"/>
    <property name="userManager" ref="userManager"/>
</bean>

<!-- Filter automatically generates default SP metadata -->
<bean id="metadataGeneratorFilter"
      class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
    <constructor-arg>
        <bean class="org.springframework.security.saml.metadata.MetadataGenerator">
            <property name="entityId"
                      value="http://{ADFS server}/adfs/services/trust"/>
            <property name="requestSigned" value="false"/>
            <property name="extendedMetadata">
                <bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
                    <property name="signMetadata" value="false"/>
                    <property name="idpDiscoveryEnabled" value="false"/>
                </bean>
            </property>
        </bean>
    </constructor-arg>
    <property name="manager" ref="metadata"/>
</bean>


<bean id="metadata" class="org.springframework.security.saml.metadata.MetadataManager">
    <constructor-arg>
        <list>
            <bean class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate">
                <constructor-arg>
                    <bean class="org.opensaml.saml2.metadata.provider.FilesystemMetadataProvider">
                        <constructor-arg name="metadata" type="java.io.File"
                                         value="/WEB-INF/saml/sp_metadata.xml"/>
                        <property name="parserPool" ref="parserPool"/>
                    </bean>
                </constructor-arg>
                <constructor-arg>
                    <bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
                        <property name="local" value="true"/>
                        <property name="securityProfile" value="metaiop"/>
                        <property name="sslSecurityProfile" value="metaiop"/>
                        <property name="signMetadata" value="true"/>
                        <property name="signingKey" value="keyName"/>
                        <property name="encryptionKey" value="keyName"/>
                        <property name="requireArtifactResolveSigned" value="true"/>
                        <property name="requireLogoutRequestSigned" value="true"/>
                        <property name="requireLogoutResponseSigned" value="true"/>
                        <property name="idpDiscoveryEnabled" value="false"/>
                    </bean>
                </constructor-arg>
                <property name="requireValidMetadata" value="false"/>
            </bean>
            <bean class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate">
                <constructor-arg>
                    <bean class="org.opensaml.saml2.metadata.provider.FilesystemMetadataProvider">
                        <constructor-arg name="metadata" type="java.io.File"
                                         value="/WEB-INF/saml/ip_metadata.xml"/>
                        <property name="parserPool" ref="parserPool"/>
                    </bean>
                </constructor-arg>
                <constructor-arg>
                    <bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
                        <property name="local" value="false"/>
                        <property name="securityProfile" value="metaiop"/>
                        <property name="sslSecurityProfile" value="metaiop"/>
                        <property name="signMetadata" value="true"/>
                        <property name="signingKey" value="keyName"/>
                        <property name="encryptionKey" value="keyName"/>
                        <property name="requireArtifactResolveSigned" value="false"/>
                        <property name="requireLogoutRequestSigned" value="false"/>
                        <property name="requireLogoutResponseSigned" value="false"/>
                        <property name="idpDiscoveryEnabled" value="false"/>
                    </bean>
                </constructor-arg>
                <property name="requireValidMetadata" value="false"/>
            </bean>

        </list>
    </constructor-arg>
    <property name="keyManager" ref="keyManager"/>
    <property name="TLSConfigurer">
        <bean class="org.springframework.security.saml.trust.httpclient.TLSProtocolConfigurer">
            <property name="keyManager" ref="keyManager"/>
            <property name="trustedKeys">
                <set>

                </set>
            </property>
        </bean>
    </property>
    <property name="hostedSPName"
              value="http://{ADFS server}/adfs/services/trust"/>
    <property name="defaultIDP"
              value="http://{ADFS server}/adfs/services/trust"/>
</bean>

<bean id="logAuthenticationSuccessHandler" parent="txProxyTemplate">
    <property name="target">
        <bean class="com.webapp.security.login.LogAuthenticationSuccessHandler">
            <property name="defaultTargetUrl" value="/startPage.htm"/>
            <property name="requestCache" ref="savedRequestCache"/>
            <property name="userDao" ref="userDao"/>
            <property name="attemptsManager" ref="authenticationAttemptsManager"/>
            <property name="userManager" ref="userManager"/>
        </bean>
    </property>
    <property name="transactionAttributes">
        <props>
            <prop key="onAuthenticationSuccess">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

<!--  SAML 2.0 -->
<!-- Secured pages with SAML as entry point -->

<sec:http pattern="/saml/**" entry-point-ref="samlEntryPoint">
    <sec:custom-filter before="FIRST" ref="metadataGeneratorFilter"/>
    <sec:custom-filter after="BASIC_AUTH_FILTER" ref="samlFilter"/>
</sec:http>

<sec:http entry-point-ref="samlEntryPoint" use-expressions="false" pattern="/">
    <sec:csrf/>
    <sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY"/>
    <sec:custom-filter before="FIRST" ref="metadataGeneratorFilter"/>
    <sec:custom-filter after="BASIC_AUTH_FILTER" ref="samlFilter"/>
</sec:http>

<!-- Filters for processing of SAML messages -->
<bean id="samlFilter" class="org.springframework.security.web.FilterChainProxy">
    <sec:filter-chain-map request-matcher="ant">
        <sec:filter-chain pattern="/saml/login" filters="samlEntryPoint"/>
        <sec:filter-chain pattern="/saml/metadata/**" filters="metadataDisplayFilter"/>
        <sec:filter-chain pattern="/saml/SSO" filters="samlWebSSOProcessingFilter"/>
        <sec:filter-chain pattern="/saml/SSOHoK/**" filters="samlWebSSOHoKProcessingFilter"/>
        <sec:filter-chain pattern="/saml/SingleLogout/**" filters="samlLogoutProcessingFilter"/>
    </sec:filter-chain-map>
</bean>

<!-- Handler deciding where to redirect user after successful login -->
<bean id="successRedirectHandler"
      class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
    <property name="defaultTargetUrl" value="/"/>
</bean>

<!-- Handler deciding where to redirect user after failed login -->
<bean id="failureRedirectHandler"
      class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
    <property name="useForward" value="true"/>
    <property name="defaultFailureUrl" value="/error/403.jsf"/>
</bean>

<!-- Handler for successful logout -->
<bean id="successLogoutHandler"
      class="org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler">
    <property name="defaultTargetUrl" value="/logout"/>
</bean>

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

<!-- Logger for SAML messages and events -->
<bean id="samlLogger" class="org.springframework.security.saml.log.SAMLDefaultLogger"/>

<bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
    <constructor-arg value="/WEB-INF/saml/samlKeystore.jks"/>

    <constructor-arg type="java.lang.String" value="123456"/>
    <constructor-arg>
        <map>
            <entry key="keyName" value="1234567"/>
        </map>
    </constructor-arg>
    <constructor-arg type="java.lang.String" value="keyName"/>
</bean>

<!-- Entry point to initialize authentication, default values taken from properties file -->
<bean id="samlEntryPoint" class="org.springframework.security.saml.SAMLEntryPoint">
    <property name="defaultProfileOptions">
        <bean class="org.springframework.security.saml.websso.WebSSOProfileOptions">
            <property name="includeScoping" value="false"/>
            <property name="nameID"
                      value="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"/>
            <property name="binding" value="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"/>
            <property name="allowCreate" value="true"/>
            <property name="assertionConsumerIndex" value="0"/>
            <property name="passive" value="false"/>
            <property name="relayState"
                      value="https://{application URL}/saml/SSO/login.htm"/>
            <property name="forceAuthN" value="true"/>
            <property name="authnContexts">
                <list>
                    <value>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
                    </value>
                </list>
            </property>
        </bean>
    </property>
    <property name="metadata" ref="metadata"/>
    <property name="samlLogger" ref="samlLogger"/>
    <property name="webSSOprofile" ref="webSSOprofile"/>
    <property name="contextProvider" ref="contextProvider"/>
    <property name="filterProcessesUrl" value="/login.htm"/>
</bean>

<!-- The filter is waiting for connections on URL suffixed with filterSuffix and presents SP metadata there -->
<bean id="metadataDisplayFilter"
      class="org.springframework.security.saml.metadata.MetadataDisplayFilter">
    <property name="manager" ref="metadata"/>
    <property name="contextProvider" ref="contextProvider"/>
    <property name="keyManager" ref="keyManager"/>
</bean>

<!-- SAML Authentication Provider responsible for validating of received SAML messages -->
<bean id="samlAuthenticationProvider"
      class="org.springframework.security.saml.SAMLAuthenticationProvider">

    <property name="userDetails" ref="userDetails"/>
    <property name="consumer" ref="webSSOprofileConsumer"/>
    <property name="hokConsumer" ref="hokWebSSOprofileConsumer"/>
    <property name="samlLogger" ref="samlLogger"/>
    <property name="forcePrincipalAsString" value="false"/>
</bean>

<bean id="userDetails" parent="txProxyTemplate">
    <property name="target">
        <bean class="com.webapp.security.SAMLUserDetails">
            <property name="userDao" ref="userDao"/>
        </bean>
    </property>
    <property name="transactionAttributes">
        <props>
            <prop key="load*">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

<!-- Provider of default SAML Context -->
<bean id="contextProvider"
      class="org.springframework.security.saml.context.SAMLContextProviderImpl">
    <property name="keyManager" ref="keyManager"/>
    <property name="metadata" ref="metadata"/>
</bean>

<!-- Processing filter for WebSSO profile messages -->
<bean id="samlWebSSOProcessingFilter"
      class="org.springframework.security.saml.SAMLProcessingFilter">
    <property name="authenticationManager" ref="samlAuthenticationManager"/>
    <property name="authenticationSuccessHandler" ref="successRedirectHandler"/>
    <property name="authenticationFailureHandler" ref="failureRedirectHandler"/>
    <property name="contextProvider" ref="contextProvider"/>
    <property name="SAMLProcessor" ref="processor"/>
</bean>

<!-- Processing filter for WebSSO Holder-of-Key profile -->
<bean id="samlWebSSOHoKProcessingFilter"
      class="org.springframework.security.saml.SAMLWebSSOHoKProcessingFilter">
    <property name="authenticationManager" ref="samlAuthenticationManager"/>
    <property name="authenticationSuccessHandler" ref="successRedirectHandler"/>
    <property name="authenticationFailureHandler" ref="failureRedirectHandler"/>
    <property name="contextProvider" ref="contextProvider"/>
    <property name="SAMLProcessor" ref="processor"/>
</bean>

<!-- Logout handler terminating local session -->
<bean id="logoutHandler"
      class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler">
    <property name="invalidateHttpSession" value="false"/>
</bean>

<!--Filter processing incoming logout messages -->
<!--First argument determines URL user will be redirected to after successful global logout -->
<bean id="samlLogoutProcessingFilter"
      class="org.springframework.security.saml.SAMLLogoutProcessingFilter">
    <constructor-arg index="0" ref="successLogoutHandler"/>
    <constructor-arg index="1" ref="logoutHandler"/>
    <property name="SAMLProcessor" ref="samlProcessor"/>
    <property name="contextProvider" ref="contextProvider"/>
    <property name="logoutProfile" ref="logoutProfile"/>
    <property name="samlLogger" ref="samlLogger"/>
</bean>

<bean id="logoutProfile"
      class="org.springframework.security.saml.websso.SingleLogoutProfileImpl">
    <property name="metadata" ref="metadata"/>
    <property name="processor" ref="samlProcessor"/>
</bean>

<!-- Class loading incoming SAML messages from httpRequest stream -->
<bean id="processor" class="org.springframework.security.saml.processor.SAMLProcessorImpl">
    <constructor-arg>
        <list>
            <ref bean="redirectBinding"/>
            <ref bean="postBinding"/>
            <ref bean="artifactBinding"/>
            <ref bean="soapBinding"/>
            <ref bean="paosBinding"/>
        </list>
    </constructor-arg>
</bean>

<!-- Initialization of OpenSAML library-->
<bean class="org.springframework.security.saml.SAMLBootstrap"/>

<!-- SAML 2.0 WebSSO Assertion Consumer -->
<bean id="webSSOprofileConsumer"
      class="org.springframework.security.saml.websso.WebSSOProfileConsumerImpl">
    <property name="metadata" ref="metadata"/>
    <property name="processor" ref="samlProcessor"/>

    <property name="responseSkew" value="600"/>
    <property name="maxAuthenticationAge" value="7200"/>
</bean>

<!-- SAML 2.0 Holder-of-Key WebSSO Assertion Consumer -->
<bean id="hokWebSSOprofileConsumer"
      class="org.springframework.security.saml.websso.WebSSOProfileConsumerHoKImpl">
    <property name="metadata" ref="metadata"/>
    <property name="processor" ref="samlProcessor"/>
</bean>

<!-- SAML 2.0 Web SSO profile -->
<bean id="webSSOprofile" class="com.webapp.filter.CustomWebSSOProfileImpl">
    <property name="metadata" ref="metadata"/>
    <property name="processor" ref="samlProcessor"/>
    <!-- property name="metadataIssuerUrl" value="https://{ADFS server}/FederationMetadata/2007-06/FederationMetadata.xml" / -->
</bean>

<!-- SAML 2.0 Holder-of-Key Web SSO profile -->
<bean id="hokWebSSOProfile"
      class="org.springframework.security.saml.websso.WebSSOProfileConsumerHoKImpl">
    <property name="metadata" ref="metadata"/>
    <property name="processor" ref="samlProcessor"/>
</bean>

<!-- SAML 2.0 ECP profile -->
<bean id="ecpprofile" class="org.springframework.security.saml.websso.WebSSOProfileECPImpl">
    <property name="metadata" ref="metadata"/>
    <property name="processor" ref="samlProcessor"/>
</bean>

<!-- SAML 2.0 Logout Profile -->
<bean id="logoutprofile"
      class="org.springframework.security.saml.websso.SingleLogoutProfileImpl">
    <property name="metadata" ref="metadata"/>
    <property name="processor" ref="samlProcessor"/>
    <property name="responseSkew" value="600"/> 
</bean>

<!-- Bindings, encoders and decoders used for creating and parsing messages -->
<bean id="postBinding" class="org.springframework.security.saml.processor.HTTPPostBinding">
    <constructor-arg ref="parserPool"/>
    <constructor-arg ref="velocityEngine"/>
</bean>

<bean id="redirectBinding"
      class="org.springframework.security.saml.processor.HTTPRedirectDeflateBinding">
    <constructor-arg ref="parserPool"/>
</bean>

<bean id="artifactBinding"
      class="org.springframework.security.saml.processor.HTTPArtifactBinding">
    <constructor-arg ref="parserPool"/>
    <constructor-arg ref="velocityEngine"/>
    <constructor-arg>
        <bean class="org.springframework.security.saml.websso.ArtifactResolutionProfileImpl">
            <constructor-arg>
                <bean class="org.apache.commons.httpclient.HttpClient">
                    <constructor-arg>
                        <bean class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager"/>
                    </constructor-arg>
                </bean>
            </constructor-arg>
            <property name="processor" ref="samlProcessor"/>
            <property name="metadata" ref="metadata"/>
        </bean>
    </constructor-arg>
</bean>

<bean id="samlProcessor" class="org.springframework.security.saml.processor.SAMLProcessorImpl">
    <constructor-arg ref="httpPostBinding"/>
</bean>

<bean id="httpRedirectBinding"
      class="org.springframework.security.saml.processor.HTTPRedirectDeflateBinding">
    <constructor-arg ref="parserPool"/>
</bean>

<bean id="httpPostBinding" class="org.springframework.security.saml.processor.HTTPPostBinding">
    <constructor-arg ref="parserPool"/>
    <constructor-arg ref="velocityEngine"/>
</bean>

<bean id="xmlHttpPostBinding"
      class="org.springframework.security.saml.processor.HTTPPostBinding">
    <constructor-arg ref="parserPool"/>
    <constructor-arg>
        <bean class="org.opensaml.saml1.binding.decoding.HTTPPostDecoder">
            <constructor-arg ref="parserPool"/>
        </bean>
    </constructor-arg>
    <constructor-arg>
        <bean class="com.webapp.filter.HttpRedirectDeflateAsHttpPostEncoder"/>
    </constructor-arg>
</bean>

<bean id="soapBinding" class="org.springframework.security.saml.processor.HTTPSOAP11Binding">
    <constructor-arg ref="parserPool"/>
</bean>

<bean id="paosBinding" class="org.springframework.security.saml.processor.HTTPPAOS11Binding">
    <constructor-arg ref="parserPool"/>
</bean>

<!-- Initialization of OpenSAML library-->
<bean class="org.springframework.security.saml.SAMLBootstrap"/>

<!-- Initialization of the velocity engine -->
<bean id="velocityEngine" class="org.springframework.security.saml.util.VelocityFactory"
      factory-method="getEngine"/>

<bean id="parserPool" class="org.opensaml.xml.parse.StaticBasicParserPool"
      init-method="initialize"/>

<bean id="parserPoolHolder" class="org.springframework.security.saml.parser.ParserPoolHolder"/>

SAML 身份验证请求:

  <!-- ADFS filter -->
  <?xml version="1.0" encoding="UTF-8"?>
  <saml2p:AuthnRequest
AssertionConsumerServiceURL="https://{application URL}/saml/SSO/login.htm"
Destination="https://{ADFS server}/adfs/ls/" ForceAuthn="true"
ID="ID" IsPassive="false" IssueInstant="2019-08-28T07:36:16.121Z"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0"
xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol">
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://{ADFS server URL}/adfs/services/trust</saml2:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
        <ds:Reference URI="#ID">
            <ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
            <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <ds:DigestValue>pA3hIQrobfvJmjpV76SuMhfD5Ig=</ds:DigestValue>
        </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>...==</ds:SignatureValue>
    <ds:KeyInfo>
        <ds:X509Data>
            <ds:X509Certificate>...</ds:X509Certificate>
        </ds:X509Data>
    </ds:KeyInfo>
</ds:Signature><saml2p:NameIDPolicy AllowCreate="true"
    Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"/>
<saml2p:RequestedAuthnContext Comparison="exact">
    <saml2:AuthnContextClassRef xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>
</saml2p:RequestedAuthnContext>

最佳答案

我最近参与了一个项目,我们将 KeyCloak 设置为 ADFS IdP 的 SP。

只有在设置以下设置时,我们才能正确处理 SAML 请求:

<小时/>

IdP 网址:${IDP_URL}/adfs/ls/

NameID 策略格式:持久

WantAuthnRequestsSigned:true

WantAssertionsSigned:true

签名算法:RSA_SHA256

SAMLSignatureKeyName:CERT_SUBJECT

<小时/>

除了更新我们这边(作为 SP)的 NameID 政策之外,我们还必须在 IdP 方面进行自定义设置,以确保 NameID 以持久格式发回。

我从您的身份验证请求中看到,NameID 策略当前设置为 emailAddress

关于java - 无法从 ADFS 服务器获取 SAML 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57688445/

相关文章:

certificate - SAML 签名证书 - CA 签名与自签名

java - 从 Java 的 ADFS SAML .NET 服务器获取请求 token

java - Android Studio 错误 : Not annotated parameter overrides @NonNull parameter 的含义

java - 如何在 Java 中打开和操作 Word 文档/模板?

java - 仅使用 AWS 免费套餐的 Spring Boot 项目

java - Spring Batch 无法打开 JPA EntityManager 进行事务;嵌套异常是 java.lang.IllegalStateException : Transaction already active

java - JVM 会垃圾收集内存中的孤立周期吗?

java - 从多个表中嵌套选择的性能

java - 过滤时很漂亮的 JSON 导入,但返回整批数据时则不然 + ID 中丑陋的括号

java - 如何使用 opensaml v3?几乎没有文档,v2 已停产