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

Spring Security SAML2使用谷歌办公套件作为Idp

荆炳
2023-03-14

我试图使用Spring Security(5.3.3. RELEASE)在Spring Boot应用程序中处理SAML2身份验证。Spring Boot应用程序是SP,谷歌办公套件将是IDP。

在我的Mavenpom.xml文件中,我有:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-saml2-service-provider</artifactId>
        </dependency>

在我的代码中,我有:


@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Bean
    public RelyingPartyRegistration googleRegistration() throws CertificateException {

        final String idpEntityId = "https://accounts.google.com/o/saml2?idpid=REDACTED";
        final String webSsoEndpoint = "https://accounts.google.com/o/saml2/idp?idpid=REDACTED";
        final String registrationId = "gsuite";
        final String localEntityIdTemplate = "{baseUrl}/saml2/service-provider-metadata/{registrationId}";
        final String acsUrlTemplate = "{baseUrl}/login/saml2/sso/{registrationId}";
        final byte[] certBytes = ("-----BEGIN CERTIFICATE-----\n" +
                "REDACTED\n" +
                "-----END CERTIFICATE-----").getBytes();
        final InputStream is = new ByteArrayInputStream(certBytes);
        final CertificateFactory cf = CertificateFactory.getInstance("X.509");
        final X509Certificate cert = (X509Certificate) cf.generateCertificate(is);

        final Saml2X509Credential credential = new Saml2X509Credential(cert,
                Saml2X509CredentialType.SIGNING); // THIS IS THE PROBLEM

        return RelyingPartyRegistration.withRegistrationId(registrationId)
                .providerDetails(config -> config.entityId(idpEntityId))
                .providerDetails(config -> config.webSsoUrl(webSsoEndpoint))
                .credentials(c -> c.add(credential))
                .localEntityIdTemplate(localEntityIdTemplate)
                .assertionConsumerServiceUrlTemplate(acsUrlTemplate)
                .build();
    }

    @Bean
    public RelyingPartyRegistrationRepository relyingPartyRegistrationRepository(
            final RelyingPartyRegistration googleRegistration) {

        return new InMemoryRelyingPartyRegistrationRepository(googleRegistration);
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception {

        http
                .authorizeRequests(authorize -> authorize
                        .anyRequest().authenticated())
                .saml2Login();
    }
}

问题是,我需要一个签名密钥,但行最终Saml2X509Credential凭据=new Saml2X509Credential(cert, Saml2X509CreentialType. SIGning);抛出一个异常,因为您必须将一个Private ateKey传递到该构造函数中,以便将其用于SIGning类型。但是,如果我使用该凭据进行验证,应用程序将失败,并需要一个签名密钥的异常。

谷歌办公套件只提供了一个元数据XML文件(Spring Security不支持)和一个. pem文件。我将. pem文件中的所有文本复制到上面的String中以生成X509证书。

在Spring Security SAML的文档中,它们显示了2个证书,但G套件只提供了1个。我应该从中生成私钥吗。pem文件?如果是,怎么做?

共有1个答案

茹轩昂
2023-03-14

成功了!

关键是禁用签名。

    @Bean
    public RelyingPartyRegistration googleRegistration() throws CertificateException {

        // remote IDP entity ID
        final String idpEntityId = "https://accounts.google.com/o/saml2?idpid=REDACTED";
        // remote WebSSO Endpoint - Where to Send AuthNRequests to
        final String webSsoEndpoint = "https://accounts.google.com/o/saml2/idp?idpid=REDACTED";
        // local registration ID
        final String registrationId = "gsuite";
        // local entity ID - autogenerated based on URL
        final String localEntityIdTemplate = "{baseUrl}/saml2/service-provider-metadata/{registrationId}";
        // local SSO URL - autogenerated, endpoint to receive SAML Response objects
        final String acsUrlTemplate = "{baseUrl}/login/saml2/sso/{registrationId}";
        // local signing (and local decryption key and remote encryption certificate)
        final byte[] certBytes = ("-----BEGIN CERTIFICATE-----\n" +
                "REDACTED\n" +
                "-----END CERTIFICATE-----").getBytes();
        final InputStream is = new ByteArrayInputStream(certBytes);
        final CertificateFactory cf = CertificateFactory.getInstance("X.509");
        final X509Certificate cert = (X509Certificate) cf.generateCertificate(is);

        final Saml2X509Credential credential = new Saml2X509Credential(cert,
                Saml2X509CredentialType.VERIFICATION, Saml2X509CredentialType.ENCRYPTION);

        return RelyingPartyRegistration.withRegistrationId(registrationId)
                .providerDetails(config -> config.entityId(idpEntityId))
                .providerDetails(config -> config.webSsoUrl(webSsoEndpoint))
                .providerDetails(config -> config.signAuthNRequest(false)) // THIS IS THE KEY
                .credentials(c -> c.add(credential))
                .localEntityIdTemplate(localEntityIdTemplate)
                .assertionConsumerServiceUrlTemplate(acsUrlTemplate)
                .build();
    }
 类似资料:
  • 上述代码的结果是: 已打开。服务帐户客户端 ID 在 GSuite 中使用适当的作用域进行授权。 服务帐户适用于普通凭据。它只适用于委托凭证。 我在我们的域中尝试了不同的API(范围)和不同的用户。 我有一个同事试图从头开始编写一个样本,他得到了同样的东西。

  • 获取Marketplace应用程序的服务帐户授权时遇到问题 在发布我们的应用程序的过程中,我们需要两种类型的同意: 管理员代表所有用户(“https://www.googleapis.com/auth/userinfo.email、https://www.googleapis.com/auth/userinfo.profile”)对 SSO 的目录范围同意。 https://www.googlea

  • 我是一个非营利组织的谷歌办公套件管理员,刚刚发现了数据导出功能,这似乎就像个人账户的外卖。 导出文件已经准备好,现在可以从谷歌云平台存储中的存储桶下载。然而,有很多很多文件夹,试图进出每个文件夹来下载很多很多。每个文件中的zip文件听起来都是一个令人头疼的问题。 我在Mac上使用Transmit,它可以通过与Amazon S3的互操作性连接到谷歌云存储。然而,当我连接时,我什么也看不到(因为我不使

  • 我尝试过将deendpoint与云SQL和Hibernate集成。但是,每次都有错误。跟随我的测试: 1 -源文件夹中的persistence . XML:http://imgur.com/hKjf8Cs给我错误:http://imgur.com/QJe8rvq 2-资源文件夹中的persistence.xml给我错误: ServletInitializationParameters.java:5

  • 这是原始查询: 原始查询的输出。请检查列H,该列有空单元格。 我试图使用以下公式对原始查询进行子查询: =QUERY(QUERY(IMPORTRANGE(“sheet_name”,“social media posts!a:as”),“选择Col1,Col14,Col12,Col10,Col23,Col16,Col13,Col37,Col2,Col3其中Col2='instagram'”,1),“

  • 我有一个使用Google Drive的应用程序,它必须(a)不需要用户登录,(b)填充授权用户可以查看的文档。 正因为如此,如本文所述,使用常规帐户作为服务帐户似乎是我唯一的选择https://developers.google.com/drive/web/service-accounts 使用常规Google帐户作为应用程序拥有的帐户 你可以像任何用户一样,通过谷歌账户注册流程或在你的谷歌应用程