如果你对Shiro不了解,可以查看作者前面发表的文章:应用Shiro到Web application(基础)
五、在Shiro中实现CAPTCHA(验证码)功能
a) 验证码表单认证过滤器
package com.wearereading.example.shiro;
importjavax.servlet.ServletRequest;
importjavax.servlet.ServletResponse;
importorg.apache.shiro.authc.AuthenticationToken;
importorg.apache.shiro.web.filter.authc.FormAuthenticationFilter;
importorg.apache.shiro.web.util.WebUtils;
public classCaptchaFormAuthenticationFilterextends FormAuthenticationFilter{
public static final StringDEFAULT_CAPTCHA_PARAM = "captcha";
private String captchaParam =DEFAULT_CAPTCHA_PARAM;
public String getCaptchaParam() {
return captchaParam;
}
protected String getCaptcha(ServletRequest request) {
return WebUtils.getCleanParam(request, getCaptchaParam());
}
protected AuthenticationToken createToken(
ServletRequest request, ServletResponse response) {
String username = getUsername(request);
String password = getPassword(request);
String captcha = getCaptcha(request);
boolean rememberMe = isRememberMe(request);
String host = getHost(request);
return new CaptchaUsernamePasswordToken(
username, password, rememberMe, host,captcha);
}
}
b) 用户名密码令牌UsernamePasswordToken
package com.wearereading.example.shiro;
importorg.apache.shiro.authc.UsernamePasswordToken;
public classCaptchaUsernamePasswordToken extends UsernamePasswordToken{
private static final longserialVersionUID = 1L;
private String captcha;
public String getCaptcha() {
return captcha;
}
public void setCaptcha(String captcha) {
this.captcha = captcha;
}
public CaptchaUsernamePasswordToken() {
super();
}
public CaptchaUsernamePasswordToken(String username,char[] password,
boolean rememberMe, String host,String captcha) {
super(username, password, rememberMe, host);
this.captcha = captcha;
}
}
c) 添加AuthenticationException
public classIncorrectCaptchaException extends AuthenticationException{
private static final longserialVersionUID = 1L;
public IncorrectCaptchaException() {
super();
}
public IncorrectCaptchaException(String message, Throwable cause) {
super(message, cause);
}
public IncorrectCaptchaException(String message) {
super(message);
}
public IncorrectCaptchaException(Throwable cause) {
super(cause);
}
}
d) Shiro INI文件
authc= com.wearereading.example.shiro.CaptchaFormAuthenticationFilter
e) 实现Realm
protectedAuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken )throwsAuthenticationException {
CaptchaUsernamePasswordToken token =
(CaptchaUsernamePasswordToken) authcToken;
String accountName = token.getUsername();
//验证码 验证
String captcha =null;
Object obj_captcha = SecurityUtils.getSubject().getSession()
.getAttribute( SessionKey.CAPTCHA );
Object obj_count = SecurityUtils.getSubject().getSession()
.getAttribute( SessionKey.LOGIN_FAILED_COUNT );
int failed_count = (obj_count ==null || !(obj_countinstanceof Integer))
?0:(Integer)obj_count;
if( obj_captchainstanceof String)
captcha = (String)obj_captcha;
if( captcha !=null && failed_count >0
&& !captcha.equalsIgnoreCase( token.getCaptcha() )){
throw newIncorrectCaptchaException("验证码错误!");
}
//用户名密码验证
if( accountName != null && !"".equals(accountName) ){
AccountManager accountManager =newAccountManagerImpl();
Account account = accountManager.get( token.getUsername() );
if( account !=null )
return new SimpleAuthenticationInfo(
account.getName(),account.getPassword(), getName() );
}
return null;
}
}
f) 登录页面
<%
Object obj = request.getAttribute(org.apache.shiro.web.filter.authc.
FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
boolean flag = false;
String msg = "";
if( obj != null ){
if( "org.apache.shiro.authc.UnknownAccountException".equals( obj ) )
msg = "未知帐号错误!";
else if("org.apache.shiro.authc.IncorrectCredentialsException".equals( obj ))
msg = "密码错误!";
else if("com.wearereading.example.shiro.IncorrectCaptchaException".equals( obj ))
msg = "验证码错误!";
else if( "org.apache.shiro.authc.AuthenticationException".equals( obj ))
msg = "认证失败!";
flag = !"".equals(msg);
}
if( flag ){
out.print( msg );
Integer count = (Integer)request.getSession().getAttribute(
SessionKey.LOGIN_FAILED_COUNT );
if( count ==null )
count = Integer.valueOf(0);
count++;
request.getSession().setAttribute(SessionKey.LOGIN_FAILED_COUNT, count );
}
%>
<form action="login.jsp" method="post">
<br/>用户帐号:
<input type="text" name="username" id="username" value=""/>
<br/>登录密码:
<input type="password" name="password" id="password" value="" />
<br/>验证码:
<input type="text" name="captcha" id="captcha" size="6"/>
<img src="/captcha" alt="captcha" />
<br/><input value="登录" type="submit" >
</form>
g) CAPTCHA实现
h)
六、代码的开发环境
JAVA1.6
Tomcat
Eclipse
七、参考资料
http://www.captcha.net/
将 Shiro作为应用的权限基础
http://www.ibm.com/developerworks/cn/opensource/os-cn-shiro/index.html
写在后面的几句话:
此文的发表于新浪博客积沙成塔,转载请标注来源 http://blog.sina.com.cn/minssh。
文章大概写于一年前,由于原文章是Word排版,里面的代码在这里看起来有点乱(Sina不支持代码排版),请原谅!