【问题标题】:How to configure spring security 3.2 to use dao authentication and custom authentication filter using java config如何使用 java config 配置 spring security 3.2 以使用 dao 身份验证和自定义身份验证过滤器
【发布时间】:2014-02-23 19:58:30
【问题描述】:

我使用 dao 身份验证和自定义身份验证过滤器搜索了 spring 安全示例,但我发现,所有示例都使用 xml 文件配置,

我的问题是如何配置自定义过滤器,即 UsernamePasswordAuthenticationFilter

我的基于 xml 的 securityConfig 文件如下所示:

<http auto-config="false" use-expressions="true">

    <intercept-url pattern="/" access="permitAll" />        
    <intercept-url pattern="/auth/login.html" access="permitAll" />     
    <intercept-url pattern="/auth/logout.html" access="permitAll" />        
    <intercept-url pattern="/auth/accessDenied.html" access="permitAll" />      
    <intercept-url pattern="/admin/**" access="hasAnyRole('ROLE_ADMIN')" />
    <intercept-url pattern="/user/**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />


    <access-denied-handler error-page="/auth/accessDenied.html"/>

    <form-login login-page='/auth/login.html' 
        default-target-url="/"
        authentication-success-handler-ref="myAuthenticationSuccessHandler"
        authentication-failure-url="/auth/loginfailed.html" />

    <logout success-handler-ref="myLogoutSuccessHandler"
            invalidate-session="true" delete-cookies="JSESSIONID" />

    <remember-me key="uniqueAndSecret" token-validity-seconds="86400" />

     <session-management session-fixation-protection="migrateSession" 
            session-authentication-error-url="/auth/loginfailed.html"> 
        <concurrency-control max-sessions="1" 
                error-if-maximum-exceeded="true" 
                expired-url="/auth/login.html" 
                session-registry-alias="sessionRegistry"/>
    </session-management>

</http>

<beans:bean id="myAuthenticationSuccessHandler" 
    class="com.asn.handler.AsnUrlAuthenticationSuccessHandler" />

<beans:bean id="myLogoutSuccessHandler" 
    class="com.asn.handler.AsnLogoutSuccessHandler" />

<beans:bean id="userDetailsService" class="com.asn.service.UserDetailsServiceImpl"/>

<authentication-manager alias="authenticationManager">      
    <authentication-provider user-service-ref="userDetailsService"> 
        <password-encoder ref="encoder"/>                      
    </authentication-provider>
    <!-- <authentication-provider>
        <user-service>
            <user name="user1" password="user1Pass" authorities="ROLE_USER" />
            <user name="admin1" password="admin1Pass" authorities="ROLE_ADMIN" />
        </user-service>
    </authentication-provider> -->
</authentication-manager>

<!-- For hashing and salting user passwords -->
<beans:bean id="encoder" 
        class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

我想将配置转换为基于 Java 配置的.. 我试过这样,这是行不通的:

SecurityConfig 类:

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    private UserDetailsService userDetailsService;
    @Autowired
    private PasswordEncoder encoder;

    /*@Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth)throws Exception {
        logger.info("configureGlobal(AuthenticationManagerBuilder auth) invoked..");
        auth.userDetailsService(userDetailsService).passwordEncoder(encoder);       
    }*/

    @Override
    protected void configure(HttpSecurity http) throws Exception {  
        http.csrf().disable().authorizeRequests()
            .antMatchers("/resources/**","/assets/**","/files/**").permitAll()
            .antMatchers("/auth","/").permitAll()                           

                .anyRequest().authenticated() //every request requires the user to be authenticated
                .and()
            .formLogin() //form based authentication is supported
                .loginPage("/auth/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();

        http.exceptionHandling().accessDeniedPage("/auth/accessDenied");

        http.sessionManagement().sessionFixation().migrateSession()
            .sessionAuthenticationStrategy(concunSessContAuthStr());
    }

    @Bean(name="sessionRegistry")
    public SessionRegistryImpl sessionRegistryBean(){
        logger.info("sessionRegistryBean() invoked..");
        return new SessionRegistryImpl();
    }

    @Bean
    public UsernamePasswordAuthenticationFilter authFilter() throws Exception{
        logger.info("authFilter() invoked.."); 
        CustomUsernamePasswordAuthenticationFilter upaf = new CustomUsernamePasswordAuthenticationFilter();
        upaf.setAuthenticationManager(".."); //here, how to set AuthenticationManager ??
        upaf.setSessionAuthenticationStrategy(concunSessContAuthStr());
        return upaf;
    }


    @Bean
    public DaoAuthenticationProvider customAuthenticationManagerBean() {

        DaoAuthenticationProvider dap = new DaoAuthenticationProvider();
        dap.setUserDetailsService(userDetailsService);
        dap.setPasswordEncoder(encoder);
        return dap;
    }

    @Bean
    public ConcurrentSessionControlAuthenticationStrategy concunSessContAuthStr(){
        logger.info("concunSessContAuthStr() invoked.."); 
        ConcurrentSessionControlAuthenticationStrategy cscas= new ConcurrentSessionControlAuthenticationStrategy(sessionRegistryBean());
        cscas.setMaximumSessions(2);
        cscas.setExceptionIfMaximumExceeded(true);
        return cscas;
    }

}

