Spring Security SAML2 Dynami c выбор IDP или Dynami c URL для них - PullRequest
1 голос
/ 11 марта 2020

Мы пытаемся настроить несколько провайдеров идентификации в приложении для поддержки различных типов единого входа. Проблема в том, что для запроса без аутентификации приложение не знает, на какой IDP перенаправить. Мы можем выяснить, какой IDP использовать, основываясь на доменном имени. Это не проблема. Проблема состоит в том, чтобы изменить фильтры для способа перенаправления на этот указанный c IDP вместо первого найденного.

Интересно, есть ли простой способ поддержать его в Spring Security или его библиотеке SAML2.

Я могу либо каким-либо образом изменить метаданные, чтобы перенаправить их на свой собственный URL-адрес (а затем добавить некоторый пользовательский код), либо сделать так, чтобы фильтр аутентификации выбрал правильный IDP на основе некоторых критериев.

ОБНОВЛЕНИЕ

Текущая конфигурация yaml:

spring:
  security:
    saml2:
      relyingparty:
        registration:
          idpone:
            identityprovider:
              entity-id: https://idpone.com
              sso-url: https://idpone.com
              verification: 
                credentials:
                - certificate-location: "classpath:saml/idpone.crt"
          idptwo:
            identityprovider:
              entity-id: https://idptwo.com
              sso-url: https://idptwo.com
              verification: 
                credentials:
                - certificate-location: "classpath:saml/idptwo.crt"

1 Ответ

2 голосов
/ 11 марта 2020

В Spring Security 5.2 вы можете настроить несколько IDP с помощью RelyingPartyRegistrationRepository.

Каждый из них выглядит примерно так при использовании Spring Boot:

spring:
  security:
    saml2:
      relyingparty:
        registration:
          idpone:
            identityprovider:
              verification:
                credentials:
                  - certificate-location: "classpath:idpOne.crt"
              entity-id: https://idp.example.org
              sso-url: https://idp.example.org/SSOService.saml2
          idptwo:
            identityprovider:
              ...

Затем вы можно инициировать запрос AuthNRequest для idpOne, указав значение http://localhost:8080/saml2/authenticate/idpOne.

По имени хоста

Если вы хотите сделать это по имени хоста, то вы можете настроить страницу /login, чтобы узнать, какая из /saml2/authenticate/{registrationId} конечных точек для перенаправления.

Сначала вы скажете Spring Security, что у вас есть пользовательская страница /login, поэтому она не создает одну:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) {
        http
            .authorizeRequests(authz -> authz
                .mvcMatchers("/login").permitAll() // here
                .anyRequest().authenticated())
            .saml2Login(saml2 -> saml2.loginPage("/login")) // and here
    }

}

И тогда вы бы его определили:

@Controller
public class LoginController {
    private final RelyingPartyRegistrationRepository relyingParties;

    // ... constructor

    @GetMapping("/login")
    public void login(HttpServletRequest request, HttpServletResponse response) {
        String registrationId = // ... derive from the host name
        RelyingPartyRegistration relyingParty = this.relyingParties
                .findByRegistrationId(registrationId);
        if (relyingParty == null) {
            response.setStatusCode(401);
        } else {
            response.sendRedirect("/saml2/authenticate/" + registrationId);
        }
    }
}

Причина поиска в конечной точке /login состоит в том, чтобы убедиться, что registrationId, указанный в имени хоста, является допустимым.

...