最近在做一个小项目,其中认证这块使用shiro+SpringMVC+easyUI,因为easyUI在提交数据的时候使用的是ajax的异步提交,所以shiro在处理数据的时候需要重写FormAuthenticationFilter的相关方法,所以在此记录下实现的过程,以供大伙参考。

  本文只给出核心代码,完整代码可去本人github上查看

https://github.com/q279583842q/SRM.git

ShiroLoginFilter

  因为shiro默认的处理验证的方式是验证成功直接跳转到我们配置的successURL中,如果认证失败则会跳转到我们指定的fail地址,而和easyUI一块使用的话通过ajax提交,shiro只需要给调用者返回一个验证的结果就可以了,所以我们需要重写FormAuthenticationFilter中的相关方法,如下:

/**
* 拦截验证后的请求
* @author 波波烤鸭
* @email dengpbs@163.com
*
*/
public class ShiroLoginFilter extends FormAuthenticationFilter{ private static final Logger log = LoggerFactory.getLogger(FormAuthenticationFilter.class); /**
* 表示当访问拒绝时
* @param request
* @param response
* @return
* @throws Exception
*/
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { if(this.isLoginRequest(request, response)) {
if(this.isLoginSubmission(request, response)) {
if(log.isTraceEnabled()) {
log.trace("Login submission detected. Attempting to execute login.");
} return this.executeLogin(request, response);
} else {
if(log.isTraceEnabled()) {
log.trace("Login page view.");
} return true;
}
} else {
if(log.isTraceEnabled()) {
log.trace("Attempting to access a path which requires authentication. Forwarding to the Authentication url [" + this.getLoginUrl() + "]");
} this.saveRequestAndRedirectToLogin(request, response);
return false;
}
} /**
*
* 当登录成功
*
* @param token
* @param subject
* @param request
* @param response
* @return
* @throws Exception
*/
@Override
protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception { HttpServletResponse httpServletResponse = (HttpServletResponse) response;
String requestType = ((HttpServletRequest)request).getHeader("X-Requested-With");
System.out.println("访问成功....");
if (requestType==null){// 不是ajax请求
System.out.println("访问成功....1");
issueSuccessRedirect(request, response);
} else {
System.out.println("访问成功....2");
httpServletResponse.setCharacterEncoding("UTF-8");
PrintWriter out = httpServletResponse.getWriter();
out.println(JSONObject.toJSON(Resp.success()));
out.flush();
out.close();
}
return false;
} /**
*
* 当登录失败
*
* @param token
* @param e
* @param request
* @param response
* @return
*/
@Override
protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
System.out.println("访问失败...");
String requestType = ((HttpServletRequest)request).getHeader("X-Requested-With");
System.out.println("访问失败..."+requestType);
if (requestType==null) {// 不是ajax请求
System.out.println("访问失败...1");
setFailureAttribute(request, e);
return true;
}
try {
System.out.println("访问失败...2");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
String message = e.getClass().getSimpleName();
String info = null;
if ("IncorrectCredentialsException".equals(message)) {
info = "密码错误";
} else if ("UnknownAccountException".equals(message)) {
info = "账号不存在";
} else if ("LockedAccountException".equals(message)) {
info = "账号被锁定";
} else {
info = "未知错误";
}
out.println(JSONObject.toJSON(Resp.fail(ErrorCode.SYSTEM_ERROR, info)));
out.flush();
out.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return false;
}
}

自定义realm