任何建议如何配置?

谢谢!

【问题讨论】:

    标签: java spring-security java-ee-7 spring-java-config


    【解决方案1】:

    要使用自定义类替换 UsernamePasswordAuthenticationFilter,请执行以下操作:

    • 创建一个新类FormLoginConfigurer,内容如下(不幸的是原来的org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer是final,不能扩展),注意对super(new CustomAuthenticationProcessingFilter(),null)的调用:

      package demo;
      
      import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
      import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer;
      import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
      import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
      import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
      import org.springframework.security.web.util.matcher.RequestMatcher;
      
      public class FormLoginConfigurer<H extends HttpSecurityBuilder<H>> extends AbstractAuthenticationFilterConfigurer<H,FormLoginConfigurer<H>,UsernamePasswordAuthenticationFilter> {
      
      public FormLoginConfigurer() {
          super(new CustomAuthenticationProcessingFilter(),null);
          usernameParameter("username");
          passwordParameter("password");
      }
      
      public FormLoginConfigurer<H> loginPage(String loginPage) {
          return super.loginPage(loginPage);
      }
      
      public FormLoginConfigurer<H> usernameParameter(String usernameParameter) {
          getAuthenticationFilter().setUsernameParameter(usernameParameter);
          return this;
      }
      
      public FormLoginConfigurer<H> passwordParameter(String passwordParameter) {
          getAuthenticationFilter().setPasswordParameter(passwordParameter);
          return this;
      }
      
      @Override
      public void init(H http) throws Exception {
          super.init(http);
          initDefaultLoginFilter(http);
      }
      
      @Override
      protected RequestMatcher createLoginProcessingUrlMatcher(
              String loginProcessingUrl) {
          return new AntPathRequestMatcher(loginProcessingUrl, "POST");
      }
      
      private String getUsernameParameter() {
          return getAuthenticationFilter().getUsernameParameter();
      }
      
      private String getPasswordParameter() {
          return getAuthenticationFilter().getPasswordParameter();
      }
      
      private void initDefaultLoginFilter(H http) {
          DefaultLoginPageGeneratingFilter loginPageGeneratingFilter = http.getSharedObject(DefaultLoginPageGeneratingFilter.class);
          if(loginPageGeneratingFilter != null && !isCustomLoginPage()) {
              loginPageGeneratingFilter.setFormLoginEnabled(true);
              loginPageGeneratingFilter.setUsernameParameter(getUsernameParameter());
              loginPageGeneratingFilter.setPasswordParameter(getPasswordParameter());
              loginPageGeneratingFilter.setLoginPageUrl(getLoginPage());
              loginPageGeneratingFilter.setFailureUrl(getFailureUrl());
              loginPageGeneratingFilter.setAuthenticationUrl(getLoginProcessingUrl());
          }
      }
      

      }

    • 从您的configure(HttpSecurity) 方法中删除formLogin() 调用,并改用以下初始化:

       FormLoginConfigurer formLogin = new FormLoginConfigurer();
       http.apply(formLogin);
       formLogin.loginPage("/auth/login")
               .permitAll();
      
    • 身份验证管理器将自动提供给您的实例

    • 您可以通过调用 http.sessionManagement() 来自定义课堂中使用的 SessionAuthenticationStrategy,或者您可以将逻辑添加到新的 FormLoginConfigurer 以更新您需要的任何内容

    另一种选择是将您的 CustomUsernamePasswordAuthenticationFilter 过滤器注册为附加过滤器:

    • configure(HttpSecurity http)方法调用中:

       http.addFilter(authFilter());
      
    • 确保手动配置过滤器的所有选项

    • 请注意,系统还会在您的之后添加另一个 UsernamePasswordAuthenticationFilter 实例

    为了添加自定义AuthenticationProvider

    • 覆盖方法configure(AuthenticationManagerBuilder auth)并添加提供者:

       @Override
       protected void configure(AuthenticationManagerBuilder auth) throws Exception {
           auth.authenticationProvider(customAuthenticationManagerBean());
       }
      

    【讨论】:

      【解决方案2】:

      你已经接近了!

      upaf.setAuthenticationManager(".."); //here, how to set AuthenticationManager ??
      

      答案是:

      upaf.setAuthenticationManager(authenticationManagerBean());
      

      另外,像这样添加您的自定义:

      http
      .addFilterBefore(authFilter(), UsernamePasswordAuthenticationFilter.class)
      

      【讨论】:

        猜你喜欢
        • 2015-02-14
        • 1970-01-01
        • 1970-01-01
        • 2018-12-11
        • 2022-01-20
        • 2014-04-20
        • 2014-12-13
        • 2021-04-21
        • 2011-10-17
        相关资源
        最近更新 更多