spring security中的默认登录页源码分析
这篇文章主要讲解了"spring security中的默认登录页源码分析",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"spring security中的默认登录页源码分析"吧!
springboot项目依赖
org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-security
在项目中随意编写一个接口,然后进行访问
@GetMapping("/")public String hello() { return "hello, spring security";}在tomcat默认端口8080,localhost:8080 下访问该接口,spring security会帮我们将路径重定向到默认的登录页

那么这个默认页是怎么来的呢?
原来Spring Security有一个默认的WebSecurityConfigurerAdapter,发现其中有一个init方法,于是在这个方法打了断点,在应用启动的时候进行跟踪。
跟踪getHttp()方法,this.disableDefaults变量默认为false,意味着将会执行applyDefaultConfiguration(this.http);方法。查看applyDefaultConfiguration方法
public void init(WebSecurity web) throws Exception { // 首先配置security要拦截的哪些http请求 HttpSecurity http = getHttp(); web.addSecurityFilterChainBuilder(http).postBuildAction(() -> { FilterSecurityInterceptor securityInterceptor = http.getSharedObject(FilterSecurityInterceptor.class); web.securityInterceptor(securityInterceptor); });}protected final HttpSecurity getHttp() throws Exception { if (this.http != null) { return this.http; } AuthenticationEventPublisher eventPublisher = getAuthenticationEventPublisher(); this.localConfigureAuthenticationBldr.authenticationEventPublisher(eventPublisher); AuthenticationManager authenticationManager = authenticationManager(); this.authenticationBuilder.parentAuthenticationManager(authenticationManager); Map, Object> sharedObjects = createSharedObjects(); this.http = new HttpSecurity(this.objectPostProcessor, this.authenticationBuilder, sharedObjects); if (!this.disableDefaults) { // 默认的配置将会走这个分支 applyDefaultConfiguration(this.http); ClassLoader classLoader = this.context.getClassLoader(); List defaultHttpConfigurers = SpringFactoriesLoader .loadFactories(AbstractHttpConfigurer.class, classLoader); for (AbstractHttpConfigurer configurer : defaultHttpConfigurers) { this.http.apply(configurer); } } configure(this.http); return this.http; } 查看applyDefaultConfiguration(this.http)方法,发现http对象new了一个DefaultLoginPageConfigurer对象属性,
private void applyDefaultConfiguration(HttpSecurity http) throws Exception { http.csrf(); http.addFilter(new WebAsyncManagerIntegrationFilter()); http.exceptionHandling(); http.headers(); http.sessionManagement(); http.securityContext(); http.requestCache(); http.anonymous(); http.servletApi(); http.apply(new DefaultLoginPageConfigurer<>()); http.logout();}查看DefaultLoginPageConfigurer类定义,发现它在初始化的同时,它也初始化了自己的2个私有成员变量,分别是DefaultLoginPageGeneratingFilter默认登录页面生成Filter,DefaultLogoutPageGeneratingFilter默认登录页面Filter, 名字起得很好,见名知意,我们马山知道这2个类的含义。
查看DefaultLoginPageGeneratingFilter的类成员变量,发现定义了一系列跟登录有关的成员变量,包括登录、登录等路径,默认的登录页面路径是"/login"
public class DefaultLoginPageGeneratingFilter extends GenericFilterBean { public static final String DEFAULT_LOGIN_PAGE_URL = "/login"; public static final String ERROR_PARAMETER_NAME = "error"; private String loginPageUrl; private String logoutSuccessUrl; private String failureUrl; private boolean formLoginEnabled; .....再结合类名思考,发现是个Filter类,那么它们应该都会重新Filter的doFilter(ServletRequest request, ServletResponse response, FilterChain chain)方法,我们查看一下DefaultLoginPageConfigurer类的``doFilter方法,果然,在doFilter`方法中发现了生成默认登录页面的方法。
private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { // 判断当前的请求是否被认证通过 boolean loginError = isErrorPage(request); boolean logoutSuccess = isLogoutSuccess(request); if (isLoginUrlRequest(request) || loginError || logoutSuccess) { // 当前请求认证失败的话,将会执行这个分支 String loginPageHtml = generateLoginPageHtml(request, loginError, logoutSuccess); response.setContentType("text/html;charset=UTF-8"); response.setContentLength(loginPageHtml.getBytes(StandardCharsets.UTF_8).length); response.getWriter().write(loginPageHtml); return; } chain.doFilter(request, response);}private String generateLoginPageHtml(HttpServletRequest request, boolean loginError, boolean logoutSuccess) { String errorMsg = "Invalid credentials"; if (loginError) { HttpSession session = request.getSession(false); if (session != null) { AuthenticationException ex = (AuthenticationException) session .getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION); errorMsg = (ex != null) ? ex.getMessage() : "Invalid credentials"; } } String contextPath = request.getContextPath(); StringBuilder sb = new StringBuilder(); sb.append("\n"); sb.append("\n"); sb.append(" \n"); sb.append(" \n"); sb.append(" \n"); sb.append(" \n"); sb.append(" \n"); sb.append(" Please sign in \n"); sb.append(" \n"); sb.append(" \n"); sb.append(" \n"); sb.append(" \n"); sb.append(" \n"); if (this.formLoginEnabled) { sb.append(" \n"); } if (this.openIdEnabled) { sb.append("
登录
方法
页面
源码
分析
变量
路径
学习
内容
分支
对象
成员
接口
项目
生成
认证
跟踪
配置
原始
代码
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
咖啡网
深圳市人人互联网科技有限公司
博彦科技互联网金融
互联网科技工作委员会
A股互联网金融科技公司
工业互联网科技新基建
互联网扶贫科技
智网互联网科技
互联网科技作文
互联网科技论文
苏州大垚互联网科技
广州紫鲸互联网科技
卓越科技互联网 招聘
港股科技和互联网
杭州壁岐互联网科技有限公司
广州市恰铎互联网科技有限公司
中国科技创新与世界互联网大会
新氧科技和美国互联网有关系吗
广州智享互联网科技
北京瑞云互联网科技有限公司
互联网金融科技
美国互联网保险保险科技
银优互联网科技有限公司
翼展科技 首家互联网医院
互联网科技和法律行业
互联网科技资金流入
互联网科技快讯热点
求路客互联网科技电话
恒生科技指数 中概互联网
互联网科技创新创业项目