Shiro实现验证码认证
来源:互联网 发布:自动整点报时软件 编辑:程序博客网 时间:2024/04/30 11:27
验证码是有效防止暴力破解的一种手段,常用做法是在服务端产生一串随机字符串与当前用户会话关联(我们通常说的放入 Session),然后向终端用户展现一张经过“扰乱”的图片,只有当用户输入的内容与服务端产生的内容相同时才允许进行下一步操作
产生验证码
作为演示,我们选择开源的验证码组件 kaptcha。这样,我们只需要简单配置一个 Servlet,页面通过 IMG 标签就可以展现图形验证码。
- <servlet>
- <servlet-name>kaptcha</servlet-name>
- <servlet-class>
- com.google.code.kaptcha.servlet.KaptchaServlet
- </servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>kaptcha</servlet-name>
- <url-pattern>/images/kaptcha.jpg</url-pattern>
- </servlet-mapping>
扩展 UsernamePasswordTokenShiro 表单认证,页面提交的用户名密码等信息,用 UsernamePasswordToken 类来接收,很容易想到,要接收页面验证码的输入,我们需要扩展此类:
- package javacommon.shiro;
- import org.apache.shiro.authc.UsernamePasswordToken;
- public class CaptchaUsernamePasswordToken extends UsernamePasswordToken {
- //验证码字符串
- private String captcha;
- public CaptchaUsernamePasswordToken(String username, char[] password,
- boolean rememberMe, String host, String captcha) {
- super(username, password, rememberMe, host);
- this.captcha = captcha;
- }
- public String getCaptcha() {
- return captcha;
- }
- public void setCaptcha(String captcha) {
- this.captcha = captcha;
- }
- }
扩展 FormAuthenticationFilter
接下来我们扩展 FormAuthenticationFilter 类
- package javacommon.shiro;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import javax.servlet.http.HttpServletRequest;
- import org.apache.shiro.authc.AuthenticationException;
- import org.apache.shiro.subject.Subject;
- import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
- import org.apache.shiro.web.util.WebUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- public class CaptchaFormAuthenticationFilter extends FormAuthenticationFilter {
- private static final Logger LOG = LoggerFactory.getLogger(CaptchaFormAuthenticationFilter.class);
- public CaptchaFormAuthenticationFilter() {
- }
- @Override
- /**
- * 登录验证
- */
- protected boolean executeLogin(ServletRequest request,
- ServletResponse response) throws Exception {
- CaptchaUsernamePasswordToken token = createToken(request, response);
- try {
- /*图形验证码验证*/
- doCaptchaValidate((HttpServletRequest) request, token);
- Subject subject = getSubject(request, response);
- subject.login(token);//正常验证
- LOG.info(token.getUsername()+"登录成功");
- return onLoginSuccess(token, subject, request, response);
- }catch (AuthenticationException e) {
- LOG.info(token.getUsername()+"登录失败--"+e);
- return onLoginFailure(token, e, request, response);
- }
- }
- // 验证码校验
- protected void doCaptchaValidate(HttpServletRequest request,
- CaptchaUsernamePasswordToken token) {
- //session中的图形码字符串
- String captcha = (String) request.getSession().getAttribute(
- com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
- //比对
- if (captcha != null && !captcha.equalsIgnoreCase(token.getCaptcha())) {
- throw new IncorrectCaptchaException("验证码错误!");
- }
- }
- @Override
- protected CaptchaUsernamePasswordToken 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.toCharArray(), rememberMe, host, captcha);
- }
- public static final String DEFAULT_CAPTCHA_PARAM = "captcha";
- private String captchaParam = DEFAULT_CAPTCHA_PARAM;
- public String getCaptchaParam() {
- return captchaParam;
- }
- public void setCaptchaParam(String captchaParam) {
- this.captchaParam = captchaParam;
- }
- protected String getCaptcha(ServletRequest request) {
- return WebUtils.getCleanParam(request, getCaptchaParam());
- }
- //保存异常对象到request
- @Override
- protected void setFailureAttribute(ServletRequest request,
- AuthenticationException ae) {
- request.setAttribute(getFailureKeyAttribute(), ae);
- }
- }
- package javacommon.shiro;
- import org.apache.shiro.authc.AuthenticationException;
- public class IncorrectCaptchaException extends AuthenticationException {
- public IncorrectCaptchaException() {
- super();
- }
- public IncorrectCaptchaException(String message, Throwable cause) {
- super(message, cause);
- }
- public IncorrectCaptchaException(String message) {
- super(message);
- }
- public IncorrectCaptchaException(Throwable cause) {
- super(cause);
- }
- }
Filter的配置及使用
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
- http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
- <!-- Shiro Filter 拦截器相关配置 -->
- <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
- <!-- securityManager -->
- <property name="securityManager" ref="securityManager" />
- <!-- 登录路径 -->
- <property name="loginUrl" value="/login.jsp" />
- <!-- 登录成功后跳转路径 -->
- <property name="successUrl" value="/pages/index.jsp" />
- <!-- 授权失败跳转路径 -->
- <property name="unauthorizedUrl" value="/login.jsp" />
- <property name="filters">
- <util:map>
- <entry key="authc" value-ref="myAuthenFilter" />
- </util:map>
- </property>
- <!-- 过滤链定义 -->
- <property name="filterChainDefinitions">
- <value>
- /login.jsp = authc
- /pages/* = authc
- /index.jsp* = authc
- /logout.do = logout
- <!-- 访问这些路径必须拥有某种权限 /role/edit/* = perms[role:edit] /role/save = perms[role:edit]
- /role/list = perms[role:view] -->
- </value>
- </property>
- </bean>
- <!-- 自定义验证拦截器 -->
- <bean id="myAuthenFilter" class="javacommon.shiro.CaptchaFormAuthenticationFilter" />
- <!-- securityManager -->
- <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- <property name="realm" ref="myRealm" />
- </bean>
- <!-- <bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
- <property name="cacheManager" ref="cacheManager" /> </bean> -->
- <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
- <!-- 自定义Realm实现 -->
- <bean id="myRealm" class="javacommon.shiro.CustomRealm">
- <!-- <property name="cacheManager" ref="shiroCacheManager" /> -->
- </bean>
- </beans>
登录页面:
- <%@page import="org.apache.shiro.web.filter.authc.FormAuthenticationFilter"%>
- <%@page import="javacommon.shiro.IncorrectCaptchaException"%>
- <%@page import="org.apache.shiro.authc.AuthenticationException"%>
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <%
- String path = request.getContextPath();
- String basePath = request.getScheme() + "://"
- + request.getServerName() + ":" + request.getServerPort()
- + path + "/";
- %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <base href="<%=basePath%>">
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>Insert title here</title>
- <style type="text/css">
- .error {
- color: red;
- }
- </style>
- <script type="text/javascript">
- function refreshCaptcha(){
- document.getElementById("img_captcha").src="<%=basePath%>images/kaptcha.jpg?t=" + Math.random();
- }
- </script>
- </head>
- <body>
- <%
- Object obj = request
- .getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
- String msg = "";
- if (obj != null) {
- if (obj instanceof IncorrectCaptchaException)
- msg = "验证码错误!";
- else
- msg = "账号或密码错误!";
- }
- out.println("<div class='error'>" + msg + "</div>");
- %>
- <form action="login.jsp" method="post">
- <input type="hidden" name="rememberMe" value="true" /> <br />
- <table>
- <tr>
- <td>用户帐号:</td>
- <td><input type="text" name="username" id="username" value="" /></td>
- </tr>
- <tr>
- <td>登录密码:</td>
- <td><input type="password" name="password" id="password"
- value="" /></td>
- </tr>
- <tr>
- <td>验证码:</td>
- <td><input type="text" name="captcha" /></td>
- </tr>
- <tr>
- <td> </td>
- <td><img alt="验证码" src="images/kaptcha.jpg" title="点击更换"
- id="img_captcha" onclick="javascript:refreshCaptcha();">(看不清<a href="javascript:void(0)" onclick="javascript:refreshCaptcha()">换一张</a>)</td>
- </tr>
- <tr>
- <td colspan="2"><input value="登录" type="submit"></td>
- </tr>
- </table>
- </form>
- </body>
- </html>
转载来自:http://blog.csdn.net/zhengwei223/article/details/9969831
0 0
- Shiro实现验证码认证
- Shiro(3)实现验证码认证
- Shiro(3)实现验证码认证
- shiro- session,自定义FormAuthenticationFilter(表单认证器)-->实现验证码校验
- 使用shiro的的表单过滤器重写shiro默认的认证规则来实现先验证验证码再验证登录所遇到的问题
- Shiro实现认证
- Apache Shiro 实现认证
- Shiro认证框架下,加入图形验证码
- spring集成shiro实现登录认证自定义验证功能(认证采用国密SM4算法)
- 使用shiro实现登陆认证
- shiro authorizingrealm实现认证授权
- 用Shiro实现身份认证
- shiro的认证代码实现
- SSH集成Shiro,实现认证
- Shiro验证码检测
- Shiro系列之Shiro+Mysql实现用户认证(Authentication)
- 【Shiro权限管理】7.实现Shiro认证流程
- SSM集成Shiro:实现登录认证
- Mysql 视图
- ARM知识汇总
- JavaScript DOM学习(1)
- linux 定时任务
- 如何输出类的非静态成员函数地址
- Shiro实现验证码认证
- 基础整理02
- 怎样做C语言课程设计?(二)
- 在別人眼中別樣的幸福
- C++易错易混知识点
- Spring MVC与JAX-RS比较与分析
- arcgis数据类型
- Android Recovery 移植 Busybox
- c++调用matlab程序