Spring Boot Shiro权限管理--自定义 FormAuthenticationFilter验证码整合
思路
shiro使用FormAuthenticationFilter进行表单认证,验证校验的功能应该加在FormAuthenticationFilter中,在认证之前进行验证码校验。
需要写FormAuthenticationFilter的子类,继承FormAuthenticationFilter,改写它的认证方法,在认证之前进行验证码校验。
自定义FormAuthenticationFilter
package com.example.config.shiro; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession; import org.apache.shiro.web.filter.authc.FormAuthenticationFilter; public class CustomFormAuthenticationFilter extends FormAuthenticationFilter{
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
// 在这里进行验证码的校验
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpSession session = httpServletRequest.getSession(); // 取出验证码
String validateCode = (String) session.getAttribute("validateCode");
// 取出页面的验证码
// 输入的验证和session中的验证进行对比
String randomcode = httpServletRequest.getParameter("randomcode");
if (randomcode != null && validateCode != null && !randomcode.equals(validateCode)) {
// 如果校验失败,将验证码错误失败信息,通过shiroLoginFailure设置到request中
httpServletRequest.setAttribute("shiroLoginFailure", "kaptchaValidateFailed");//自定义登录异常
// 拒绝访问,不再校验账号和密码
return true;
}
return super.onAccessDenied(request, response);
}
}
在ShiroConfiguration.java中的shiroFilter方法注入自定义FormAuthenticationFilter
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
System.out.println("ShiroConfiguration.shiroFilter()");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();//获取filters
filters.put("authc", new CustomFormAuthenticationFilter());//将自定义 的FormAuthenticationFilter注入shiroFilter中
// 必须设置SecuritManager
shiroFilterFactoryBean.setSecurityManager(securityManager); // 拦截器
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); // 配置退出过滤器,其中的具体代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/logout", "logout");
//验证码可以匿名访问
filterChainDefinitionMap.put("/validatecodeServlet", "anon"); //配置记住我或认证通过可以访问的地址 filterChainDefinitionMap.put("/index", "user");
filterChainDefinitionMap.put("/", "user"); // <!-- 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
// <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问--> filterChainDefinitionMap.put("/**", "authc"); // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/login");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/index");
// 未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/403"); shiroFilterFactoryBean
.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean; }
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();//获取filters
filters.put("authc", new CustomFormAuthenticationFilter());//将自定义 的FormAuthenticationFilter注入shiroFilter中
登录方法加入自定义的异常kaptchaValidateFailed
@RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(HttpServletRequest request, Map<String, Object> map) {
System.out.println("HomeController.login");
// 登录失败从request中获取shiro处理的异常信息
// shiroLoginFailure:就是shiro异常类的全类名
String exception = (String) request.getAttribute("shiroLoginFailure");
String msg = "";
if (exception != null) {
if (UnknownAccountException.class.getName().equals(exception)) {
System.out.println("UnknownAccountException -->帐号不存在:");
msg = "UnknownAccountException -->帐号不存在:";
} else if (IncorrectCredentialsException.class.getName().equals(exception)) {
System.out.println("IncorrectCredentialsException -- > 密码不正确:");
msg = "IncorrectCredentialsException -- > 密码不正确:";
} else if ("kaptchaValidateFailed".equals(exception)) {
System.out.println("kaptchaValidateFailed -- > 验证码错误");
msg = "kaptchaValidateFailed -- > 验证码错误";
} else {
msg = "else >> " + exception;
System.out.println("else -- >" + exception);
}
}
map.put("msg", msg);
// 此方法不处理登录成功,由shiro进行处理.
return "/login";
}
login.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<meta charset="UTF-8" />
<title>Insert title here</title>
</head>
<body>
错误信息:<h4 th:text="${msg}"></h4>
<form action="" method="post">
<p>账号:<input type="text" name="username" value="admin"/></p>
<p>密码:<input type="text" name="password" value="123456"/></p>
<p>验证码:<input type="text" name="randomcode"/>
<img th:src="@{/validatecodeServlet}" height="20px" width="60px" onclick="random(this)"/></p>
<P><input type="checkbox" name="rememberMe" />记住我</P>
<p><input type="submit" value="登录"/></p>
</form>
<script th:inline="javascript">
function random(tmp){
tmp.src="/validatecodeServlet?rnd="+Math.random();
}
</script>
</body>
</html>
验证码Servlet
package com.example.servlet; import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random; import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; @WebServlet(urlPatterns="/validatecodeServlet")
public class ValidatecodeServlet extends HttpServlet{
/**
*
*/
private static final long serialVersionUID = 1L; @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(">>>>>>>>>>doGet()<<<<<<<<<<<");
doPost(req, resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(">>>>>>>>>>doPost()<<<<<<<<<<<");
int width = 60;
int height = 32;
//create the image
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
// set the background color
g.setColor(new Color(0xDCDCDC));
g.fillRect(0, 0, width, height);
// draw the border
g.setColor(Color.black);
g.drawRect(0, 0, width - 1, height - 1);
// create a random instance to generate the codes
Random rdm = new Random();
String hash1 = Integer.toHexString(rdm.nextInt());
System.out.print(hash1);
// make some confusion
for (int i = 0; i < 50; i++) {
int x = rdm.nextInt(width);
int y = rdm.nextInt(height);
g.drawOval(x, y, 0, 0);
}
// generate a random code
String capstr = hash1.substring(0, 4);
HttpSession session = req.getSession(true);
//将生成的验证码存入session
session.setAttribute("validateCode", capstr);
g.setColor(new Color(0, 100, 0));
g.setFont(new Font("Candara", Font.BOLD, 24));
g.drawString(capstr, 8, 24);
g.dispose();
//输出图片
resp.setContentType("image/jpeg");
OutputStream strm = resp.getOutputStream();
ImageIO.write(image, "jpeg", strm);
strm.close(); }
}
Application.java
package com.example; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Spring Boot Shiro权限管理--自定义 FormAuthenticationFilter验证码整合的更多相关文章
- (39.2). Spring Boot Shiro权限管理【从零开始学Spring Boot】
(本节提供源代码,在最下面可以下载) (4). 集成Shiro 进行用户授权 在看此小节前,您可能需要先看: http://412887952-qq-com.iteye.com/blog/229973 ...
- (39.1) Spring Boot Shiro权限管理【从零开始学Spring Boot】
(本节提供源代码,在最下面可以下载)距上一个章节过了二个星期了,最近时间也是比较紧,一直没有时间可以写博客,今天难得有点时间,就说说Spring Boot如何集成Shiro吧.这个章节会比较复杂,牵涉 ...
- Spring Boot Shiro 权限管理
Spring Boot Shiro 权限管理 标签: springshiro 2016-01-14 23:44 94587人阅读 评论(60) 收藏 举报 .embody{ padding:10px ...
- (39.4) Spring Boot Shiro权限管理【从零开始学Spring Boot】
在读此文章之前您还可能需要先了解: (39.1) Spring Boot Shiro权限管理[从零开始学Spring Boot] http://412887952-qq-com.iteye.com/b ...
- (39.3) Spring Boot Shiro权限管理【从零开始学Spring Boot】
在学习此小节之前您可能还需要学习: (39.1) Spring Boot Shiro权限管理[从零开始学Spring Boot] http://412887952-qq-com.iteye.com/b ...
- Spring Boot Shiro 权限管理 【转】
http://blog.csdn.net/catoop/article/details/50520958 主要用于备忘 本来是打算接着写关于数据库方面,集成MyBatis的,刚好赶上朋友问到Shiro ...
- 十、 Spring Boot Shiro 权限管理
使用Shiro之前用在spring MVC中,是通过XML文件进行配置. 将Shiro应用到Spring Boot中,本地已经完成了SpringBoot使用Shiro的实例,将配置方法共享一下. 先简 ...
- 19. Spring Boot Shiro 权限管理
转自:https://blog.csdn.net/catoop/article/details/50520958
- Spring boot security权限管理集成cas单点登录
挣扎了两周,Spring security的cas终于搞出来了,废话不多说,开篇! Spring boot集成Spring security本篇是使用spring security集成cas,因此,先 ...
随机推荐
- nexus 私服相关的配置
1 上传到nexus的配置 1 settings.xml <server> <id>releases</id> <username>admin</ ...
- js的事件冒泡
先来段代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w ...
- DevExtreme 搭建Node.js开发环境
简介 DevExtreme is a component suite for creating highly responsive web applications for touch devices ...
- ES增删改查入门1
1.RESTful接口使用方法 为了方便直观我们使用Head插件提供的接口进行演示,实际上内部调用的RESTful接口. RESTful接口URL的格式: http://localhost:9200/ ...
- Win7无线路由Win8/8.1开启网络承载DOS命令笔记本电脑当无线路由器
以下废话,先吐槽几句 这个功能其实在Win7+系统都内置了,不要再用什么某豹.某大师.某Soft之类的开启无线网络,这些软件都是骗你们安装一些垃圾软件的. 另外吐槽 某度wifi.某数字wifi都是垃 ...
- Dojo 学习笔记 之 Dojo hitch&partial
原文: http://dojotoolkit.org/documentation/tutorials/1.10/hitch/index.html 版本: Dojo 1.10 为了更好地使用JavaSc ...
- [QualityCenter]QC是什么?发展历程是怎样?
QC,即Quality Center,是一个基于Web的测试管理工具.它可以组织和管理应用程序测试流程的所有阶段,包括制定测试需求.计划测试.执行测试和跟踪缺陷.此外,通过Quality Center ...
- SSL Labs: Increased Penalty When TLS 1.2 Is Not Supported
https://community.qualys.com/blogs/securitylabs/2015/05/22/ssl-labs-increased-penalty-when-tls-12-is ...
- 思科双出口+策略路由+NAT
使用策略路由,从教育网出去的,在教育网接口进行nat转换 访问教育网资源平时走教育网,故障走电信 访问internat走电信线路,故障走教育网 服务器静态绑定教育网ip,不管电信.联通.教育网都走教育 ...
- js01
/////////////////////////////////////////////////////////////js开端/////////////////////////////////// ...