Shiro在web应用中实现验证码功能
来源:互联网 发布:时间序列数据聚类分析 编辑:程序博客网 时间:2024/06/13 18:48
原文参照:http://www.micmiu.com/opensource/security/shiro-web-captcha/
目录结构:
- 概述
- 扩展shiro认证
- 验证码工具
- 验证码servlet
- 配置文件修改
- 修改登录页面
- 测试验证
[一]、概述
本文简单讲述在web应用整合shiro后,如何实现登录验证码认证的功能。
[二]、扩展shiro的认证
创建验证码异常类:CaptchaException.java
扩展默认的用户认证的bean为:UsernamePasswordCaptchaToken.java
扩展原始默认的过滤为:FormAuthenticationCaptchaFilter.java
修改shiro认证逻辑:ShiroDbRealm.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
packagecom.micmiu.framework.web.v1.system.service;
importjava.io.Serializable;
importorg.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException;
importorg.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
importorg.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
importorg.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
importorg.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
importorg.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
importorg.apache.shiro.subject.SimplePrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import com.micmiu.framework.web.v1.system.entity.Role;
importcom.micmiu.framework.web.v1.system.entity.User;
import com.micmiu.modules.captcha.CaptchaServlet;
importcom.micmiu.modules.support.shiro.CaptchaException;
import com.micmiu.modules.support.shiro.UsernamePasswordCaptchaToken;
/**
* 演示用户和权限的认证,使用默认 的SimpleCredentialsMatcher
*
* @author <a href="http://www.micmiu.com">Michael Sun</a>
*/
publicclass ShiroDbRealmextends AuthorizingRealm{
privateUserService userService;
/**
* 认证回调函数, 登录时调用.
*/
@Override
protectedAuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken)throws AuthenticationException{
UsernamePasswordCaptchaTokentoken =(UsernamePasswordCaptchaToken)authcToken;
Stringusername =token.getUsername();
if(username== null){
thrownew AccountException(
"Null usernames are not allowed by this realm.");
}
// 增加判断验证码逻辑
Stringcaptcha =token.getCaptcha();
StringexitCode =(String)SecurityUtils.getSubject().getSession()
.getAttribute(CaptchaServlet.KEY_CAPTCHA);
if(null== captcha|| !captcha.equalsIgnoreCase(exitCode)){
thrownew CaptchaException("验证码错误");
}
User user= userService.getUserByLoginName(username);
if(null== user){
thrownew UnknownAccountException("No account found for user ["
+username +"]");
}
returnnew SimpleAuthenticationInfo(newShiroUser(user.getLoginName(),
user.getName()),user.getPassword(),getName());
}
/**
* 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用.
*/
@Override
protectedAuthorizationInfo doGetAuthorizationInfo(
PrincipalCollectionprincipals){
ShiroUser shiroUser= (ShiroUser)principals.fromRealm(getName())
.iterator().next();
User user= userService.getUserByLoginName(shiroUser.getLoginName());
if(user!= null){
SimpleAuthorizationInfo info =new SimpleAuthorizationInfo();
for(Role role: user.getRoleList()){
// 基于Permission的权限信息
info.addStringPermissions(role.getAuthList());
}
returninfo;
}else {
returnnull;
}
}
/**
* 更新用户授权信息缓存.
*/
publicvoid clearCachedAuthorizationInfo(Stringprincipal){
SimplePrincipalCollectionprincipals =new SimplePrincipalCollection(
principal,getName());
clearCachedAuthorizationInfo(principals);
}
/**
* 清除所有用户授权信息缓存.
*/
publicvoid clearAllCachedAuthorizationInfo(){
Cache<Object,AuthorizationInfo>cache =getAuthorizationCache();
if(cache!= null){
for(Objectkey :cache.keys()){
cache.remove(key);
}
}
}
@Autowired
publicvoid setUserService(UserServiceuserService){
this.userService= userService;
}
/**
* 自定义Authentication对象,使得Subject除了携带用户的登录名外还可以携带更多信息.
*/
publicstatic classShiroUser implementsSerializable {
privatestatic finallong serialVersionUID= -1748602382963711884L;
privateString loginName;
privateString name;
publicShiroUser(StringloginName,String name){
this.loginName= loginName;
this.name= name;
}
publicString getLoginName(){
returnloginName;
}
/**
* 本函数输出将作为默认的<shiro:principal/>输出.
*/
@Override
publicString toString(){
returnloginName;
}
publicString getName(){
returnname;
}
}
}
[三]、验证码工具类
CaptchaUtil.java
[四]、创建验证码的servlet
CaptchaServlet.java
[五]、修改配置文件
在 web.xml 中增加配置:
修改 applicationContext-shiro.xml 中的配置如下:
[六]、修改登录页面
login.jsp
[七]、验证测试
启动项目后会看到如下页面:
0 0
- Shiro在web应用中实现验证码功能
- Shiro在web应用中实现验证码、回显登录失败信息
- 应用Shiro到Web Application(验证码实现)
- 在 Web 项目中应用 Apache Shiro
- 在 Web 项目中应用 Apache Shiro
- 在 Web 项目中应用 Apache Shiro
- 在 Web 项目中应用 Apache Shiro
- 在 Web 项目中应用 Apache Shiro
- 在 Web 项目中应用 Apache Shiro
- 在Web 项目中应用 Apache Shiro
- 在 Web 项目中应用 Apache Shiro
- 在 Web 项目中应用 Apache Shiro
- 在 Web 项目中应用 Apache Shiro
- 在 Web 项目中应用 Apache Shiro
- 在 Web 项目中应用 Apache Shiro
- 在 Web 项目中应用 Apache Shiro
- 在 Web 项目中应用 Apache Shiro
- 在 Web 项目中应用 Apache Shiro
- 关于Activity向右滑动销毁的具体实现
- [授权发表]缓冲区溢出与注入分析
- 【C语言】将大写字母换成小写字母输出
- MFC 基础概念
- 关于C语言中feof的使用
- Shiro在web应用中实现验证码功能
- 慎用mysql的enum字段
- tomcat8.0环境下解决get方法中文参数乱码问题
- 从浏览器内核级别修改layout相关的UI行为
- 设计模式学习(十八):状态模式
- 软件开发之心态篇
- Linux-常用命令(2)权限管理命令
- 正则表达式匹配邮箱规则
- JS命名空间