时间:2021-05-19
1.自定义登录页面
(1)首先在static目录下面创建login.html
注意:springboot项目默认可以访问resources/resources,resources/staic,resources/public目录下面的静态文件
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>登录页面</title></head><body><form action="/auth/login" method="post"> 用户名:<input type="text" name="username"> <br/> 密 码:<input type="password" name="password"> <br/> <input type="submit" value="登录"></form></body></html>(2)在spring securiy配置类中做如下配置
@Override protected void configure(HttpSecurity http) throws Exception { http.formLogin() // 指定自定义登录页面 .loginPage("/login.html") // 登录url .loginProcessingUrl("/auth/login") .and() .authorizeRequests() // 添加一个url匹配器,如果匹配到login.html,就授权 .antMatchers("/login.html").permitAll() .anyRequest() .authenticated() .and() // 关闭spring security默认的防csrf攻击 .csrf().disable(); }(3)测试
略
(4)存在的问题
<1>作为可以复用的登录模块,我们应该提供个性化的登录页面,也就是说不能写死只跳转到login.html。
此问题比较好解决,使用可配置的登录页面,默认使用login.html即可。
<2> 请求跳转到login.html登录页面,貌似没有什么问题,但作为restful风格的接口,一般响应的都是json数据格式,尤其是app请求。
解决思想:用户发起数据请求 --> security判断是否需要身份认证 ----->跳转到一个自定义的controller方法 ------>在该方法内判断是否是html发起的请求,如果是,就跳转到login.html,如果不是,响应一个json格式的数据,说明错误信息。
自定义Controller
@Slf4j@RestControllerpublic class LoginController { /** * 请求缓存 */ private RequestCache requestCache = new HttpSessionRequestCache(); /** * 重定向工具类 */ private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); /** * 如果配置的登录页就使用配置的登录面,否则使用默认的登录页面 */// @Value("${xxxx:defaultLoginPage}")// private String standardLoginPage; private String standardLoginPage = "/login.html"; // 登录页 /** * 用户身份认证方法 */ @GetMapping("/user/auth") @ResponseStatus(code = HttpStatus.UNAUTHORIZED) // 返回状态 public ResponseData login(HttpServletRequest request, HttpServletResponse response) throws IOException { SavedRequest savedRequest = requestCache.getRequest(request, response); if (savedRequest != null) { String targetUrl = savedRequest.getRedirectUrl(); log.info("请求是:" + targetUrl); // 如果请求是以html结尾 if (StringUtils.endsWithIgnoreCase(targetUrl, ".html")) { redirectStrategy.sendRedirect(request, response, standardLoginPage); } } return new ResponseData("该请求需要登录,js拿到我的响应数据后,是否需要跳转到登录页面你自己看着办吧?"); }}spring security给该controller的login方法授权
@Override protected void configure(HttpSecurity http) throws Exception { http.formLogin() // 先进controller中去 .loginPage("/user/auth") // 指定自定义登录页面 .loginPage("/login.html") // 登录url .loginProcessingUrl("/auth/login") .and() .authorizeRequests() // 该controller需要授权 .antMatchers("/user/auth").permitAll() // 添加一个url匹配器,如果匹配到login.html,就授权 .antMatchers("/login.html").permitAll() .anyRequest() .authenticated() .and() // 关闭spring security默认的防csrf攻击 .csrf().disable(); }这样子就行了!!!
2. 自定义登录成功处理(返回json)
(1)实现AuthenticationSuccessHandler.java
import com.fasterxml.jackson.databind.ObjectMapper;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.http.MediaType;import org.springframework.security.core.Authentication;import org.springframework.security.web.authentication.AuthenticationSuccessHandler;import org.springframework.stereotype.Component;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@Slf4j@Componentpublic class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler { @Autowired private ObjectMapper objectMapper; /** * Called when a user has been successfully authenticated. * @param request * @param response * @param authentication * @throws IOException * @throws ServletException */ @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { log.info("登录成功!!!"); // 将登录成功的信息写到前端 response.setContentType(MediaType.APPLICATION_JSON_VALUE); response.getWriter().write(objectMapper.writeValueAsString(authentication)); }}(2)修改security配置类
@Autowired private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler; @Override protected void configure(HttpSecurity http) throws Exception { http.formLogin() // 先进controller中去 .loginPage("/user/auth") // 指定自定义登录页面 .loginPage("/login.html") // 登录url .loginProcessingUrl("/auth/login") .successHandler(myAuthenticationSuccessHandler) .and() .authorizeRequests() // 该controller需要授权 .antMatchers("/user/auth").permitAll() // 添加一个url匹配器,如果匹配到login.html,就授权 .antMatchers("/login.html").permitAll() .anyRequest() .authenticated() .and() // 关闭spring security默认的防csrf攻击 .csrf().disable(); }(3)测试
说明:authentication对象中包含的信息,会因为登录方式的不同而发生改变
3.自定义登录失败处理(返回json)
实现AuthenticationFailureHandler.java接口即可,跟登录成败处理配置一样。
4.自定义登录成功处理逻辑
以上的登录成功或失败的返回的都是json,但是在某些情况下,就是存在着登录成功或者失败进行页面跳转(spring security默认的处理方式),那么这种返回json的方式就不合适了。所以,我们应该做得更灵活,做成可配置的。
对于登录成功逻辑而言只需要对MyAuthenticationSuccessHandler.java稍做修改就行,代码如下所示:
/** * SavedRequestAwareAuthenticationSuccessHandler spring security 默认的成功处理器 */@Slf4j@Componentpublic class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { @Autowired private ObjectMapper objectMapper; /** * 配置的登录方式 */// @Value("${xxx:默认方式}") private String loginType = "JSON"; /** * Called when a user has been successfully authenticated. */ @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { log.info("登录成功!!!"); // 如果配置的登录方式是JSON,就返回json数据 if ("JSON".equals(loginType)) { // 将登录成功的信息写到前端 response.setContentType(MediaType.APPLICATION_JSON_VALUE); response.getWriter().write(objectMapper.writeValueAsString(authentication)); } else { // 否则就使用默认的跳转方式 super.onAuthenticationSuccess(request,response,authentication); } }}5.自定义登录失败处理逻辑
同登录成功类似,具体代码如下:
import com.fasterxml.jackson.databind.ObjectMapper;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.http.HttpStatus;import org.springframework.http.MediaType;import org.springframework.security.core.AuthenticationException;import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;import org.springframework.stereotype.Component;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@Slf4j@Componentpublic class MySimpleUrlAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { @Autowired private ObjectMapper objectMapper; /** * 配置的登录方式 */// @Value("${xxx:默认方式}") private String loginType = "JSON"; @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { log.info("登录失败!!!"); // 如果配置的登录方式是JSON,就返回json数据 if ("JSON".equals(loginType)) { // 将登录成功的信息写到前端 response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.setContentType(MediaType.APPLICATION_JSON_VALUE); response.getWriter().write(objectMapper.writeValueAsString(exception)); } else { // 否则就使用默认的跳转方式,跳转到一个错误页面 super.onAuthenticationFailure(request,response,exception); } }}@Autowired private MySimpleUrlAuthenticationFailureHandler mySimpleUrlAuthenticationFailureHandler; @Override protected void configure(HttpSecurity http) throws Exception { http.formLogin() // 先进controller中去 .loginPage("/user/auth") // 指定自定义登录页面 .loginPage("/login.html") // 登录url .loginProcessingUrl("/auth/login") .successHandler(myAuthenticationSuccessHandler) .failureHandler(mySimpleUrlAuthenticationFailureHandler) .and() .authorizeRequests() // 该controller需要授权 .antMatchers("/user/auth").permitAll() // 添加一个url匹配器,如果匹配到login.html,就授权 .antMatchers("/login.html").permitAll() .anyRequest() .authenticated() .and() // 关闭spring security默认的防csrf攻击 .csrf().disable(); }以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
自定义登录filter上篇文章我们说到,对于用户的登录,security通过定义一个filter拦截login路径来实现的,所以我们要实现自定义登录,需要自己定
前言:前面几篇讲了自定义控件绘制原理Android自定义控件基本原理详解(一),Android自定义控件之自定义属性(二),Android自定义控件之自定义组合
前言:前两篇介绍了自定义控件的基础原理Android自定义控件基本原理详解(一)、Android自定义控件之自定义属性(二)。今天重点介绍一下如何通过自定义组合
Java中自定义异常详解及实例代码下面做了归纳总结,欢迎批评指正自定义异常classChushulingExceptionextendsException{pu
AndroidViewPagerIndicator详解及实例代码关于自定义View的属性零碎知识自定义View和自定义属性的知识不再此提及,这里着重说的是属性在