0

在我的 web.xml 中,我有两个不同的调度程序 servlet,其中一个具有来自根上下文的所有 bean,第二个调度程序 servlet 具有另一个 authenticationManager。如前所述:

在 Web MVC 框架中,每个 DispatcherServlet 都有自己的 WebApplicationContext,它继承了根 WebApplicationContext 中已经定义的所有 bean。根 WebApplicationContext 应该包含应该在其他上下文和 Servlet 实例之间共享的所有基础结构 bean。这些继承的 bean 可以在特定于 servlet 的范围内被覆盖,并且您可以在给定的 Servlet 实例本地定义新的特定于范围的 bean。

所以我的新 authenticationManager 必须覆盖根上下文中的相同 bean。这个 authenticationManager 有另一个 daoAuthenticationProvider,它有另一个 userDetailsS​​ervice。但是,当我想从第二个 dispathcer servlet 的路径登录系统时,spring 使用 root 上下文中的 authenticationManager。

它是 web.xml:

<context-param>
          <param-name>contextClass</param-name>
          <param-value>
              org.springframework.web.context.support.AnnotationConfigWebApplicationContext
          </param-value>
      </context-param>

      <context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>ua.translate.AppConfig</param-value>
      </context-param>

 <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>


      <filter>
          <filter-name>springSecurityFilterChain</filter-name>
          <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
      </filter>

      <filter-mapping>
          <filter-name>springSecurityFilterChain</filter-name>
          <url-pattern>/*</url-pattern>
          <dispatcher>REQUEST</dispatcher>
          <dispatcher>ERROR</dispatcher>
      </filter-mapping>

      <servlet>
          <servlet-name>dispatcher</servlet-name>
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
          <init-param>
              <param-name>contextClass</param-name>
              <param-value>
                  org.springframework.web.context.support.AnnotationConfigWebApplicationContext
              </param-value>
          </init-param>
          <init-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>ua.translate.AppConfig</param-value>
          </init-param>
          <load-on-startup>1</load-on-startup>
      </servlet>

      <servlet>
          <servlet-name>adminDispatcher</servlet-name>
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
          <init-param>
              <param-name>contextClass</param-name>
              <param-value>
                  org.springframework.web.context.support.AnnotationConfigWebApplicationContext
              </param-value>
          </init-param>
          <init-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>ua.admin.AdminConfig</param-value>
          </init-param>
          <load-on-startup>1</load-on-startup>
      </servlet>

      <servlet-mapping>
          <servlet-name>adminDispatcher</servlet-name>
          <url-pattern>/bulbular/</url-pattern>
      </servlet-mapping>

      <servlet-mapping>
          <servlet-name>dispatcher</servlet-name>
          <url-pattern>/</url-pattern>
      </servlet-mapping>

它是 AdminConfig.class:

@EnableWebMvc
@Configuration
@ComponentScan(basePackages = {"ua.admin"})
@EnableTransactionManagement
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AdminConfig extends WebMvcConfigurerAdapter{
}

它是 WebSecurityConfigurerAdapter 实现,位于 ua.admin 包中,并具有新的 authenticationManager:

@EnableWebSecurity
@Configuration
@ComponentScan(basePackages = {"ua.translate.handler","ua.translate.service.impl"})
@Order(1)
public class AdminSecurityConfig extends WebSecurityConfigurerAdapter{


@Autowired
protected CustomSuccessHandler customSuccessHandler;

@Autowired
@Qualifier("customAccessDeniedHandler")
protected AccessDeniedHandler accessDeniedHandler;

 @Autowired
 @Qualifier("adminDetailsService")
 private UserDetailsService uds;


 @Override
 public void configure(WebSecurity web){
     web 
        .ignoring()
        .antMatchers(new String[]{"/resources/**"});
 }

@Override
protected void configure(HttpSecurity http) throws Exception {
    http    
            .antMatcher("/bulbular/**")
            .authorizeRequests()
            .antMatchers("/bulbular/login").permitAll()
            .anyRequest().hasRole("ADMIN")
        .and()
            .formLogin()
            .loginPage("/bulbular/login")
            .permitAll()
            .successHandler(customSuccessHandler)
            .failureUrl("/bulbular/login?error")
            .usernameParameter("username")
            .passwordParameter("password")
            .loginProcessingUrl("/j_spring_security_check")
        .and()
                .logout().deleteCookies("JSESSIONID")
                        .logoutUrl("/bulbular/logout")
                        .logoutSuccessUrl("/bulbular/login?logout")
        .and()
            .csrf()
        .and()
            .exceptionHandling()
            .accessDeniedHandler(accessDeniedHandler);
}


 @Bean
 public AuthenticationProvider daoAuthenticationProvider() {
    DaoAuthenticationProvider impl = new DaoAuthenticationProvider();
    impl.setUserDetailsService(uds);
    impl.setPasswordEncoder(bcryptEncoder());
    impl.setHideUserNotFoundExceptions(false);
    return impl;
 }


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


@Bean(name = "authenticationManager")
public ProviderManager getProviderManager(){
    List<AuthenticationProvider> providers = new ArrayList<>();
    providers.add(daoAuthenticationProvider());
    ProviderManager providerManager = new ProviderManager(providers);
    return providerManager;

}

此类是根上下文中的 WebSecurityConfigurer 实现,它是另外两个类的基类:

@EnableWebSecurity
@ComponentScan(basePackages = {"ua.translate"})
@Order(99)
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
protected CustomSuccessHandler customSuccessHandler;

@Autowired
@Qualifier("customAccessDeniedHandler")
protected AccessDeniedHandler accessDeniedHandler;

@Autowired
protected PersistentTokenRepository tokenRepository;

@Autowired
@Qualifier("userDetailsServiceImpl")
protected UserDetailsService uds;

@Override
public void configure(WebSecurity web){
    web 
        .ignoring()
        .antMatchers(new String[]{"/resources/**"});
}


@Bean
public AuthenticationProvider daoAuthenticationProvider() {
    DaoAuthenticationProvider impl = new DaoAuthenticationProvider();
    impl.setUserDetailsService(uds);
    impl.setPasswordEncoder(bcryptEncoder());
    impl.setHideUserNotFoundExceptions(false);
    return impl;
}

@Bean(name = "authenticationManager")
public ProviderManager getProviderManager(){
    List<AuthenticationProvider> providers = new ArrayList<>();
    providers.add(daoAuthenticationProvider());
    ProviderManager providerManager = new ProviderManager(providers);
    return providerManager;

}

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

有两个子类,它们位于根上下文中:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Configuration
@Order(3)
public static class AppSecurityConfigClient extends AppSecurityConfig{

    @Override
    public void configure(WebSecurity web){
        web 
            .ignoring()
            .antMatchers(new String[]{"/resources/**"});
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http    

                .authorizeRequests()
                .antMatchers("/client/registration*").anonymous()
                .antMatchers("/index","/translators","/orders","/client/login*","/client/confirmation").permitAll()
                .antMatchers("/client/**").hasRole("CLIENT")
            .and()
                .formLogin()
                .loginPage("/client/login")
                .permitAll()
                .successHandler(customSuccessHandler)
                .failureUrl("/client/login?error")
                .usernameParameter("username")
                .passwordParameter("password")
                .loginProcessingUrl("/j_spring_security_check")
            .and()
                    .logout().deleteCookies("JSESSIONID")
                            .logoutUrl("/client/logout")
                            .logoutSuccessUrl("/client/login?logout")
            .and()

             /*!!!!Доделать saved request url!!!!*/

                .rememberMe().tokenRepository(tokenRepository)
                .tokenValiditySeconds(86400)
            .and()
                .csrf()
            .and()
                .exceptionHandling()
                .accessDeniedHandler(accessDeniedHandler);
    }

}

