原文:http://zhangxiao.org/2016/jfinal-shiro-integration2/
续上一篇《JFianl整合Shiro(一)》
我准备在这里,具体的描述下JFianl整合Shiro的基本流程。

Maven Dependency

我现在使用是

<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>1.2.4</version>
</dependency>

配置web.xml

<listener><listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener><filter><filter-name>ShiroFilter</filter-name><filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter><filter-mapping><filter-name>ShiroFilter</filter-name><url-pattern>/*</url-pattern><dispatcher>REQUEST</dispatcher><dispatcher>FORWARD</dispatcher><dispatcher>INCLUDE</dispatcher><dispatcher>ERROR</dispatcher>
</filter-mapping>
  • <listener> 节点定义了一个ServletContextListener,在web应用程序启动的生时候启动Shiro环境(包括shiro的SecurityManager)默认情况下, 这个listener会自动去找我们的WEB-INF/classes/shiro.ini。
  • <filter> 节点定义了主要的ShiroFilter.这个filter被要求去过滤所有进入web应用程序的请求,因此shiro可以在一个请求到达应用程序之前进行必要的身份验证和访问控制。
  • <filter-mapping> 节点确保所有请求类型通过被ShiroFilterare提出(filed)filter-mapping节点一般是不指定dispatcher元素的,但是shiro需要它们都被定义,以便它能够过滤所有可能被web应用执行的不同请求类型。

添加shiro.ini文件

以下是我常用的shiro.ini

[main]
#sessionId相关设定
sessionIdCookie=org.apache.shiro.web.servlet.SimpleCookie
sessionIdCookie.name=jshop-admin-web
sessionIdCookie.path=/
sessionIdCookie.maxAge=1800
sessionIdCookie.httpOnly=true#sessionManager
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
sessionManager.sessionIdCookie = $sessionIdCookie
sessionManager.sessionIdCookieEnabled = true
sessionManager.globalSessionTimeout = 3600000#Realm
dbRealm = com.yourdomain.module.shiro.Realm#Cache
cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager#---------------
securityManager.sessionManager=$sessionManager
securityManager.realm = $dbRealm
securityManager.cacheManager = $cacheManager#[filters] 这个已经被取消,并入main中
#自定义验证过滤器
app_auth= com.yourdomain.module.shiro.AuthorizeFilter
#登录页面
app_auth.loginUrl = /auth/login
#未授权页面
app_auth.unauthorizedUrl=/auth/unauthorized[urls]
/test/** = anon
/public/** = anon
/uploads/** = anon
/passport/* = anon
/** = app_auth

sessionIdCookie、sessionManager

这俩个似乎没啥好说的。

cacheManager

它定义了一个新的缓存管理实例. 缓存在Shiro的构架体系中是一个非常重要的部分 - 它减少了和数据存贮之间持续往返的通讯。这个例子是使用了在单个JVM上比较好使的MemoryConstrainedCacheManager。如果对你的应用是部署在多个服务器(比如服务器集群)的话,你将会想使用一个集群缓存管理器的实现来替代。

realm

它是很关键的一个地方,这是是需要自己实现的。它作为shiro的一个组件,可以让shiro访问到你的系统中的用户、角色、权限等数据。

[urls]

这是非常重要的一个节点,来配置哪些路径映射哪些过滤器来进行鉴权,可以用逗号分开,配置多个过滤器。

这里的anon是shiro内置的一个过滤器,表示不需要进行鉴权。当然还是很多的shiro内置鉴权过滤器.在后面简单介绍下

[filters]

1.2以后,filters被并入[main]节点,如果继续保留也没事儿,只是会出个警告而已。app_auth是我自己实现的一个filter系统中主要使用这个filter进行鉴权。

shiro的内置filters

  • anon

org.apache.shiro.web.filter.authc.AnonymousFilter

  • authc

org.apache.shiro.web.filter.authc.FormAuthenticationFilter

  • authcBasic

org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter

  • logout

org.apache.shiro.web.filter.authc.LogoutFilter

  • noSessionCreation

org.apache.shiro.web.filter.session.NoSessionCreationFilter

  • perms

org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter

  • port

org.apache.shiro.web.filter.authz.PortFilter

  • rest

org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter

  • roles

org.apache.shiro.web.filter.authz.RolesAuthorizationFilter

  • ssl

org.apache.shiro.web.filter.authz.SslFilter

  • user

org.apache.shiro.web.filter.authc.UserFilter

自定义realm

com.yourdomain.module.shiro.Realm

需要继承shiro的AuthorizingRealm

public class Realm extends AuthorizingRealm

需要实现2个抽象方法

doGetAuthenticationInfo

主要是在登录的时候,进行用户身份验证

 /*** 获取用户验证信息* @param authcToken 所需验证的token* @return null or 身份信息* @throws AuthenticationException 验证异常*/
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {UsernamePasswordToken token = (UsernamePasswordToken) authcToken;SysAdmin admin = AdminService.getByUsername(token.getUsername());if (admin != null) {if(!admin.getPassword().equals(String.valueOf(token.getPassword()))){throw new AuthenticationException("密码错误");}Db.update("update sys_admin set loginTime=?,loginCount=loginCount+1 where id=?",new Date(),admin.getId());return new SimpleAuthenticationInfo(admin, admin.getPassword(),admin.getUsername());} else {throw new AuthenticationException("用户不存在");}}

