zoukankan      html  css  js  c++  java
  • Spring Security-- 验证码功能的实现

    spring security4 添加验证码

    http://www.itwendao.com/article/detail/165400.html

    http://www.itdadao.com/articles/c15a754492p0.html

    @Bean
    public EmbeddedServletContainerCustomizer containerCustomizer() {
        return new EmbeddedServletContainerCustomizer() {
            @Override
            public void customize(ConfigurableEmbeddedServletContainer container) {
                container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/404"));
                container.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500"));
            }
        };
    }

     http://www.cnblogs.com/xinzhao/p/4934247.html?utm_source=tuicool&utm_medium=referral

    https://stackoverflow.com/questions/29783059/redirect-in-a-filter-with-spring-boot/29789630

    在spring security的内置login处理是无法满足要求的,需要自己进行各种定制。这里介绍login中实现验证码的实现。

    实现方法

    可以有三种方法可以实现验证码的功能

    第一种

    自定义一个filter,放在SpringSecurity过滤器之前,在用户登录的时候会先经过这个filter,然后在这个filter中实现对验证码进行验证的功能,这种方法不推荐,因为它已经脱离了SpringSecurity

    第二种

    自定义一个filter让它继承自UsernamePasswordAuthenticationFilter,然后重写attemptAuthentication方法在这个方法中实现验证码的功能,如果验证码错误就抛出一个继承自AuthenticationException的验证吗错误的异常比如(CaptchaException),然后这个异常就会被SpringSecurity捕获到并将异常信息返回到前台,这种实现起来比较简单。
    譬如:LoginAuthenticationFilter.java

    import com.google.code.kaptcha.Constants;
    import com.tangcheng.app.domain.exception.CaptchaException;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
    import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class LoginAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    
        public LoginAuthenticationFilter() {
            AntPathRequestMatcher requestMatcher = new AntPathRequestMatcher("/login", "POST");
            this.setRequiresAuthenticationRequestMatcher(requestMatcher);
            this.setAuthenticationManager(getAuthenticationManager());
    //        this.setAuthenticationFailureHandler(new LoginAuthenticationFailureHandler());
        }
    
        @Override
        public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
            String verification = request.getParameter("code");
            String captcha = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
    
            if (!captcha.contentEquals(verification)) {
                throw new CaptchaException("captcha code not matched!");
            }
            return super.attemptAuthentication(request, response);
        }
    }

    java config:

    public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    LoginAuthenticationFilter loginAuthenticationFilter = new LoginAuthenticationFilter();
    loginAuthenticationFilter.setAuthenticationManager(authenticationManager());
    loginAuthenticationFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
    ....
    http.authorizeRequests()

       ...

    .addFilterBefore(loginAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
    ...


    自定义的跳转url,方便前端进行友好提示

        @Bean
        public AuthenticationFailureHandler authenticationFailureHandler() {
            ExceptionMappingAuthenticationFailureHandler failureHandler = new ExceptionMappingAuthenticationFailureHandler();
            Map<String, String> failureUrlMap = new HashMap<>();
            failureUrlMap.put(BadCredentialsException.class.getName(), LoginAuthenticationFailureHandler.PASS_ERROR_URL);
            failureUrlMap.put(CaptchaException.class.getName(), LoginAuthenticationFailureHandler.CODE_ERROR_URL);
            failureUrlMap.put(AccountExpiredException.class.getName(), LoginAuthenticationFailureHandler.EXPIRED_URL);
            failureUrlMap.put(LockedException.class.getName(), LoginAuthenticationFailureHandler.LOCKED_URL);
            failureUrlMap.put(DisabledException.class.getName(), LoginAuthenticationFailureHandler.DISABLED_URL);
            failureHandler.setExceptionMappings(failureUrlMap);
            return failureHandler;
        }
    package com.tangcheng.app.rest.security;
    
    import com.tangcheng.app.domain.exception.CaptchaException;
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * Created by tangcheng on 5/21/2017.
     */
    public class LoginAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
        public static final String PASS_ERROR_URL = "/login?error";
        public static final String CODE_ERROR_URL = "/login?code";
        public static final String EXPIRED_URL = "/login?expire";
        public static final String DISABLED_URL = "/login?disabled";
        public static final String LOCKED_URL = "/login?locked";
    
        @Override
        public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
    
            if (exception instanceof CaptchaException) {
                getRedirectStrategy().sendRedirect(request, response, CODE_ERROR_URL);
            } else {
                getRedirectStrategy().sendRedirect(request, response, PASS_ERROR_URL);
            }
        }
    }

    https://github.com/helloworldtang/spring-boot-cookbook/blob/master/app/src/main/java/com/tangcheng/app/api/rest/security/LoginAuthenticationFailureHandler.java

    或xml配置:

    <bean id="loginFilter" class="com.zrhis.system.security.DefaultUsernamePasswordAuthenticationFilter">  
        <property name="authenticationManager"  ref="authenticationManager"></property>  
        <property name="authenticationSuccessHandler">  
            <bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">  
                <property name="defaultTargetUrl" value="/index.jsp"></property>  
            </bean>  
        </property>  
        <property name="authenticationFailureHandler">  
            <bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">  
                <property name="defaultFailureUrl" value="/login.jsp"></property>  
            </bean>  
        </property>  
    </bean>  

    最后在http中加入custom-filter配置,将这个filter放在SpringSecurity的FORM_LOGIN_FILTER之前.

    <custom-filter ref="loginFilter" before="FORM_LOGIN_FILTER"/>  

    第三种

    直接替换掉SpringSecurity的UsernamePasswordAuthenticationFilter,这种比较复杂,但是更为合理,也是我现在正在用的。 
    如果用这种方法那么http 中的auto-config就必须去掉,而form-login配置也必须去掉,因为这个不需要了,里面的属性都需要我们自行注入。

    首先需要创建并配置一个login.jsp作为登录页面EntryPoint

    <bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">  
        <property name="loginFormUrl" value="/login.jsp" />  
    </bean>  

    然后在http中配置下

    <sec:http access-decision-manager-ref="accessDecisionManager"  entry-point-ref="authenticationEntryPoint">  

    然后我们来写CaptchaAuthenticationFilter,同样需要继承自UsernamePasswordAuthenticationFilter

    public class CaptchaAuthenticationFilter extends UsernamePasswordAuthenticationFilter{  
    
        public static final String SPRING_SECURITY_FORM_CAPTCHA_KEY = "j_captcha";  
        public static final String SESSION_GENERATED_CAPTCHA_KEY = Constant.SESSION_GENERATED_CAPTCHA_KEY;  
    
        private String captchaParameter = SPRING_SECURITY_FORM_CAPTCHA_KEY;  
    
        public Authentication attemptAuthentication(HttpServletRequest request,  
                HttpServletResponse response) throws AuthenticationException {  
    
            String genCode = this.obtainGeneratedCaptcha(request);  
            String inputCode = this.obtainCaptcha(request);  
            if(genCode == null)  
                throw new CaptchaException(this.messages.getMessage("LoginAuthentication.captchaInvalid"));  
            if(!genCode.equalsIgnoreCase(inputCode)){  
                throw new CaptchaException(this.messages.getMessage("LoginAuthentication.captchaNotEquals"));  
            }  
    
            return super.attemptAuthentication(request, response);  
        }  
    
        protected String obtainCaptcha(HttpServletRequest request){  
            return request.getParameter(this.captchaParameter);  
        }  
    
        protected String obtainGeneratedCaptcha (HttpServletRequest request){  
            return (String)request.getSession().getAttribute(SESSION_GENERATED_CAPTCHA_KEY);  
        }  
    
    } 

     Java Config:

    public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    CaptchaAuthenticationFilter loginAuthenticationFilter = new CaptchaAuthenticationFilter();
    loginAuthenticationFilter.setAuthenticationManager(authenticationManager());
    loginAuthenticationFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
    ....
    http.authorizeRequests()

       ...

    .addFilterBefore(loginAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
    ...


    自定义的跳转url,方便前端进行友好提示

        @Bean
        public AuthenticationFailureHandler authenticationFailureHandler() {
            ExceptionMappingAuthenticationFailureHandler failureHandler = new ExceptionMappingAuthenticationFailureHandler();
            Map<String, String> failureUrlMap = new HashMap<>();
            failureUrlMap.put(BadCredentialsException.class.getName(), LoginAuthenticationFailureHandler.PASS_ERROR_URL);
            failureUrlMap.put(CaptchaException.class.getName(), LoginAuthenticationFailureHandler.CODE_ERROR_URL);
            failureUrlMap.put(AccountExpiredException.class.getName(), LoginAuthenticationFailureHandler.EXPIRED_URL);
            failureUrlMap.put(LockedException.class.getName(), LoginAuthenticationFailureHandler.LOCKED_URL);
            failureUrlMap.put(DisabledException.class.getName(), LoginAuthenticationFailureHandler.DISABLED_URL);
            failureHandler.setExceptionMappings(failureUrlMap);
            return failureHandler;
        }

     


    或XML配置:

    在配置文件中配置CaptchaAuthenticationFilter

    <bean id="captchaAuthenticaionFilter" class="com.zrhis.system.security.CaptchaAuthenticationFilter">  
        <property name="authenticationManager" ref="authenticationManager" />  
        <property name="authenticationFailureHandler" ref="authenticationFailureHandler" />  
        <property name="authenticationSuccessHandler" ref="authenticationSuccessHandler" />  
        <property name="filterProcessesUrl" value="/login.do" />  
    </bean>  
    
    <bean id="authenticationSuccessHandler" class="com.zrhis.system.security.SimpleLoginSuccessHandler">  
        <property name="defaultTargetUrl" value="/WEB-INF/app.jsp"></property>  
        <property name="forwardToDestination" value="true"></property>  
    </bean>  
    <bean id="authenticationFailureHandler" 
          class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">  
        <property name="defaultFailureUrl" value="/login.jsp" />  
    </bean>  

    从配置文件中就可以看出来authenticationManager、authenticationFailureHandler、authenticationSuccessHandler、filterProcessesUrl等都需要我们自行注入了。 

    filterProcessesUrl定义的是登录验证的地址,默认的是j_spring_security_check这里我们改成login.do

    authenticationSuccessHandler中的defaultTargetUrl定义的是登录成功后跳转到的页面

    authenticationFailureHandler中的defaultTargetUrl定义的是登录失败后跳转到的页面

    我们的首页app.jsp在/WEB-INF下所以需要使用服务器跳转,所以需要将forwardToDestination设为true,因为客户端跳转是不能直接访问WEB-INF下的内容的。

    最后在http中将FORM_LOGIN_FILTER替换掉,最终http中完整的配置就变成了下面的内容

    <sec:http access-decision-manager-ref="accessDecisionManager"  
        entry-point-ref="authenticationEntryPoint">  
    
        <sec:access-denied-handler ref="accessDeniedHandler"/>  
    
        <sec:session-management invalid-session-url="/login.jsp" />  
    
        <sec:custom-filter ref="filterSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR"/>  
        <sec:custom-filter ref="captchaAuthenticaionFilter" position="FORM_LOGIN_FILTER"/>  
    </sec:http>  

    custom-filter中before是在这个filter之前,after是之后,position是替换。

    http://www.infocool.net/kb/WWW/201701/268891.html

     在使用Spring Security框架过程中,经常会有这样的需求,即在登录验证时,附带增加额外的数据,如验证码、用户类型等。下面将介绍如何实现。

      注:我的工程是在Spring Boot框架基础上的,使用xml方式配置的话请读者自行研究吧。

    • 实现自定义的WebAuthenticationDetails

      该类提供了获取用户登录时携带的额外信息的功能,默认实现WebAuthenticationDetails提供了remoteAddress与sessionId信息。开发者可以通过Authentication的getDetails()获取WebAuthenticationDetails。我们编写自定义类CustomWebAuthenticationDetails继承自WebAuthenticationDetails,添加我们关心的数据(以下是一个token字段)。

    package com.courses.service;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.security.web.authentication.WebAuthenticationDetails;
    
    public class CustomWebAuthenticationDetails extends WebAuthenticationDetails {
        /**
         * 
         */
        private static final long serialVersionUID = 6975601077710753878L;
        private final String token;
    
        public CustomWebAuthenticationDetails(HttpServletRequest request) {
            super(request);
            token = request.getParameter("token");
        }
    
        public String getToken() {
            return token;
        }
    
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append(super.toString()).append("; Token: ").append(this.getToken());
            return sb.toString();
        }
    }

       注:在登录页面,可将token字段放在form表单中,也可以直接加在url的参数中,进而把额外数据发送给后台。

    • 实现自定义的AuthenticationDetailsSource

      该接口用于在Spring Security登录过程中对用户的登录信息的详细信息进行填充,默认实现是WebAuthenticationDetailsSource,生成上面的默认实现WebAuthenticationDetails。我们编写类实现AuthenticationDetailsSource,用于生成上面自定义的CustomWebAuthenticationDetails。

    package com.courses.service;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.security.authentication.AuthenticationDetailsSource;
    import org.springframework.security.web.authentication.WebAuthenticationDetails;
    import org.springframework.stereotype.Component;
    
    @Component
    public class CustomAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> {
    
        @Override
        public WebAuthenticationDetails buildDetails(HttpServletRequest context) {
            return new CustomWebAuthenticationDetails(context);
        }
    }
    • 配置使用自定义的AuthenticationDetailsSource

      只要看这一句.formLogin().authenticationDetailsSource(authenticationDetailsSource)

        @Autowired
        private AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> authenticationDetailsSource;
    
        protected void configure(HttpSecurity http) throws Exception {
            http
                .headers()
                    .cacheControl()
                    .contentTypeOptions()
                    .httpStrictTransportSecurity()
                    .xssProtection()
                    .and()
                .authorizeRequests()
                    .antMatchers(
                        "/css/**",
                        "/js/**")
                    .permitAll()
                    .antMatchers("/**")
                    .authenticated()
                    .and()
                .formLogin()
                    .loginPage("/login")
                    .permitAll()
                    .defaultSuccessUrl("/todo.html", true)
                    .authenticationDetailsSource(authenticationDetailsSource)
                .and()
                    .logout()
                    .logoutUrl("/logout")
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                    .logoutSuccessUrl("/login")
                    .and()
                .csrf().disable();
        }
    • 实现自定义的AuthenticationProvider

      AuthenticationProvider提供登录验证处理逻辑,我们实现该接口编写自己的验证逻辑。

    package com.courses.service;
    
    import org.springframework.security.authentication.AuthenticationProvider;
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.stereotype.Component;
    
    @Component
    public class CustomAuthenticationProvider implements AuthenticationProvider {
        
        @Override
        public Authentication authenticate(Authentication authentication) 
                throws AuthenticationException {
            CustomWebAuthenticationDetails details = (CustomWebAuthenticationDetails) authentication.getDetails();  // 如上面的介绍,这里通过authentication.getDetails()获取详细信息
            // System.out.println(details); details.getRemoteAddress(); details.getSessionId(); details.getToken();
            // 下面是验证逻辑,验证通过则返回UsernamePasswordAuthenticationToken,
            // 否则,可直接抛出错误(AuthenticationException的子类,在登录验证不通过重定向至登录页时可通过session.SPRING_SECURITY_LAST_EXCEPTION.message获取具体错误提示信息)
            if (验证通过) {
                return UsernamePasswordAuthenticationToken(省略参数);
            } else {
                throw new AuthenticationException的子类("你要显示的错误信息")
            }
        }
    
        @Override
        public boolean supports(Class<?> authentication) {
            return authentication.equals(UsernamePasswordAuthenticationToken.class);
        }
    
    }
    • 配置使用自定义的AuthenticationProvider
        @Autowired
          private AuthenticationProvider authenticationProvider; 
      
        @Autowired
          public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
              auth.authenticationProvider(authenticationProvider);
          }

    http://www.cnblogs.com/phoenix-smile/p/5666686.html

        @Bean
        public AuthenticationFailureHandler authenticationFailureHandler() {
            ExceptionMappingAuthenticationFailureHandler failureHandler = new ExceptionMappingAuthenticationFailureHandler();
            Map<String, String> failureUrlMap = new HashMap<>();
            failureUrlMap.put(AccountExpiredException.class.getName(), LoginAuthenticationFailureHandler.EXPIRE_URL);
            failureUrlMap.put(BadCredentialsException.class.getName(), LoginAuthenticationFailureHandler.PASS_ERROR_URL);
            failureUrlMap.put(CaptchaException.class.getName(), LoginAuthenticationFailureHandler.KAPTCHA_ERROR_URL);
            failureHandler.setExceptionMappings(failureUrlMap);
            return failureHandler;
        }
    Caused by: java.lang.IllegalArgumentException: authenticationManager must be specified
        at org.springframework.util.Assert.notNull(Assert.java:134)
        at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.afterPropertiesSet(AbstractAuthenticationProcessingFilter.java:164)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624)
        ... 24 common frames omitted
    <sec:custom-filter position="FORM_LOGIN_FILTER" ref="formLoginFilter" />
    <bean id="formLoginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
      <property name="authenticationManager" ref="authenticationManager"/>
      <property name="filterProcessesUrl" value="/j_spring_security_check"/>
      <property name="usernameParameter" value="username "/>
      <property name="passwordParameter" value="password"/>
      <property name="authenticationSuccessHandler">
        <bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler ">
          <property name="alwaysUseDefaultTargetUrl" value="true"/>
          <property name="defaultTargetUrl" value="/success.jsp"/>
        </bean>
      </property>
      <property name="authenticationFailureHandler">
        <!--bean class=" org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler "/-->
        <bean id="authenticationFailureHandler" class="
     org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
          <property name="exceptionMappings">
            <props>
              <prop key="org.springframework.security.authentication.BadCredentialsException">/login/badCredentials</prop>
              <prop key="org.springframework.security.authentication.CredentialsExpiredException">/login/credentialsExpired</prop>
              <prop key="org.springframework.security.authentication.LockedException">/login/accountLocked</prop>
              <prop key="org.springframework.security.authentication.DisabledException">/login/accountDisabled</prop>
            </props>
          </property>
        </bean>
      </property>
     </bean>

    http://www.jdon.com/dl/best/spring-security.html

     最后就是最重要的security config 了:

    import com.service.user.CustomerService;
    import com.web.filter.SiteMeshFilter;
    import com.web.mySecurity.*;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.annotation.Order;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.authentication.AuthenticationProvider;
    import org.springframework.security.authentication.ProviderManager;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.crypto.password.StandardPasswordEncoder;
    import org.springframework.security.web.access.ExceptionTranslationFilter;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
    import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
    import org.springframework.web.filter.CharacterEncodingFilter;
    
    import javax.servlet.DispatcherType;
    import javax.servlet.FilterRegistration;
    import javax.servlet.ServletContext;
    import java.util.ArrayList;
    import java.util.EnumSet;
    import java.util.List;
    
    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends AbstractSecurityWebApplicationInitializer {
    
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new StandardPasswordEncoder("MD5");
        }
    
        @Autowired
        private CustomerService customerService;
    
        @Configuration
        @Order(1)
        public static class FrontendWebSecurityConfigureAdapter extends WebSecurityConfigurerAdapter {
    
            @Autowired
            private MyValidCodeProcessingFilter myValidCodeProcessingFilter;
    
            @Override
            protected void configure(HttpSecurity http) throws Exception {
                http.csrf().disable()  
                        .authorizeRequests()
                        .antMatchers("/user/login", "/user/logout").permitAll()
                        .anyRequest().authenticated()
                        .and()
                        .addFilterBefore(myValidCodeProcessingFilter, UsernamePasswordAuthenticationFilter.class)
                        .formLogin()
                        .loginPage("/user/login")
                        .and()
                        .logout()
                        .logoutUrl("/user/logout")
                        .logoutSuccessUrl("/user/login");
            }
    
        }
    
        @Bean(name = "frontAuthenticationProvider")
        public MyAuthenticationProvider frontAuthenticationProvider() {
            MyAuthenticationProvider myAuthenticationProvider = new MyAuthenticationProvider();
            myAuthenticationProvider.setUserDetailsService(customerService);
            myAuthenticationProvider.setPasswordEncoder(passwordEncoder());
            return myAuthenticationProvider;
        }
    
        @Bean
        public AuthenticationManager authenticationManager() {
            List<AuthenticationProvider> list = new ArrayList<>();
            list.add(frontAuthenticationProvider());
            AuthenticationManager authenticationManager = new ProviderManager(list);
            return authenticationManager;
        }
    
        @Bean
        public MyValidCodeProcessingFilter myValidCodeProcessingFilter(AuthenticationManager authenticationManager) {
            MyValidCodeProcessingFilter filter = new MyValidCodeProcessingFilter();
            filter.setAuthenticationManager(authenticationManager);
            filter.setAuthenticationSuccessHandler(frontAuthenticationSuccessHandler());
            filter.setAuthenticationFailureHandler(frontAuthenticationFailureHandler());
            return filter;
        }
    
        @Bean
        public FrontAuthenticationFailureHandler frontAuthenticationFailureHandler() {
            return new FrontAuthenticationFailureHandler("/user/login");
        }
    
        @Bean
        public FrontAuthenticationSuccessHandler frontAuthenticationSuccessHandler() {
            return new FrontAuthenticationSuccessHandler("/front/test");
        }
    
        @Bean
        public MyAuthenticationEntryPoint myAuthenticationEntryPoint() {
            return new MyAuthenticationEntryPoint("/user/login");
        }
    
    }

    http://www.itwendao.com/article/detail/165400.html

  • 相关阅读:
    Qt串口的使用记录
    CImage灰度化
    (记录)MSYS2+MINGW32编译ffmpeg过程
    Blas 基本函数功能
    blas中dgemm_的用法
    选择、插入、冒泡排序
    简单的页面
    中国大学排名
    爬bing 主页
    读书报告
  • 原文地址:https://www.cnblogs.com/softidea/p/6914279.html
Copyright © 2011-2022 走看看