/**
* 认证和授权的自定义Realm
*
* @author 波波烤鸭
* @email dengpbs@163.com
*
*/
public class SecurityRealm extends AuthorizingRealm { @Resource
private IUserService userService; /**
* 认证的方法
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 获取提交的账号
UsernamePasswordToken t = (UsernamePasswordToken) token;
// 获取登录的账号
String userName = t.getUsername();
System.out.println("---->" + userName);
User user = new User();
user.setUsername(userName);
List<User> list = userService.login(userName);
if (list == null || list.size() != 1) {
// 账号不存在或者用户过多都返回null
return null;
}
user = list.get(0); SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), "bobo");
return info;
} /**
* 授权的方法
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
// 省略 。。。
return null;
} }

shiro的配置文件

easyUI中提交数据

$.ajax({
type: "post"
, timeout: 10000
, // 超时时间 10 秒
headers: { 'X-Requested-With':'XMLHttpRequest' }
, url: "login.do"
, data: $("#ff").serialize()
, success: function(data) {
if(JSON.parse(data).status==200){
// 表示登录成功,跳转到home页面
location.href="home";
}else{
$.messager.alert('登录失败',JSON.parse(data).message);
}
}
});

如此就可以实现我们需要的功能了,希望此文对你有所帮助^ _ ^

Shiro+easyUI+SpringMVC实现登录认证的更多相关文章

  1. spring boot(十四)shiro登录认证与权限管理

    这篇文章我们来学习如何使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求.在Java领域一般有Spring Security ...

  2. Spring Cloud之路:(七)SpringBoot+Shiro实现登录认证和权限管理

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/sage_wang/article/details/79592269一.Shiro介绍1.Shiro是 ...

  3. shiro中接入单点登录功能

    最近新建的系统中使用了shiro,而shiro框架中包含登录认证和鉴权的功能,因为我们系统要统一接入公司内部的单点登录(isso)系统,所以通过isso的登录用户,需要在shiro中置为已认证,一下提 ...

  4. Shiro 整合SpringMVC 并实现权限管理,登录和注销

    Shiro 整合SpringMVC 并且实现权限管理,登录和注销 Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring S ...

  5. shiro实现APP、web统一登录认证和权限管理

    先说下背景,项目包含一个管理系统(web)和门户网站(web),还有一个手机APP(包括Android和IOS),三个系统共用一个后端,在后端使用shiro进行登录认证和权限控制.好的,那么问题来了w ...

  6. 将 Shiro 作为应用的权限基础 二:基于SpringMVC实现的认证过程

    认证就是验证用户身份的过程.在认证过程中,用户需要提交实体信息(Principals)和凭据信息(Credentials)以检验用户是否合法.最常见的“实体/凭证”组合便是“用户名/密码”组合. 一. ...

  7. springboot+mybatis+shiro——登录认证和权限控制

    转载:https://z77z.oschina.io/ 一.引入依赖 shiro-all包含shiro所有的包.shiro-core是核心包.shiro-web是与web整合.shiro-spring ...

  8. SpringMVC拦截器实现登录认证(转发)

    感谢原作者,转发自:http://blog.csdn.net/u014427391/article/details/51419521 以Demo的形式讲诉拦截器的使用 项目结构如图: 需要的jar:有 ...

  9. JavaEE权限管理系统的搭建(四)--------使用拦截器实现登录认证和apache shiro密码加密

    RBAC 基于角色的权限访问控制(Role-Based Access Control)在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限.这就极大地简化了权限的管理.在一个 ...

随机推荐

  1. vue安装使用

    一.安装(cmd) 1.全局安装vue cnpm install --global vue-cli 2.cd到需要创建项目的文件夹下 3.创建项目 项目是基于webpack的 vue init web ...

  2. rest_framework之认证源码剖析

    如果我们写API有人能访问,有人不能访问,则需要些认证. 如何知道该用户是否已登入? 如果用户登入成功,则给用户一个随机字符串,去访问另一个页面. 以前写session的时候,都是把session写c ...

  3. Round A - Kick Start 2019

    a.链接:https://codingcompetitions.withgoogle.com/kickstart/round/0000000000050e01/00000000000698d6 题意: ...

  4. nodejs操作mysql常见错误

    1.Cannot enqueue Handshake after already enqueuing a Hand shake.这个错误提示意思是某个数据库连接已经执行了,不能进行多次连接了.遇到此类 ...

  5. 循环结构for

    教程:高能:语句结构都是由关键字开头,用冒号结束! 一:语句结构 for <variable> in <sequence>:    <statements>else ...

  6. ucore代码分析

    lab2: 总共分为四个包一个文件,分别为: boot: 操作系统加载程序代码 kern: 操作系统内核代码 libs: 相关的库和数据结构 tools: 相关编译链接调试工具 Makefile: 构 ...

  7. 权限系统设计-day01

    数据库表的设计:   关键流程思考: 权限在SSH系统中应该表现为什么东西? 小胖这个用户登陆:1,检查用户名和密码;2,检查通过; 1),得到小胖这个用户的对应的所有的角色:R1 2),根据所有的角 ...

  8. Spring源码工程导入Eclsipse缺少两个jar文件

    按照<Spring源码深度解析>所述,使用gradle cleanidea eclipse将Spring源码转为eclipse工程后,导入eclipse,最后发现还是缺少spring-cg ...

  9. FCC(ES6写法) Exact Change

    设计一个收银程序 checkCashRegister() ,其把购买价格(price)作为第一个参数 , 付款金额 (cash)作为第二个参数, 和收银机中零钱 (cid) 作为第三个参数. cid  ...

  10. numpy.random 常用函数详解之排列乱序篇(Permutations)

    1.numpy.random.shuffle(x) 参数:填入数组或列表. 返回值:无. 函数功能描述:对填入的数组或列表进行乱序处理,shape保持不变. 2.numpy.random.permut ...