doGetAuthorizationInfo

在第一次鉴权的时候进行调用,获取并保存到chache中(没有配置cache是不是每次都得调用?)

/*** 获取用户授权信息* @param principals 用户身份* @return null or 授权信息*/
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {SysAdmin userInPrincipal = (SysAdmin) principals.getPrimaryPrincipal();//根据用户获取权限List<String> stringPermissions = AdminService.getPermissions(userInPrincipal.getId());SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();//stringPermissions结构://user//user:list//user:add//user:edit//...info.addStringPermissions(stringPermissions);return info;
}

我这里返回的:字符串权限表达式(字符串通配符权限),对于各自所对应的资源(主要就是url路径),我是保存在数据库中,方便进行配置,然后再加上缓存。在自定义filter中将url转换成对应的表达式,然后进行鉴权。

登录、注销

登录

public void login() {if(Boolean.FALSE.equals(validateCaptcha("captcha"))){renderJson(CommonService.ajaxError("验证码错误"));return;}String username = getPara("username");String password = HashKit.md5(getPara("password"));Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(username, password);try {subject.login(token);renderJson(CommonService.ajaxSuccess());} catch (AuthenticationException e) {//虽然在realm中有具体的错误信息,但是安全起见,统一返回登录失败renderJson(CommonService.ajaxError("登陆失败"));}
}

注销

public void logout() {Subject subject = SecurityUtils.getSubject();subject.logout();redirect("/passport/login");
}

是不是感觉很easy:)

自定义filter

com.yourdomain.module.shiro.AuthorizeFilter

继承shiro的AuthorizationFilter

public class AuthorizeFilter extends AuthorizationFilter 

实现抽象方法isAccessAllowed

protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {//-----------------用户验证------------------Subject currentUser = getSubject(request, response);if (!currentUser.isAuthenticated())return false;//-----------------获取资源权限表达式-------------SysAdmin user = (SysAdmin) currentUser.getPrincipal();//request中加入attribute便于controller调用admin的信息request.setAttribute("admin",user);// 根据actionKey分析出权限表达式HttpServletRequest hsr = ((HttpServletRequest) request);String root = hsr.getContextPath();String URI = hsr.getRequestURI();String actionKey = URI.replace(root,"");if("".equals(actionKey))actionKey="/";RoleService roleService = new RoleService();String expression = roleService.getActionKeyExpression(actionKey);//-----------------进行鉴权-------------if (user==null)return false;else if(user.getStr("username").equals("superadmin")){//超级管理员具有所有权限return true;}else if(expression==null){return false;}else if(currentUser.isPermitted(expression)){//鉴权return true;}else{return false;}}
  1. 在这里,我根据actionKey分析出所对应的权限表达式
  2. 对于用户superadmin,默认具有所有权限,等同于,不需要鉴权
  3. 其他用户根据权限表达式,来进行鉴权

关于用户、角色、url资源及对应的权限表达式

你可以按照你自己的方式来构建一套,我相信对于大多数人应该不成问题,因为这个已经不属于shiro的范畴了。自己搞几个表,搞几个配置界面,做下缓存策略等等。

模板引擎中使用扩展函数(标签)

有时候你的应用也许需要在界面上进行鉴权,比如按钮啥的,这时候就可能需要扩展模板引擎的函数或者标签。

可以参考下 《beetl 和 shrio 结合》 http://my.oschina.net/xiandaf...

只要解决如何扩展模板引擎的函数或者标签,其他,我想应该都是雷同的吧。

JFinal整合Shiro(二)相关推荐

  1. jfinal整合shiro回顾

    2019独角兽企业重金招聘Python工程师标准>>> 目前jfinal使用shiro进行身份验证和授权的后台实现已完成,现在我再来总结下学习过程及代码实现过程.最近半年多项目开发都 ...

  2. jfinal使用shiro注解大体流程

    2019独角兽企业重金招聘Python工程师标准>>> 上一篇答题梳理了jfinal整合shiro的流程,jfinal读取shiro注解,这一篇将作为补充. 1.JFinalShir ...

  3. SSM整合shiro权限框架

    一.SSM整合shiro框架 1.步骤 1.添加shiro框架需要的jar包,包括shiro-core.shiro-web.shiro-spring的关系依赖 <!-- shiro jar包依赖 ...

  4. SpringBoot整合Shiro实现登录认证和授权CHCache

    文章目录 一. springboot实现普通登录 1 添加依赖 2 编写配置文件 3 新建实体类和mapper 4 编写业务层代码 5 编写控制器 6 编写启动类 7 编写登录页面和主页面 二. sp ...

  5. apache shiro怎么升级_Springboot整合Shiro之授权

    第二条为推广文章,阅读一次0.3kuai, 收入用于网站服务器及资源索取. Shiro是我们常用的一个权限管理框架,本文的重点是来介绍下在SpringBoot环境下我们怎么来使用Shiro. 一.添加 ...

  6. Spring Boot2 整合 Shiro ,两种方式全总结!

    前言:在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 文章目录 一.Spring Securit ...

  7. 补习系列(6)- springboot 整合 shiro 一指禅

    欢迎添加华为云小助手微信(微信号:HWCloud002 或 HWCloud003),输入关键字"加群",加入华为云线上技术讨论群:输入关键字"最新活动",获取华 ...

  8. SpringBoot整合Shiro实现权限控制,验证码

    本文介绍 SpringBoot 整合 shiro,相对于 Spring Security 而言,shiro 更加简单,没有那么复杂. 目前我的需求是一个博客系统,有用户和管理员两种角色.一个用户可能有 ...

  9. SpringBoot 整合Shiro 一指禅

    目标 了解ApacheShiro是什么,能做什么: 通过QuickStart 代码领会 Shiro的关键概念: 能基于SpringBoot 整合Shiro 实现URL安全访问: 掌握基于注解的方法,以 ...

最新文章

  1. 初识Quartz(三)
  2. 安装nginx0.7x+php5.2.8(Fastcgi)小结
  3. 玩玩.net的ildasm與ilasm (转)
  4. AOP面向切面编程在Android中的使用
  5. NOIP2017提高组比赛总结
  6. macos关闭软件更新小红点_MacOS和Windows哪个更适合你?
  7. Robotium双client測试框架
  8. IDEA中使用Maven
  9. 在电脑上安装python-在电脑上安装python的方法
  10. Q140:PBRT-V3,各种渲染算法(Integrator,积分器)汇总
  11. HDOJ 2147 HDU 2147 kiki's game ACM 2147 IN HDU
  12. 计算机组装与维护英语怎么说,计算机组装与维护-复习题(国外英语资料).doc
  13. c语言程序代码分享,一些简单的C语言程序代码(最新整理)
  14. JavaWeb教程———Ajax
  15. Android jetpack Room数据库(一)基本使用
  16. CentOS7 防火墙开放端口配置
  17. MySQL数据库软件及SQL简介
  18. ANSYS FLUENT 超临界流体物性分段线性插值数据批量导入
  19. 前端学习day 10--小米商城首页的制作
  20. 菜鸟教程 + Java基础课程 + part2

热门文章

  1. 结束下面sql块_如何执行超过100M的SQL脚本?
  2. 语言学与计算机应用学什么,2016考研专业:语言学及应用语言学
  3. 建立时间裕量与保持时间裕量的简单理解
  4. 我对变量产生了这些想法
  5. Expo大作战(三十)--expo sdk api之Permissions(权限管理模块),Pedometer(计步器api)
  6. 修改自动生成get/set方法模板代码
  7. 5G推进阻力大 面临多利益方博弈
  8. aspx文件、aspx.cs文件、aspx.designer.cs文件之讲解
  9. clojure的感觉
  10. 怎样修改flash builder注释里的@author