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

将Spring Boot安全SAML与Azure广告图库应用集成为多租户

冷吉星
2023-03-14

我正在开发JavaSpring Boot System,并尝试使用SAML单点登录与Azure非库应用程序集成。

我发现了如何创建非图库应用程序,如何将非图库应用程序应用到Azure图库列表等。例如,这个链接是关于配置SAML SSO:配置基于SAML的单点登录,所以我了解Azure端的配置和过程。

我使用的是Spring Security SAML扩展。但是除了基于XML的官方SAML扩展文档之外,即使我做了很多研究,我也找不到Spring Boot端的配置。

顺便说一下,我的主要目标是将我们的组织应用程序添加到Azure gallery应用程序列表中。我们的应用程序由多家公司使用,因此如果我们将我们的组织应用程序添加到Azure Gallery应用程序列表,我们的客户可以将他们的Azure AD帐户配置为s so集成。

我的问题如下:

  1. 如何将Azure非库应用程序集成到Spring Boot应用程序?
  2. 如何处理多个Azure AD租户?

有人能帮我吗?

编辑:目前我用Spring Boot和Azure广告非图库应用程序进行了单点登录。我使用Azure AD Federation XML元数据URL配置了IdP元数据。你可以在下面看到源代码:

@Configuration
@Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
    @Value("${security.saml2.metadata-url}")
    private String IdPMetadataURL;

    @Value("${server.ssl.key-alias}")
    private String keyStoreAlias;

    @Value("${server.ssl.key-store-password}")
    private String keyStorePassword;

    @Value("${server.port}")
    String port;

    @Value("${server.ssl.key-store}")
    private String keyStoreFile;

    @Autowired
    private SAMLUserService samlUserService;

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/saml/**", "/", "/login", "/home", "/about").permitAll()
                .anyRequest().authenticated()
                .and()
                .apply(saml())
                .webSSOProfileConsumer(getWebSSOProfileConsumerImpl())
                .userDetailsService(samlUserService)
                .serviceProvider()
                .keyStore()
                .storeFilePath(this.keyStoreFile)
                .password(this.keyStorePassword)
                .keyname(this.keyStoreAlias)
                .keyPassword(this.keyStorePassword)
                .and()
                .protocol("https")
                .hostname(String.format("%s:%s", "localhost", this.port))
                .basePath("/")
                .and()
                .identityProvider()
                .metadataFilePath(IdPMetadataURL)
                .and();
    }

    public WebSSOProfileConsumerImpl getWebSSOProfileConsumerImpl(){
        WebSSOProfileConsumerImpl consumer = new WebSSOProfileConsumerImpl();
        consumer.setMaxAuthenticationAge(26000000); //300 days
        return consumer;
    }
}

从现在开始,我需要生成IdP元数据XML,而不是使用IdP元数据URL。使用如下字段:

    < li>IdP实体ID < li>IdP单点登录URL < li>IdP公共证书

我正在思考的过程是:

  1. 我们的客户在上面注册他们的Azure AD IdP字段
  2. 我的Spring Boot系统自动生成IdP元数据XML
  3. 然后客户的Azure AD SSO可以集成到我们的系统中

如果有什么问题,请教我。

共有3个答案

詹正浩
2023-03-14

最后,我完成了动态IDP的解决方案。我在这个简化的项目中使用了spring boot security saml。谢谢你实施它的乌利塞斯博基奥。也非常感谢ledjon,他与我分享了他的经历。

下面是我如何配置http安全性的saml部分

http.apply(saml)
    .serviceProvider()
        .metadataGenerator()
        .entityId(LocalSamlConfig.LOCAL_SAML_ENTITY_ID)
        .entityBaseURL(entityBaseUrl)
        .includeDiscoveryExtension(false)
    .and()
        .sso()
        .successHandler(new SendToSuccessUrlPostAuthSuccessHandler(canvasAuthService))
    .and()
        .metadataManager(new LocalMetadataManagerAdapter(samlAuthProviderService))
        .extendedMetadata()
        .idpDiscoveryEnabled(false)
    .and()
        .keyManager()
        .privateKeyDERLocation("classpath:/saml/localhost.key.der")
        .publicKeyPEMLocation("classpath:/saml/localhost.cert")
    .and()
        .http()
            .authorizeRequests()
            .requestMatchers(saml.endpointsMatcher())
            .permitAll();

这里重要的部分是.metadataManager(新的LocalMetadataManagerAdapter(samlAuthProviderService)),这就是我们试图在这里解决的问题。对象 samlAuthProviderService 是一个 Bean 托管的对象,它包含从数据库中实际检索元数据的逻辑,因此没有太多特别的内容。但这是我的LocalMetadataManagerAdapter大致的样子:

@Slf4j
public class LocalMetadataManagerAdapter extends CachingMetadataManager {

    private final SamlAuthProviderService samlAuthProviderService;

    public LocalMetadataManagerAdapter(SamlAuthProviderService samlAuthProviderService) throws MetadataProviderException {
        super(null);
        this.samlAuthProviderService = samlAuthProviderService;
    }

    @Override
    public boolean isRefreshRequired() {
        return false;
    }

    @Override
    public EntityDescriptor getEntityDescriptor(String entityID) throws MetadataProviderException {
        // we don't really want to use our default at all, so we're going to throw an error
        // this string value is defined in the "classpath:/saml/idp-metadata.xml" file:
        // which is then referenced in application.properties as saml.sso.idp.metadata-location=classpath:/saml/idp-metadata.xml
        if("defaultidpmetadata".equals(entityID)) {
            throw exNotFound("Unable to process requests for default idp. Please select idp with ?idp=x parameter.");
        }

        EntityDescriptor staticEntity = super.getEntityDescriptor(entityID);

        if(staticEntity != null)
            return staticEntity;

        // we need to inject one, and try again:
        injectProviderMetadata(entityID);

        return super.getEntityDescriptor(entityID);
    }

    @SneakyThrows
    private void injectProviderMetadata(String entityID) {
        String xml =
            samlAuthProviderService.getMetadataForConnection(entityID)
                .orElseThrow(() -> exRuntime("Unable to find metadata for entity: " + entityID));

        addMetadataProvider(new LocalMetadataProvider(entityID, xml));

        // this will force a refresh/re-wrap of the new entity
        super.refreshMetadata();
    }
}

这里重要的部分是< code > getEntityDescriptor()的覆盖,它将在运行时被调用以获取元数据对象。我还通过重写< code>isRefreshRequired()以返回false来禁用刷新。您可以确定这对您的用例是否有意义。

引用的 LocalMetadataProvider 只是一个包装类,用于在需要时存储/返回 xml 字符串:

public class LocalMetadataProvider extends AbstractReloadingMetadataProvider {

    private final String Id;
    private final String xmlData;

    public LocalMetadataProvider(String id, String xmlData) {
        this.Id = id;
        this.xmlData = xmlData;

        setParserPool(LocalBeanUtil.getBeanOrThrow(ParserPool.class));
    }

    @Override
    protected String getMetadataIdentifier() {
        return this.Id;
    }

    @Override
    protected byte[] fetchMetadata() throws MetadataProviderException {
        return xmlData.getBytes();
    }
}

最后,我们可以将idp元数据entityID作为参数传递。并从DB等中检索entityID元数据:/saml/login? idp=X其中X是我们想要传递给getEntityDescriptor()的entityID值。

万俟均
2023-03-14

若要将应用程序列表到 Azure 库应用程序列表,请仔细阅读本文档。请完成文档中提到的整个过程,以便在 azure 库中列出您的应用程序。

仅对于已经存在于库中的应用程序,才会提到应用程序的配置端。对于非画廊应用程序,您需要在应用程序端配置azure广告元数据值。

锺威
2023-03-14

我正在使用带有Spring Boot的Spring Security SAML扩展。使用哪种SAML IdP并不重要,因为您只需要IdP元数据。您可以生成SP元数据,并按照MS文档中的说明使用它。您可以在SAML文档中检查Spring Security。

 类似资料:
  • 我决定从旧的azure门户创建应用程序并将应用程序设置为多租户。 我已经设置了OAuth 2.0令牌endpoint(< code > https://log in . Microsoft online . com/ 如果我尝试使用任何已注册的Office 365用户ID(我用于登录Azure的用户除外)进行授权,则会收到此错误: 来自身份提供者“https://STS . windows . n

  • 我们希望将Azure ADB2C用于Web应用程序,以允许用户使用其公司ADFS帐户登录。 根据Azure Active Directory B2C:使用自定义策略将ADF添加为SAML身份提供程序: “与ADFS帐户联合需要ADFS帐户的客户端机密,才能代表应用程序信任Azure AD B2C。您需要将ADFS证书存储在Azure AD B2C租户中。” 这意味着我们需要将他们的. pfx证书(

  • 使用以下方法将用户添加到角色中没有问题 我收到“错误的请求”,在Fiddler中“一个或多个属性无效”。没有额外的信息。

  • 我合作的公司有许多客户使用谷歌广告为他们的网站做营销。公司希望使用客户的数据进行分析。我得到了一个项目,使用C#集成谷歌广告API,从谷歌广告中获取所有数据,如活动等,并将其移动到我们的系统中为每个客户端。我只给开发人员令牌和客户端的客户ID。例如 客户A的客户ID 客户B的客户ID 当我浏览谷歌广告API文档时,我有点不知所措。在文档中,是OAuth2。0需要创建才能使用客户端库,该库将生成客户

  • 我正在开发一个与多个Idp集成的spring boot应用程序。我在互联网上查看了许多将spring应用程序与SAML集成的示例,所有这些示例都展示了如何通过应用程序属性与Idp集成。 在OAuth 2.0的情况下,我们有MSAL库提供的客户端,我们集成如下。 在Spring boot中有没有类似的方法,让客户端调用ADFS SAMLIDP并对用户进行身份验证? 根据请求,从数据库中获取IDP详细

  • 我对springfox和Swagger2都是新手。我一直在尝试将SpringFox/Swagger2与我的spring boot微服务集成以生成API文档。 我遵循了“http://springfox.github.io/springfox/docs/snapshot/”站点中给出的步骤。但是我没有成功的带来api文档页面。 每当我试图点击URL“http://localhost:8081/swa