Jfinal与shiro集成实现动态URL鉴权,不装插件只需要一个类
来源:互联网 发布:如何在淘宝发布产品 编辑:程序博客网 时间:2024/06/11 05:16
Jfinal与Shiro集成,有玛雅牛和dreamip两个Jfinal插件,但还是想以简单的方式实现动态URL鉴权。
本人的实现思路是,利用Shiro本身的过滤器扩展来实现动态通过数据库URL授权。方法如下:
1. 新建一个JFinal Maven项目
2. pom.xml中添加对Shiro的引用:
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-all</artifactId> <version>1.2.3</version> </dependency>3. /WEB-INF/web.xml中加入shiro的支持
<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>
4. resource目录下新增配置文件shiro.ini
[main]shiro.loginUrl = /auth/loginjdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealmdataSource = com.mysql.jdbc.jdbc2.optional.MysqlDataSourcedataSource.serverName = localhostdataSource.user = rootdataSource.password = rootdataSource.databaseName = jinlujdbcRealm.dataSource = $dataSourcejdbcRealm.authenticationQuery = SELECT password FROM sec_user WHERE status=1 AND username = ?jdbcRealm.userRolesQuery = SELECT r.role_name FROM sec_role AS r, sec_user_role AS ur WHERE r.id = ur.role_id AND r.status=1 AND ur.user_id = (SELECT id FROM sec_user WHERE username = ?)jdbcRealm.permissionsQuery = SELECT p.permission FROM sec_permission AS p, sec_role_permission AS rp WHERE p.id = rp.permission_id AND rp.role_id = (SELECT id FROM sec_role WHERE role_name = ?)jdbcRealm.permissionsLookupEnabled = truesecurityManager.realms = $jdbcRealmpasswordMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcherpasswordMatcher.hashAlgorithmName=MD5jdbcRealm.credentialsMatcher=$passwordMatcher#cacheshiroCacheManager = org.apache.shiro.cache.ehcache.EhCacheManagershiroCacheManager.cacheManagerConfigFile = classpath:ehcache.xmlsecurityManager.cacheManager = $shiroCacheManager #sessionsessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAOsessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManagersessionDAO.activeSessionsCacheName = shiro-activeSessionCachesessionManager.sessionDAO = $sessionDAOsecurityManager.sessionManager = $sessionManagersecurityManager.sessionManager.globalSessionTimeout = 3600000[filters]urlFilter=com.ziyTech.framework.interceptor.ShiroPathMatchFilter#这里的规则,web.xml中的配置的ShiroFilter会使用到。[urls]/=anon/img/**=anon/js/**=anon/css/**=anon/fonts/**=anon/uploader/**=anon/uploads/**=anon/auth/**=anon/msg/**=anon/api/**=anon/test/*=anon/**=urlFilter其中[main]节中,jdbcRealm定义一个数据库认证域,根据那几个SQL,可以构造出相应的数据表。定义了一个MD5的密码加密算法,在[filters]节自定义了一个过滤ShiroPathMatchFilter,并且在[urls]节将其它非开放的URL鉴权都指向它。
5. ShiroPathMatchFilter实现对URL进行过滤
package com.ziyTech.framework.interceptor;import com.google.common.collect.ArrayListMultimap;import com.google.common.collect.ImmutableListMultimap;import com.google.common.collect.Multimap;import com.jfinal.log.Log;import com.jfinal.plugin.activerecord.Db;import com.jfinal.plugin.activerecord.Record;import com.ziyTech.framework.service.Conf;import com.ziyTech.framework.model.SecRole;import org.apache.shiro.subject.Subject;import org.apache.shiro.web.filter.AccessControlFilter;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import java.util.*;public class ShiroPathMatchFilter extends AccessControlFilter { private static final Log log = Log.getLog(Conf.class); private static Multimap<String,String> allPermissions = ArrayListMultimap.create(); private static List<String> allRoles = new ArrayList<String>(); public static void initUrlMaps(){ log.info("start initializing permission maps."); // 缓存所有角色 allRoles.clear(); List<SecRole> secRoles =SecRole.dao.findAll(); for(SecRole secRole:secRoles){ allRoles.add(secRole.getStr("role_name")); } // 缓存所有权限 allPermissions.clear(); List<Record> rolePermissions = Db.find("select r.role_name,p.permission " + "from sec_role r,sec_permission p,sec_role_permission rp " + "where rp.role_id=r.id and rp.permission_id=p.id and permission is not null "); for(Record rolePermission :rolePermissions){ allPermissions.put(rolePermission.getStr("role_name"),rolePermission.getStr("permission")); } log.info("finished permissions map with entries:" + allPermissions.size()); } public boolean isAccessAllowed(Subject subject,String path){ if(allPermissions.isEmpty()){ initUrlMaps(); } for(String role : allRoles){ if(subject.hasRole(role)){ for(String url:allPermissions.get(role)){ if(pathsMatch(url, path)){ return true; } } } } return false; } @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object o) throws Exception { if(allPermissions.isEmpty()){ initUrlMaps(); } Subject subject = getSubject(request, response); for(String role : allRoles){ if(subject.hasRole(role)){ for(String url:allPermissions.get(role)){ if(pathsMatch(url, request)){ return true; } } } } return false; } @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { log.info("onAccessDenied"); setLoginUrl("/auth/login"); redirectToLogin(request,response); return false; }}
上述代码中静态变量allPermissions为MultiMap, 引这Google guava。有静态方法initUrlMaps,可在其它地方对授权信息进行初始化,如用户更改了角色,角色更改了权限时。
6. 我的鉴权相关数据库定义:
CREATE TABLE sec_user ( id INT NOT NULL AUTO_INCREMENT, username VARCHAR(50), password VARCHAR(50), email VARCHAR(100), mobile VARCHAR(20), avatar VARCHAR(200), full_name VARCHAR(100), status INT DEFAULT '1' NOT NULL, created_at TIMESTAMP NULL, updated_at TIMESTAMP NULL, deleted_at TIMESTAMP NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8CREATE TABLE sec_role ( id INT NOT NULL AUTO_INCREMENT, role_name VARCHAR(50), description VARCHAR(200), status INT DEFAULT '1' NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, updated_at TIMESTAMP NULL, deleted_at TIMESTAMP NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8CREATE TABLE sec_permission ( id INT NOT NULL AUTO_INCREMENT, permission VARCHAR(50) NOT NULL, description VARCHAR(200) NOT NULL, status INT DEFAULT '1' NOT NULL, category VARCHAR(50), name VARCHAR(50), url VARCHAR(50), PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8CREATE TABLE sec_user_role ( id INT NOT NULL AUTO_INCREMENT, user_id INT NOT NULL, role_id INT NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8CREATE TABLE sec_role_permission ( id INT NOT NULL AUTO_INCREMENT, role_id INT NOT NULL, permission_id INT NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
7. 使用方法
7.1 sec_permission表中,如图定义权限,指定URL pattern
7.2 通过sec_role_permission将多个权限赋予一个角色
7.3 通过sec_user_role给用户赋予角色,以实现授权
0 0
- Jfinal与shiro集成实现动态URL鉴权,不装插件只需要一个类
- 给JFinal添加Shiro插件功能,支持Shiro所有注解
- jfinal+freemarker+shiro的简单实现
- spring 整合shiro ,并实现动态url 配置
- JFinal所集成的插件们
- shiro与spring集成
- springMVC与shiro集成
- shiro 与spring集成
- Shiro与Spring集成
- shiro与spring集成
- shiro与spring集成
- Jquery只请求一个url,页面不刷新
- java bean代码生成器(只需要提供一个url和最外部的类名即可)
- 开涛的shiro动态URL会出现不进行授权解决方法
- 关于JFinal与kisso集成使用心得
- 大数据平台监控(一):Ganglia在集群中快速安装方案【内含通过yum只下载不安装,需要安装一个yum的插件】
- SSH集成Shiro,实现认证
- SSH集成shiro实现登陆
- HTML初识
- Java数据结构和算法-高级排序(1-希尔排序)
- 跨路径读取Cookie
- (0013)iOS 开发之集成友盟第三方登录
- Android笔记:Android获取系统时间的几种方法
- Jfinal与shiro集成实现动态URL鉴权,不装插件只需要一个类
- 2016.12.27_IIC的使用总结
- SpingMvc 基于java 配置(0配置)
- Android 镜像使用帮助
- Android HTTP和HTTPS那点事
- linux----which命令
- zTree插件setting配置详解
- 在禁用UAC时无法激活此应用
- wsimport 带https协议wdsl 时报错的处理