如何使用多个登录页面,一个用于管理员,另一个用于用户

uzi*_*iak 5 spring spring-security spring-boot

我想要两个不同的登录页面。一份供管理员使用,另一份供用户使用。

@Order(1)当我从静态类中删除注释时,仅使用下面的代码@Order,只有最后一个有效。我在两个不同的ConfigSecurity文件中使用它们,但它不起作用。

我期待他们俩都能工作。然而只有一个在工作。

package com.example.FlightAgency.security;
import com.example.FlightAgency.service.UserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Configuration
    @Order(1)
    public static class App1ConfigurationAdapter {
        @Bean
        public UserDetailsService userDetailsService() {
            return new UserService();
        }

        @Bean
        public PasswordEncoder passwordEncoder() {
            return NoOpPasswordEncoder.getInstance();
        }

        @Bean
        public SecurityFilterChain filterChainApp1(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                    .requestMatchers("/user/**").hasAuthority("USER")
                    .and()
                .formLogin()
                    .loginPage("/user/login")
                    .usernameParameter("email")
                    .loginProcessingUrl("/user/login")
                    .defaultSuccessUrl("/user/")
                    .permitAll()
                    .and()
                .logout()
                    .logoutUrl("/user/logout")
                    .logoutSuccessUrl("/user/login")
                    .deleteCookies("JSESSIONID")
                    .and()
                .exceptionHandling()
                    .accessDeniedPage("/403")
                    .and()
                .csrf().disable();
            return http.build();
        }
    }

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

        @Bean
        public SecurityFilterChain filterChainApp2(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                    .requestMatchers("/admin/**").hasAuthority("ADMIN")
                    .and()
                .formLogin()
                    .loginPage("/admin/login")
                    .usernameParameter("email")
                    .loginProcessingUrl("/admin/login")
                    .defaultSuccessUrl("/admin/")
                    .permitAll()
                    .and()
                .logout()
                    .logoutUrl("/admin/logout")
                    .logoutSuccessUrl("/admin/login")
                    .deleteCookies("JSESSIONID")
                    .and()
                .exceptionHandling()
                    .accessDeniedPage("/403")
                    .and()
                .csrf().disable();
            return http.build();
        }
    }
}    `
Run Code Online (Sandbox Code Playgroud)

dur*_*dur 12

两个安全过滤器链均不受限制(默认为/**)。

\n

春季安全6

\n

您必须使用 限制第一个securityMatcher,请参阅Spring Security Reference

\n
\n

多个 HttpSecurity 实例

\n

我们可以配置多个HttpSecurity实例,就像我们可以<http>在 XML 中拥有多个块一样。关键是要注册多个SecurityFilterChain @Beans。以下示例对以 开头的 URL\xe2\x80\x99s 有不同的配置/api/

\n
@Configuration\n@EnableWebSecurity\npublic class MultiHttpSecurityConfig {\n  @Bean                                                             \n  public UserDetailsService userDetailsService() throws Exception {\n      // ensure the passwords are encoded properly\n      UserBuilder users = User.withDefaultPasswordEncoder();\n      InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();\n      manager.createUser(users.username("user").password("password").roles("USER").build());\n      manager.createUser(users.username("admin").password("password").roles("USER","ADMIN").build());\n      return manager;\n  }\n\n  @Bean\n  @Order(1)                                                        \n  public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {\n      http\n          .securityMatcher("/api/**")                                   \n          .authorizeHttpRequests(authorize -> authorize\n              .anyRequest().hasRole("ADMIN")\n          )\n          .httpBasic(withDefaults());\n      return http.build();\n  }\n\n  @Bean                                                            \n  public SecurityFilterChain formLoginFilterChain(HttpSecurity http) throws Exception {\n      http\n          .authorizeHttpRequests(authorize -> authorize\n              .anyRequest().authenticated()\n          )\n          .formLogin(withDefaults());\n      return http.build();\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. 像往常一样配置身份验证。
  2. \n
  3. 创建一个SecurityFilterChain包含的实例@Order来指定SecurityFilterChain应首先考虑哪个。
  4. \n
  5. 声明http.securityMatcherHttpSecurity仅适用于以 开头的 URL /api/
  6. \n
  7. 创建 的另一个实例SecurityFilterChain。如果 URL 不以 开头/api/,则使用此配置。此配置被视为 after apiFilterChain,因为它有一个@Order值 after 1(没有@Order默认值是最后一个)。
  8. \n
\n
\n