013 个性化用户认证流程
Posted 曹军
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了013 个性化用户认证流程相关的知识,希望对你有一定的参考价值。
一:任务
1.任务
自定义登录页面
自定义登录成功处理
自定义登录失败处理
二:自定义登录页面
1.说明
在security中,默认的登录处理是
2.BrowserSecurityConfig
这里从新定义登录的页面,与登录方法
1 package com.cao.security.browser; 2 3 import org.springframework.context.annotation.Bean; 4 import org.springframework.context.annotation.Configuration; 5 import org.springframework.security.config.annotation.web.builders.HttpSecurity; 6 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 7 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 8 import org.springframework.security.crypto.password.PasswordEncoder; 9 /** 10 * 覆盖掉security原有的配置 11 * @author dell 12 * 13 */ 14 @Configuration 15 public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter{ 16 @Override 17 protected void configure(HttpSecurity http) throws Exception { 18 //表单登陆的一个安全认证环境 19 http.formLogin() 20 .loginPage("/index.html") 21 .loginProcessingUrl("/authentication/form") 22 // http.httpBasic() 23 .and() 24 .authorizeRequests() //请求授权 25 .antMatchers("/index.html").permitAll() //这个url不需要认证 26 .anyRequest() //任何请求 27 .authenticated() //都需要认证 28 .and() 29 .csrf().disable(); //去掉csrf的防护 30 31 } 32 33 @Bean 34 public PasswordEncoder passwordEncoder() { 35 return new BCryptPasswordEncoder(); 36 } 37 }
3.index.htnl
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>登录</title> 6 </head> 7 <body> 8 <h2>标准登录页面</h2> 9 <h3>表单登录</h3> 10 <form action="/authentication/form" method="post"> 11 <table> 12 <tr> 13 <td>用户名</td> 14 <td><input type="text" name="username"></td> 15 </tr> 16 <tr> 17 <td>密码</td> 18 <td><input type="password" name="password"></td> 19 </tr> 20 <tr> 21 <td colspan="2"><button type="submit">登录</button></td> 22 </tr> 23 </table> 24 </form> 25 </body> 26 </html>
4.登录界面
三:优化
1.问题
现在的处理是接收到html请求,然后直接跳转到了html登录页面
因为,这里优化一下比较好,做到统一处理。
现在的优化方法如下:
2.先修改配置类
这里说明,进入的显示控制类,然后由控制类进行决定走哪里
这里还包含了自定义的url不进过认证,这里的程序先粘贴过来了。
1 package com.cao.security.browser; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.context.annotation.Bean; 5 import org.springframework.context.annotation.Configuration; 6 import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 8 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 9 import org.springframework.security.crypto.password.PasswordEncoder; 10 11 import com.cao.security.core.properties.SecurityProperties; 12 /** 13 * 覆盖掉security原有的配置 14 * @author dell 15 * 16 */ 17 @Configuration 18 public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter{ 19 @Autowired 20 private SecurityProperties securityProperties; 21 22 @Override 23 protected void configure(HttpSecurity http) throws Exception { 24 //表单登陆的一个安全认证环境 25 http.formLogin() 26 .loginPage("/authentication/require") 27 .loginProcessingUrl("/authentication/form") 28 // http.httpBasic() 29 .and() 30 .authorizeRequests() //请求授权 31 .antMatchers("/authentication/require", 32 securityProperties.getBrowser().getLoginPage()).permitAll() //这个url不需要认证,包含自定义的登录页 33 .anyRequest() //任何请求 34 .authenticated() //都需要认证 35 .and() 36 .csrf().disable(); //去掉csrf的防护 37 38 } 39 40 @Bean 41 public PasswordEncoder passwordEncoder() { 42 return new BCryptPasswordEncoder(); 43 } 44 }
3.控制类
这里直接读取的是可以自定义的页面,后续会添加如何引入的。
1 /** 2 * 3 */ 4 package com.cao.security.browser; 5 6 import java.io.IOException; 7 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 import org.apache.commons.lang.StringUtils; 12 import org.slf4j.Logger; 13 import org.slf4j.LoggerFactory; 14 import org.springframework.beans.factory.annotation.Autowired; 15 import org.springframework.http.HttpStatus; 16 import org.springframework.security.web.DefaultRedirectStrategy; 17 import org.springframework.security.web.RedirectStrategy; 18 import org.springframework.security.web.savedrequest.HttpSessionRequestCache; 19 import org.springframework.security.web.savedrequest.RequestCache; 20 import org.springframework.security.web.savedrequest.SavedRequest; 21 import org.springframework.web.bind.annotation.RequestMapping; 22 import org.springframework.web.bind.annotation.ResponseStatus; 23 import org.springframework.web.bind.annotation.RestController; 24 25 import com.cao.security.browser.support.SimpleResponse; 26 import com.cao.security.core.properties.SecurityProperties; 27 28 /** 29 * @author dell 30 * 31 */ 32 @RestController 33 public class BrowserSecurityController { 34 private Logger logger=LoggerFactory.getLogger(getClass()); 35 //拿到引气身份跳转的请求 36 //因为在跳转之前,security会将请求缓存到session中 37 private RequestCache requestCache=new HttpSessionRequestCache(); 38 39 //跳转 40 private RedirectStrategy redirectStrategy=new DefaultRedirectStrategy(); 41 42 //方便读取自定义登录页的配置项 43 @Autowired 44 private SecurityProperties securityProperties; 45 46 /** 47 * 当需要身份认证的时候,跳转到这里 48 * @param request 49 * @param response 50 * @return 51 * @throws Exception 52 */ 53 @RequestMapping("/authentication/require") 54 @ResponseStatus(code=HttpStatus.UNAUTHORIZED) 55 public SimpleResponse requiredAuthentication(HttpServletRequest request,HttpServletResponse response) throws Exception { 56 SavedRequest saveRequest=requestCache.getRequest(request, response); 57 if(saveRequest!=null) { 58 String target=saveRequest.getRedirectUrl(); 59 logger.info("引发跳转的请求:"+target); 60 if(StringUtils.endsWithIgnoreCase(target, ".html")) { 61 //跳转到一个自定义的登录页 62 redirectStrategy.sendRedirect(request, response, securityProperties.getBrowser().getLoginPage()); 63 } 64 } 65 return new SimpleResponse("访问的服务需要身份认证,请引导到登录页"); 66 } 67 }
返回值,需要一个类。SimpleResponse.java
1 package com.cao.security.browser.support; 2 3 public class SimpleResponse { 4 public SimpleResponse(Object content) { 5 this.content=content; 6 } 7 8 private Object content; 9 10 public Object getContent() { 11 return content; 12 } 13 14 public void setContent(Object content) { 15 this.content = content; 16 } 17 18 }
4.系统配置封装
方便统一管理用户的配置项。
5.新建SecurityProperties
这里是最外层的一层包装
同时。这里需要放入在core的项目下。
首先,这里会读取的是jun.security开头的配置项,同时会把配置项的第三个字段读取到同browser相同的类中。所以,后续还要写browser的类。
1 package com.cao.security.core.properties; 2 3 import org.springframework.boot.context.properties.ConfigurationProperties; 4 5 @ConfigurationProperties(prefix="jun.security") 6 public class SecurityProperties { 7 private BrowserProperties browser=new BrowserProperties(); 8 9 public BrowserProperties getBrowser() { 10 return browser; 11 } 12 13 public void setBrowser(BrowserProperties browser) { 14 this.browser = browser; 15 } 16 17 18 }
6.BrowserProperties.java
这里要读取的是配置项的第四个字段,这里需要的是不能乱写。
loginPage这里有一个默认值,如果用户没有给,就使用初始化的值。
1 package com.cao.security.core.properties; 2 3 public class BrowserProperties { 4 5 private String loginPage="/index.html"; 6 7 public String getLoginPage() { 8 return loginPage; 9 } 10 11 public void setLoginPage(String loginPage) { 12 this.loginPage = loginPage; 13 } 14 15 }
7.SecurityConfig.java
这里是的配置项的类生效,这里的类写最外层的即可。
1 package com.cao.security.core.properties; 2 3 import org.springframework.boot.context.properties.EnableConfigurationProperties; 4 import org.springframework.context.annotation.Configuration; 5 6 @Configuration 7 //让SecurityProperties读取器生效 8 @EnableConfigurationProperties(SecurityProperties.class) 9 public class SecurityCoreConfig { 10 11 }
8.自定义的配置项
这里写在demo项目中。
1 ##JDBC 2 spring.datasource.driver-class-name = com.mysql.jdbc.Driver 3 spring.datasource.url= jdbc:mysql://127.0.0.1:3308/test?useUnicode=yes&characterEncoding=UTF-8&useSSL=false 4 spring.datasource.username = root 5 spring.datasource.password = 123456 6 7 ##session store type 8 spring.session.store-type=none 9 10 ##server port 11 #server.port=8060 12 13 ##security login 14 #security.basic.enabled = false 15 16 jun.security.browser.loginPage=/newIndex.html
9.效果
访问:http://localhost:8080/user/
访问:newIndex.html
访问:http://localhost:8080/index.html
四:登录成功后的处理
1.修改初始化的配置
主要是说明登录成功后使用自定义的类
1 package com.cao.security.browser; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.context.annotation.Bean; 5 import org.springframework.context.annotation.Configuration; 6 import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 8 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 9 import org.springframework.security.crypto.password.PasswordEncoder; 10 import org.springframework.security.web.authentication.AuthenticationSuccessHandler; 11 12 import com.cao.security.browser.authentication.BrowserAuthenticationSucceswsHandler; 13 import com.cao.security.core.properties.SecurityProperties; 14 /** 15 * @Description 覆盖掉security原有的配置 16 * @author dell 17 * 18 */ 19 @Configuration 20 public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter{ 21 //获取自定义的登录页面 22 @Autowired 23 private SecurityProperties securityProperties; 24 25 //使用自己的登录成功后的处理类 26 @Autowired 27 private AuthenticationSuccessHandler browserAuthenticationSucceswsHandler; 28 29 30 @Override 31 protected void configure(HttpSecurity http) throws Exception { 32 //表单登陆的一个安全认证环境 33 http.formLogin() 34 .loginPage("/authentication/require") 35 .loginProcessingUrl("/authentication/form") 36 .successHandler(browserAuthenticationSucceswsHandler) 37 // http.httpBasic() 38 .and() 39 .authorizeRequests() //请求授权 40 .antMatchers("/authentication/require", 41 securityProperties.getBrowser().getLoginPage()).permitAll() //这个url不需要认证,包含自定义的登录页 42 .anyRequest() //任何请求 43 .authenticated() //都需要认证 44 .and() 45 .csrf().disable(); //去掉csrf的防护 46 47 } 48 49 @Bean 50 public PasswordEncoder passwordEncoder() { 51 return new BCryptPasswordEncoder(); 52 } 53 }
2.登录成功处理类
1 package com.cao.security.browser.authentication; 2 3 import java.io.IOException; 4 5 import javax.servlet.ServletException; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 import org.slf4j.Logger; 10 import org.slf4j.LoggerFactory; 11 import org.springframework.beans.factory.annotation.Autowired; 12 import org.springframework.security.core.Authentication; 13 import org.springframework.security.web.authentication.AuthenticationSuccessHandler; 14 import org.springframework.stereotype.Component; 15 16 import com.fasterxml.jackson.databind.ObjectMapper; 17 18 @Component(value="browserAuthenticationSucceswsHandler") 19 public class BrowserAuthenticationSucceswsHandler implements AuthenticationSuccessHandler { 20 private Logger logger=LoggerFactory.getLogger(getClass()); 21 22 @Autowired 23 private ObjectMapper objectMapper; 24 25 /** 26 * @Description 登录成功会被调用 27 */ 28 @Override 29 public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, 30 Authentication authentication) throws IOException, ServletException { 31 //Authentication 封装了认证信息 32 logger.info("登录成功"); 33 response.setContentType("application/json;charset=UTF-8"); 34 //将authentication转为json字符串 35 response.getWriter().write(objectMapper.writeValueAsString(authentication)); 36 } 37 38 }
3.效果
登录成功后的authentication的json格式如下:
五:登录失败后的处理
1.修改初始化的配置
1 package com.cao.security.browser; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.context.annotation.Bean; 5 import org.springframework.context.annotation.Configuration; 6 import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 8 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 9 import org.springframework.security.crypto.password.PasswordEncoder; 10 import org.springframework.security.web.authentication.AuthenticationSuccessHandler; 11 12 import com.cao.security.browser.authentication.BrowserAuthenticationFailHandler; 13 import com.cao.security.browser.authentication.BrowserAuthenticationSucceswsHandler; 14 import com.cao.security.core.properties.SecurityProperties; 15 /** 16 * @Description 覆盖掉security原有的配置 17 * @author dell 18 * 19 */ 20 @Configuration 21 public class BrowserSecurityCo以上是关于013 个性化用户认证流程的主要内容,如果未能解决你的问题,请参考以下文章
VSCode自定义代码片段15——git命令操作一个完整流程
VSCode自定义代码片段15——git命令操作一个完整流程
spring-security 个性化用户认证流程——自定义登录页面(可配置)