SpringSecurity(三):表单登陆

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception{

    
         http.formLogin()//采用form的方式提交账号密码,默认传入字段名为username,password
        .loginPage("/login.html")
        .loginProcessingUrl("/doLogin")
        .usernameParameter("uname")
        .passwordParameter("password")
        .successHandler(new LoginSuccessHandler( ))//登录成功由LoginSuccessHandler处理,LoginSuccessHandler需要继承AuthenticationSuccessHandler
        .failureHandler(new LoginFailureHandler( )) //登录失败由LoginFailureHandler处理
        .permitAll()



}

}

在Spring Security中,如果我们需要自定义配置的话,就需要编写配置类,继承WebSecurityConfigurerAdapter
(1)首先configure方法是一个链式配置,当然也可以不用链式配置,每一个属性配置完毕后从http.从新写起
(2)formLogin()表示开启表单登陆配置,loginPage用来指定登陆页面地址,usernameParameter指定表单传入的账号的属性名,passwordParameter指定表单传入的密码的属性名,loginProcessingUrl用来配置登录接口地址,需要注意的是usernameParameter,passwordParameter,passwordParameter需要和前端表格中一样,successHandler表明登录成功后的处理器,failureHandler表明登录失败的处理器,permitAll表明跟登陆有关的页面和接口不做拦截,defaultSuccessUrl表明登陆成功后的跳转到之前访问的地址,successForwardUrl表明登陆成功后会跳转到指定的地址,failureUrl表明登陆失败的跳转地址

源码分析

无论是defaultSuccessUrl,successForwardUrl都是调用了AuthenticationSuccessHandler接口的实例(SavedRequestAwareAuthenticationSuccessHandler 和 ForwardAuthenticationSuccessHandler)

SavedRequestAwareAuthenticationSuccessHandler 类

defaultSuccessUrl调用的就是这个类的实例,我们看一下源码

public class SavedRequestAwareAuthenticationSuccessHandler extends
        SimpleUrlAuthenticationSuccessHandler {
    protected final Log logger = LogFactory.getLog(this.getClass());
 
    private RequestCache requestCache = new HttpSessionRequestCache();
 
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
            HttpServletResponse response, Authentication authentication)
            throws ServletException, IOException {
        //这里取出了一个request
        SavedRequest savedRequest = requestCache.getRequest(request, response);
 
        if (savedRequest == null) {
            super.onAuthenticationSuccess(request, response, authentication);
 
            return;
        }
        String targetUrlParameter = getTargetUrlParameter();
        if (isAlwaysUseDefaultTargetUrl()
                || (targetUrlParameter != null && StringUtils.hasText(request
                        .getParameter(targetUrlParameter)))) {
            requestCache.removeRequest(request, response);
            super.onAuthenticationSuccess(request, response, authentication);
 
            return;
        }
 
        clearAuthenticationAttributes(request);
 
        // Use the DefaultSavedRequest URL !!关键的一句!!
        String targetUrl = savedRequest.getRedirectUrl();
        logger.debug("Redirecting to DefaultSavedRequest Url: " + targetUrl);
        // 这里有一个很明显的跳转操作,追踪targetUrl怎么来的
        getRedirectStrategy().sendRedirect(request, response, targetUrl);
    }
 
    public void setRequestCache(RequestCache requestCache) {
        this.requestCache = requestCache;
    }
}

(1)先从requestCache取出之前缓存的请求,如果没有,就说明用户在登录页面之前没有访问其他页面,就调用父类的onAuthenticationSuccess方法,跳转到defaultSuccessUrl指定的地址
(2)如果targetUrl (用户显示定义 http://localhost:8080/login?target=/hello)存在,则登录成功后跳转到targetUrl中,如果alwaysUseDefaultTargetUrl为true,则登陆成功后跳转到defaultSuccessUrl指定的地址
(3)以上条件都不满足,登陆成功后则从requestCache取出之前缓存的请求,进行跳转

自定义登陆成功/失败处理器

在前后端分离的项目中,我们需要后端返回的是json数据,而不是进行页面的跳转,此时就需要我们自定义一个AuthenticationSuccessHandler接口的实现类,并通过successHandler/failureHandler 指定

AuthenticationSuccessHandler接口的核心方法就是onAuthenticationSuccess

@Comp
public class LoginSuccessHandler implements AuthenticationSuccessHandler{
@Override
public void onAuthenticationSuccess(HttpServletRequest request,HttpServletResponse response,Authentication authentication) throws IOException,ServletException{
//这里返回我们封装好的统一结果类实例即可

}

}

登录失败处理器同理,不过继承的是AuthenticationFailureHandler接口

注销登录

http.logout()
    .logoutUrl("/logout")
    .invaildateHttpSession(true)
    .clearAuthentication(true)
    .logoutSuccessUrl("/mylogin.html")

(1).logout()方法表示开启注销登录功能
(2).logoutUrl()制定了注销登录的请求地址,默认是GET请求
(3).invaildateHttpSession 表明是否使session失效,默认为true
(4).clearAuthentication表明是否消除认证信息,默认为true
(5).logoutSuccessUrl()表明注销成功后的跳转地址

也可以使用自定义的登出成功处理器

.logoutSuccessHandler(new LogoutSuccessHandler() {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//返回我们的统一结果封装类

                }
            })
上一篇:2021年来看看Java的发展,Java校招面试指南


下一篇:SpringSecurity