Shiro+easyUI+SpringMVC实现登录认证
最近在做一个小项目,其中认证这块使用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实现登录认证的更多相关文章
- spring boot(十四)shiro登录认证与权限管理
这篇文章我们来学习如何使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求.在Java领域一般有Spring Security ...
- Spring Cloud之路:(七)SpringBoot+Shiro实现登录认证和权限管理
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/sage_wang/article/details/79592269一.Shiro介绍1.Shiro是 ...
- shiro中接入单点登录功能
最近新建的系统中使用了shiro,而shiro框架中包含登录认证和鉴权的功能,因为我们系统要统一接入公司内部的单点登录(isso)系统,所以通过isso的登录用户,需要在shiro中置为已认证,一下提 ...
- Shiro 整合SpringMVC 并实现权限管理,登录和注销
Shiro 整合SpringMVC 并且实现权限管理,登录和注销 Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring S ...
- shiro实现APP、web统一登录认证和权限管理
先说下背景,项目包含一个管理系统(web)和门户网站(web),还有一个手机APP(包括Android和IOS),三个系统共用一个后端,在后端使用shiro进行登录认证和权限控制.好的,那么问题来了w ...
- 将 Shiro 作为应用的权限基础 二:基于SpringMVC实现的认证过程
认证就是验证用户身份的过程.在认证过程中,用户需要提交实体信息(Principals)和凭据信息(Credentials)以检验用户是否合法.最常见的“实体/凭证”组合便是“用户名/密码”组合. 一. ...
- springboot+mybatis+shiro——登录认证和权限控制
转载:https://z77z.oschina.io/ 一.引入依赖 shiro-all包含shiro所有的包.shiro-core是核心包.shiro-web是与web整合.shiro-spring ...
- SpringMVC拦截器实现登录认证(转发)
感谢原作者,转发自:http://blog.csdn.net/u014427391/article/details/51419521 以Demo的形式讲诉拦截器的使用 项目结构如图: 需要的jar:有 ...
- JavaEE权限管理系统的搭建(四)--------使用拦截器实现登录认证和apache shiro密码加密
RBAC 基于角色的权限访问控制(Role-Based Access Control)在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限.这就极大地简化了权限的管理.在一个 ...
随机推荐
- TCP(控制传输协议)详解
1.传输层概述 在OSI参考模型中,网络层是面向通信的最高层但同时也是面向用户程序的最底层. 传输层的主要作用: 复用:在发送端,多个应用程序公用一个传输层: 分用:在接收端,传输层把从网络层接收到的 ...
- vs2012,打开早期版本窗体错误
<runtime> <NetFx40_LegacySecurityPolicy enabled="true"/></runtime>
- Server的API如何设计才满足RESTful要求?
Server的API如何设计才满足RESTful要求? 首先是简洁版里面的那几点.外加一些附带的 best practices:1. URL root: https://example.org/api ...
- python--ModuleFoundError
python 模块导入错误: 1. 首先py文件名不能和导入的模块名相同 (我在学习matplotlib库的时候就把文件名设置成matplotlib 多次运行不成功) 2. 由于我电脑上只有numpy ...
- python elasticsearch 批量写入数据
from elasticsearch import Elasticsearch from elasticsearch import helpers import pymysql import time ...
- 用js限制网页只能在微信内置浏览器或支付宝内置浏览器中打开
function is_weixinOrAli(){ var ua = navigator.userAgent.toLowerCase(); //判断浏览器的类型 if (ua.match(/Micr ...
- 为bootstrap+angularJs打造的表格代码生成器
private void btnCreateCode_Click(object sender, EventArgs e) { string objName = txtObjName.Text; if ...
- MYSQL数据库数据拆分之分库分表总结
数据存储演进思路一:单库单表 单库单表是最常见的数据库设计,例如,有一张用户(user)表放在数据库db中,所有的用户都可以在db库中的user表中查到. 数据存储演进思路二:单库多表 随着用户数量的 ...
- InputStream和Reader,FileInputStream和 FileReader的区别
一.InputStream和Reader的区别 InputStream和Reader都可以用来读数据(从文件中读取数据或从Socket中读取数据),最主要的区别如下: InputStream用来读取二 ...
- FFmpeg 结构体学习(八):FFMPEG中重要结构体之间的关系
FFMPEG中结构体很多.最关键的结构体可以分成以下几类: 解协议(http,rtsp,rtmp,mms) AVIOContext,URLProtocol,URLContext主要存储视音频使用的协议 ...