Zwei Anmeldeseiten mit Spring Security

Zwei Login-Seiten mit Spring Security

1. Einführung

In diesem Tutorial werden wir sehen, wie wirconfigure Spring Security to work with two different login pages mit zwei verschiedenen Spring Securityhttp-Elementen in der Konfiguration verwenden können.

2. 2 HTTP-Elemente konfigurieren

Unter Umständen benötigen wir zwei Anmeldeseiten, wenn wir eine Seite für Administratoren einer Anwendung und eine andere Seite für normale Benutzer haben.

Wir werdenconfigure two http elements, die durch das jeweils zugeordnete URL-Muster unterschieden werden:

  • /user * für Seiten, für deren Zugriff eine normale Benutzerauthentifizierung erforderlich ist

  • /admin * für Seiten, auf die ein Administrator zugreifen wird

Jedeshttp-Element hat eine andere Anmeldeseite und eine andere Anmeldeverarbeitungs-URL.

Um zwei verschiedenehttp-Elemente zu konfigurieren, erstellen wir zwei statische Klassen, die mit@Configuration versehen sind und dieWebSecurityConfigurerAdapter erweitern.

Beide werden in eine reguläre@Configuration-Klasse eingeordnet:

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    ...
}

Definieren wir dieWebSecurityConfigurerAdapter für die Benutzer von“ADMIN”:

@Configuration
@Order(1)
public static class App1ConfigurationAdapter extends WebSecurityConfigurerAdapter {
    public App1ConfigurationAdapter() {
        super();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.antMatcher("/admin*")
          .authorizeRequests()
          .anyRequest()
          .hasRole("ADMIN")

          .and()
          .formLogin()
          .loginPage("/loginAdmin")
          .loginProcessingUrl("/admin_login")
          .failureUrl("/loginAdmin?error=loginError")
          .defaultSuccessUrl("/adminPage")

          .and()
          .logout()
          .logoutUrl("/admin_logout")
          .logoutSuccessUrl("/protectedLinks")
          .deleteCookies("JSESSIONID")

          .and()
          .exceptionHandling()
          .accessDeniedPage("/403")

          .and()
          .csrf().disable();
    }
}

Und jetzt definieren wir dieWebSecurityConfigurerAdapter für normale Benutzer:

@Configuration
@Order(2)
public static class App2ConfigurationAdapter extends WebSecurityConfigurerAdapter {

    public App2ConfigurationAdapter() {
        super();
    }

    protected void configure(HttpSecurity http) throws Exception {
        http.antMatcher("/user*")
          .authorizeRequests()
          .anyRequest()
          .hasRole("USER")

          .and()
          .formLogin()
          .loginPage("/loginUser")
          .loginProcessingUrl("/user_login")
          .failureUrl("/loginUser?error=loginError")
          .defaultSuccessUrl("/userPage")

          .and()
          .logout()
          .logoutUrl("/user_logout")
          .logoutSuccessUrl("/protectedLinks")
          .deleteCookies("JSESSIONID")

          .and()
          .exceptionHandling()
          .accessDeniedPage("/403")

          .and()
          .csrf().disable();
    }
}

Beachten Sie, dass wir durch Platzieren der Annotation@Orderfür jede statische Klasse die Reihenfolge angeben, in der die beiden Klassen basierend auf dem Mustervergleich berücksichtigt werden, wenn eine URL angefordert wird.

Zwei Konfigurationsklassen können nicht dieselbe Reihenfolge haben.

3. Benutzerdefinierte Anmeldeseiten

Wir erstellen für jeden Benutzertyp eine eigene benutzerdefinierte Anmeldeseite. Für den Administrator hat das Anmeldeformular eine“user_login”-Aktion, wie in der Konfiguration definiert:

User login page

User:
Password:

Die Administrator-Anmeldeseite ist ähnlich, außer dass das Formular gemäß der Java-Konfiguration eine Aktion von“admin_login” enthält.

4. Authentifizierungskonfiguration

Jetzt müssen wirconfigure authentication for our application. Schauen wir uns zwei Möglichkeiten an, um dies zu erreichen: eine mit einer gemeinsamen Quelle für die Benutzerauthentifizierung und die andere mit zwei separaten Quellen.

4.1. Verwenden einer allgemeinen Benutzerauthentifizierungsquelle

Wenn beide Anmeldeseiten eine gemeinsame Quelle für die Authentifizierung von Benutzern haben, können Sie eine einzelne Bean vom TypUserDetailsService erstellen, die die Authentifizierung übernimmt.

Lassen Sie uns dieses Szenario anhand einesInMemoryUserDetailsManager demonstrieren, das zwei Benutzer definiert - einen mit einer Rolle von“USER” und einen mit einer Rolle von“ADMIN”:

@Bean
public UserDetailsService userDetailsService() throws Exception {
    InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
    manager.createUser(User
      .withUsername("user")
      .password(encoder().encode("userPass"))
      .roles("USER")
      .build());

    manager.createUser(User
      .withUsername("admin")
      .password(encoder().encode("adminPass"))
      .roles("ADMIN")
      .build());

    return manager;
}

@Bean
public static PasswordEncoder encoder() {
    return new BCryptPasswordEncoder();
}

4.2. Verwenden von zwei verschiedenen Benutzerauthentifizierungsquellen

Wenn Sie unterschiedliche Quellen für die Benutzerauthentifizierung haben - eine für Administratoren und eine für normale Benutzer - können Sie in jeder statischen@Configuration-Klasse einAuthenticationManagerBuilder konfigurieren. Schauen wir uns ein Beispiel eines Authentifizierungsmanagers für den Benutzer eines“ADMIN”an:

@Configuration
@Order(1)
public static class App1ConfigurationAdapter extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
          .withUser("admin")
          .password(encoder().encode("admin"))
          .roles("ADMIN");
    }
}

In diesem Fall wird dieUserDetailsService-Bean aus dem vorherigen Abschnitt nicht mehr verwendet.

6. Fazit

In diesem kurzen Tutorial haben wir gezeigt, wie zwei verschiedene Anmeldeseiten in derselben Spring Security-Anwendung implementiert werden.

Den vollständigen Code für diesen Artikel finden Sie inGitHub project.

Wenn Sie die Anwendung ausführen, können Sie auf die obigen Beispiele über den URI von/protectedLinkszugreifen.