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/>
密&emsp;码:<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
@RestController
public 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
@Component
public 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
@Component
public 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
@Component
public 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();
}

02 spring security 自定义用户认证流程的更多相关文章

  1. Spring Security 自定义登录认证(二)

    一.前言 本篇文章将讲述Spring Security自定义登录认证校验用户名.密码,自定义密码加密方式,以及在前后端分离的情况下认证失败或成功处理返回json格式数据 温馨小提示:Spring Se ...

  2. 认证与授权】Spring Security系列之认证流程解析

    上面我们一起开始了Spring Security的初体验,并通过简单的配置甚至零配置就可以完成一个简单的认证流程.可能我们都有很大的疑惑,这中间到底发生了什么,为什么简单的配置就可以完成一个认证流程啊 ...

  3. spring security 表单认证的流程

    spring security表单认证过程 表单认证过程 Spring security的表单认证过程是由org.springframework.security.web.authentication ...

  4. (二)spring Security 自定义登录页面与校验用户

    文章目录 配置 security 配置下 MVC 自定义登录页面 自定义一个登陆成功欢迎页面 效果图 小结: 使用 Spring Boot 的快速创建项目功能,勾选上本篇博客需要的功能:web,sec ...

  5. Spring Security OAuth2.0认证授权五:用户信息扩展到jwt

    历史文章 Spring Security OAuth2.0认证授权一:框架搭建和认证测试 Spring Security OAuth2.0认证授权二:搭建资源服务 Spring Security OA ...

  6. [权限管理系统(四)]-spring boot +spring security短信认证+redis整合

    [权限管理系统]spring boot +spring security短信认证+redis整合   现在主流的登录方式主要有 3 种:账号密码登录.短信验证码登录和第三方授权登录,前面一节Sprin ...

  7. Spring Security 的注册登录流程

    Spring Security 的注册登录流程 数据库字段设计 主要数据库字段要有: 用户的 ID 用户名称 联系电话 登录密码(非明文) UserDTO对象 需要一个数据传输对象来将所有注册信息发送 ...

  8. Spring Security:用户和Spring应用之间的安全屏障

    摘要:Spring Security是一个安全框架,作为Spring家族的一员. 本文分享自华为云社区<[云驻共创]深入浅出Spring Security>,作者:香菜聊游戏. 一.前言 ...

  9. Spring Security 概念基础 验证流程

    Spring Security 概念基础 验证流程 认证&授权 认证:确定是否为合法用户 授权:分配角色权限(分配角色,分配资源) 认证管理器(Authentication Manager) ...

随机推荐

  1. [转]Jenkins HTML报告样式无法显示问题解决

    原文地址: https://vwin.github.io/2018/10/11/Jenkins-HTML%E6%8A%A5%E5%91%8A%E6%A0%B7%E5%BC%8F%E6%97%A0%E6 ...

  2. Vagrant - 打造跨平台的一致开发环境

    官网 参考资料 借助 Vagrant ,可以使用 Vagrantfile 文件自动化虚拟机的安装和配置流程,方便快速的打造跨平台的统一开发环境. 1. Vagrant 是啥 Vagrant 用于构建及 ...

  3. python 微服务方案

    介绍 使用python做web开发面临的一个最大的问题就是性能,在解决C10K问题上显的有点吃力.有些异步框架Tornado.Twisted.Gevent 等就是为了解决性能问题.这些框架在性能上有些 ...

  4. tp框架 MVC模式

    一.定义 MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方 ...

  5. tp 框架目录结构

    ThinkPHP是为了简化企业级应用开发和敏捷WEB应用开发而诞生的.最早诞生于2006年初,2007年元旦正式更名为ThinkPHP,并且遵循Apache2开源协议发布.ThinkPHP从诞生以来一 ...

  6. 06 案例篇:系统的 CPU 使用率很高,但为啥却找不到高 CPU 的应用?

    上一节我讲了 CPU 使用率是什么,并通过一个案例教你使用 top.vmstat.pidstat 等工具,排查高 CPU 使用率的进程,然后再使用 perf top 工具,定位应用内部函数的问题.不过 ...

  7. 洛谷P2786 英语1(eng1)- 英语作文——map

    给一手链接 https://www.luogu.com.cn/problem/P2786 拿这道题当map模板练练手qwq #include<cstdio> #include<cst ...

  8. spring cloud gateway获取response body

    网关发起请求后,微服务返回的response的值要经过网关才发给客户端.本文主要讲解在spring cloud gateway 的过滤器中获取微服务的返回值,因为很多情况我们需要对这个返回进行处理.网 ...

  9. form-control的作用

    表单控件加上类form-control后,效果为: 宽度为100% 设置边框为浅灰色 控件具有4px的圆角 设置阴影效果,元素得到焦点时,阴影和边框效果会发生变化 设置placeholder的颜色为# ...

  10. CodeChef GCD2

    GCD2   Problem code: GCD2   Submit All Submissions   All submissions for this problem are available. ...