最近在做一个小项目,其中认证这块使用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. windows本地用户及组的区别

    Administrators(超级管理员组) 用来管理注册用户或者具有一定权限的其他管理员,维护网站的运行. Administrators中的用户对计算机/域有不受限制的完全访问权,分配给该组的默认权 ...

  2. HDP Hive StorageHandler 下推优化的坑

    关键词:hdp , hive , StorageHandler 了解Hive StorageHandler的同学都知道,StorageHandler作为Hive适配不同存储的拓展类,同时肩负着Hive ...

  3. HTML入门13

    构建表格 使用colspan和rowspan添加无单位的数字值作为属性来实现行合并和列合并: <col>来定义列的样式,每一个<col>都会制定每列的样式,对于不需要指定列的样 ...

  4. 2.SSM整合_多表_一对一或多对一的增删改查

    一对一和多对一配置一样,这里就放到一起. 1.配置文件跟上一章一样,这里就不多写了,主要是Mapper映射文件 多 接口 public interface NewsMapper { public vo ...

  5. Python函数式编程之lambda表达式

    一:匿名函数的定义 lambda parameter_list: expression 二:三元表达式 条件为真时返回的结果 if 条件判断 else 条件为假的时候返回的结果 三:map map(f ...

  6. ivew ui

    render操作: render:(h, params) => { return h('div', [ h('Button',{ on:{ click:()=>{ this.edit(pa ...

  7. DOS命令(二)

    1. findstr “要查找的字符串” 文件,用来从文件中检索包含相关内容的字符串集合. [例如:查找包含“TTL”的字符串] 2.  del 要删除的文件,用来删除某个文件. 3. pause,用 ...

  8. WdatePicker 日期控件- 功能及示例

      3. 多语言和自定义皮肤多语言支持 通过lang属性,可以为每个日期控件单独配置语言,当然也可以通过WdatePicker.js配置全局的语言语言列表和语言安装说明详见语言配置 示例3-1 多语言 ...

  9. Spring Cloud,Dubbo及HSF对比

    Round 1:背景 Dubbo,是阿里巴巴服务化治理的核心框架,并被广泛应用于阿里巴巴集团的各成员站点.阿里巴巴近几年对开源社区的贡献不论在国内还是国外都是引人注目的,比如:JStorm捐赠给Apa ...

  10. FFmpeg 学习(六):FFmpeg 核心模块 libavformat 与 libavcodec 分析

    一.libavformat介绍 libavformat的主要组成与层次调用关系如下图: AVFromatContext是API层直接接触到的结构体,它会进行格式的封装和解封装,它的数据部分由底层提供, ...