Java 使用G套件作为Idp的Spring Security SAML2

Java 使用G套件作为Idp的Spring Security SAML2,java,spring-security,saml-2.0,google-workspace,spring-security-saml2,Java,Spring Security,Saml 2.0,Google Workspace,Spring Security Saml2,我试图使用Spring安全性(5.3.3.RELEASE)在Spring引导应用程序中处理SAML2身份验证。带有SP和G套件的Spring Boot应用程序将是IDP 在我的Maven pom.xml文件中,我有: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-star

我试图使用Spring安全性(5.3.3.RELEASE)在Spring引导应用程序中处理SAML2身份验证。带有SP和G套件的Spring Boot应用程序将是IDP

在我的Maven pom.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>
问题是我需要一个签名密钥,但行
final Saml2X509Credential credential=new Saml2X509Credential(cert,Saml2X509CredentialType.signing)
引发异常,因为您必须将
私钥
传递到该构造函数中,才能将其用于
签名
类型。但是,如果我使用该凭据进行验证,应用程序将失败,但需要签名密钥的情况除外

G套件只提供元数据XML文件(Spring Security不支持)和
.pem
文件。我将
.pem
文件中的所有文本复制到上面的字符串中,以生成X509证书

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

让它工作起来

密钥正在禁用签名

    @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();
    }

等待这是两件不同的事情。如果要对请求进行签名,则需要一个带有私钥的签名凭据。您始终需要验证凭据来验证来自IdP的AuthNResponse
    @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();
    }