@Configuration
@Order(2)
public static class AppSecurityConfigTranslator extends AppSecurityConfig {


    @Override
    public void configure(WebSecurity web){
        web 
            .ignoring()
            .antMatchers(new String[]{"/resources/**"});
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .antMatcher("/translator/**")
                .authorizeRequests()
                .antMatchers("/translator/registration*").anonymous()
                .antMatchers("/translator/index","/translator/login*","/translator/confirmation").permitAll()
                .antMatchers("/translator/**").hasRole("TRANSLATOR")
                .anyRequest().authenticated()
            .and()
                .formLogin()
                .loginPage("/translator/login")
                .permitAll()
                .successHandler(customSuccessHandler)
                .failureUrl("/translator/login?error")
                .usernameParameter("username")
                .passwordParameter("password")
                .loginProcessingUrl("/j_spring_security_check")
            .and()
                    .logout().deleteCookies("JSESSIONID")
                            .logoutUrl("/translator/logout")
                            .logoutSuccessUrl("/translator/login?logout")
            .and()
            /**
             * Доделать saved request url!!!
             */
                .rememberMe().tokenRepository(tokenRepository)
                .tokenValiditySeconds(86400)
            .and()
                .csrf()
            .and()
                .exceptionHandling()
                .accessDeniedHandler(accessDeniedHandler)
            .and()
                .userDetailsService(uds);
    }

}

}

因此,adminDispatcher servlet 使用 ua.admin.AdminConfig,它依次扫描 ua.admin 包,并找到带有第二个 authenticationManager 实现的 WebSecurityConfigurerAdapter 实现。

/bulbular/ - 它是这个dispathcer servlet 的路径,也是WebSecurityConfigurerAdapter 实现中http 配置的路径。但是当我想从 /bulbular/login 页面登录时,spring 使用来自 SecurityConfig.class 的实现 - 来自根上下文的类。请帮忙!!!!

4

0 回答 0