文章目录:
- 1、如何使用shiro实现不同用户登录
- 2、shiro 的全新控制怎么动态
- 3、如何使用Shiro实现不同用户登录成功后跳转到不同主页
- 4、springmvc shiro进行整合时,登录为什么不进realm
- 5、springmvc+shiro集成,但不想要shiro的登录要怎么做
- 6、shiro-all 1.2.3 jar包 doc源码文件下载
如何使用shiro实现不同用户登录
1、力推 Filter 过滤器,
2、后台判断根据权限跳转页面
登陆成功后获取 Subject 对象.
然后通过 Subject 对象来判断当前用户的角色/权限,之后执行不同的跳转(直接在LoginAction中做).
shiro 的全新控制怎么动态
html] view plain copy
package com.silvery.security.shiro.service.impl;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.shiro.cache.Cache;
import org.springframework.beans.factory.annotation.Autowired;
import com.silvery.project.cms.model.Authority;
import com.silvery.project.cms.model.Permission;
import com.silvery.project.cms.service.PermissionService;
import com.silvery.project.cms.vo.PermissionVo;
import com.silvery.security.shiro.cache.SimpleMapCache;
import com.silvery.security.shiro.cache.extend.SimpleCacheManager;
import com.silvery.security.variable.Const;
/**
*
* 加载第三方角色资源配置服务类
*
* @author shadow
*
*/
public class SimpleFilterChainDefinitionsService extends AbstractFilterChainDefinitionsService {
@Autowired
private SimpleCacheManager simpleCacheManager;
@Autowired
private PermissionService permissionService;
@Override
public MapString, String initOtherPermission() {
return converResultMap(initOperation());
}
@SuppressWarnings("unchecked")
private MapObject, Object initOperation() {
MapObject, Object resultMap = new HashMapObject, Object();
// 加载数据库所有资源
PermissionVo vo = new PermissionVo();
ListPermission permissions = (ListPermission) permissionService.query(vo).getValue();
ListAuthority authorities = null;
for (Permission permission : permissions) {
// 遍历查询当前资源的配置角色
vo.setId(permission.getId());
authorities = (ListAuthority) permissionService.query4authority(vo).getValue();
// 组装角色集合
SetString authoritySet = getPermissionSet(authorities);
if (authoritySet.isEmpty()) {
continue;
}
if (permission.getType() == 1) {
// 请求路径资源处理
resultMap.put(permission.getContent(), MessageFormat.format(SHIRO_AUTHORITY_FORMAT, authoritySet));
} else {
// 元素资源处理
MapObject, Object map = new HashMapObject, Object(1);
map.put(Const.OTHER_PERMISSSION_CACHE_NAME, authoritySet);
CacheObject, Object cache = new SimpleMapCache(Const.OTHER_PERMISSSION_CACHE_NAME, map);
simpleCacheManager.createCache(Const.OTHER_PERMISSSION_CACHE_NAME + "_" + permission.getId(), cache);
}
}
return resultMap;
}
/** 获取角色名称集合 */
private SetString getPermissionSet(ListAuthority authorities) {
SetString authoritieSet = new HashSetString(authorities.size());
for (Authority authority : authorities) {
authoritieSet.add(authority.getContent());
}
return authoritieSet;
}
/** 泛型Object转换String */
private MapString, String converResultMap(MapObject, Object map) {
MapString, String resultMap = new HashMapString, String(map.size());
for (Map.EntryObject, Object entry : map.entrySet()) {
resultMap.put(entry.getKey().toString(), entry.getValue().toString());
}
return resultMap;
}
}
1. 加载所有资源,包括请求URL,元素节点等数据,我这里为了演示,没有分那么细就只有两种
2. 请求URL的直接放到框架中,形式如/user/list.do*=role[root,user],跟我们shiro.xml配置的一样
3. 元素节点则相应放到以键值对的形式放到缓存,以节点的编号组合成key保证可以找到这个缓存对,值是相应的角色集合
我们的缓存就存在各个资源所需要的角色集合, 加载数据步骤已经完毕了下面看看我们是怎么应用的
首先我是使用springMVC+freemarker作为展现层,具体怎么配置整合我也不说,百度一堆,直接看我帖代码说明
[html] view plain copy
!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ""
html xmlns=""
head
meta http-equiv="Content-Type" content="text/html; charset=utf-8" /
title欢迎主页/title
/head
body
${username!"游客"}, 欢迎您的访问! br /
hr /
可选操作:
#if username??
@sec id="2" body="a href='/cms/user/page.do'用户列表/a " /a href="/cms/authority/page.do"权限列表/a a href="/cms/permission/page.do"资源列表/a a href="/cms/logout.do"注销退出/a
#else
a href="#" onclick="top.location.href='/cms/logout.do';"前往登录/a
/#if
hr /
/body
/html
很明显看到我的页面有一个@sec的标签,然后有两个参数,一个id,一个是body,至于id则是你资源的编号,body是需要元素节点内容
然后我们怎么通过这个标签来判定是否在页面渲染body的节点内容呢?
下面我们看看这个@sec的实现
[html] view plain copy
package com.silvery.core.freemarker;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import com.silvery.security.shiro.cache.extend.SimpleCacheManager;
import com.silvery.security.variable.Const;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
/**
*
* FreeMarker自定义标签,节点权限控制
*
* @author shadow
*
*/
public class SecurityTag implements TemplateDirectiveModel {
@Autowired
private SimpleCacheManager simpleCacheManager;
@SuppressWarnings("unchecked")
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody directiveBody)
throws TemplateException, IOException {
Object id = params.get("id");
Object body = params.get("body");
validate(id, body);
if (hasRole(id)) {
env.getOut().write(body.toString());
} else {
env.getOut().write("");
}
}
private void validate(Object id, Object body) throws TemplateException {
if (id == null || id.toString().trim().equals("")) {
throw new TemplateException("参数[id]不能为空", null);
}
if (body == null) {
throw new TemplateException("参数[body]不能为空", null);
}
}
@SuppressWarnings("unchecked")
private boolean hasRole(Object id) {
CacheObject, Object cache = simpleCacheManager.getCache(Const.OTHER_PERMISSSION_CACHE_NAME + "_" + id);
if (cache == null) {
return false;
} else {
Object obj = cache.get(Const.OTHER_PERMISSSION_CACHE_NAME);
if (obj == null) {
return false;
}
SetString authoritySet = (SetString) obj;
Subject subject = SecurityUtils.getSubject();
for (String authority : authoritySet) {
if (subject.hasRole(authority)) {
return true;
}
}
}
return false;
}
}
很清晰地看到,我们是用到之前的那个资源角色缓存,通过判定缓存中存在的角色与当前shiro认证用户拥有的角色匹配,如存在任意相同角色则渲染相应节点
如Subject拥有角色[root,user],而x编号资源拥有[user,test]角色,很明显有交集会认证通过,反之则直接渲染空字符
大概流程就是这样,有的人可能会问,如何配置这个tag实现类呢?我帖下spring-mvc.xml的freemarker配置
[html] view plain copy
!-- FreeMarker配置 --
bean id="freemarkerConfig"
class="4622-8a69-93c7-611f org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"
property name="templateLoaderPath" value="/WEB-INF/ftl/" /
property name="defaultEncoding" value="UTF-8" /
property name="freemarkerVariables"
map
entry key="sec"
bean class="8a69-93c7-611f-9c00 com.silvery.core.freemarker.SecurityTag"
/bean
/entry
/map
/property
property name="freemarkerSettings"
props
prop key="template_update_delay"10/prop
prop key="locale"zh_CN/prop
prop key="datetime_format"yyyy-MM-dd HH:mm:ss/prop
prop key="date_format"yyyy-MM-dd/prop
prop key="number_format"#.####/prop
/props
/property
/bean
相信懂freemarker的人都能看明白,我也不累赘说明;最后再说一句,谢谢大家支持.
如何使用Shiro实现不同用户登录成功后跳转到不同主页
重写登录成功后方法,extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter
/**
* 重写登录成功后方法,根据情况跳转到不同的路径
*/
@SuppressWarnings("unchecked")
@Override
protected boolean onLoginSuccess(AuthenticationToken token,
Subject subject, ServletRequest request, ServletResponse response)
throws Exception {
// 判断有没有认证
ListString roles = (ListString) UserUtils.getSession().getAttribute("roles");
for (int r = 0; r roles.size(); r++) {
if ("auth".equals(roles.get(r))) {
// 认证跳转到首页
WebUtils.issueRedirect(request, response, getSuccessUrl(), null, true);
}
}
// 未认证跳转到认证页面
WebUtils.issueRedirect(request, response, "/aa", null, true);
return false;
}
springmvc shiro进行整合时,登录为什么不进realm
要你自己去触发Login操作
推荐一套完整的Shiro Demo,免费的。
Shiro介绍文档:
Demo已经部署到线上,地址是
管理员帐号:admin,密码:sojson.com 如果密码错误,请用sojson。PS:你可以注册自己的帐号,然后用管理员赋权限给你自己的帐号,但是,每20分钟会把数据初始化一次。建议自己下载源码,让Demo跑起来,然后跑的更快。
springmvc+shiro集成,但不想要shiro的登录要怎么做
你自己登录,登录完毕之后,手动调用Shiro的登录,伪登录即可。
推荐一个完整的ShiroDemo
Shiro介绍文档:
Demo已经部署到线上,地址是,
管理员帐号:admin,密码:sojson.com 如果密码错误,请用sojson。
PS:你可以注册自己的帐号,然后用管理员赋权限给你自己的帐号,但是,每20分钟会把数据初始化一次。建议自己下载源码,让Demo跑起来,然后跑的更快。
shiro-all 1.2.3 jar包 doc源码文件下载
首先在Apache的官网上下载一个文件,最终的下载页面网页链接,进入到该页面以后,首先看到的链接(蓝色),点击就可以下载了,这个就是压缩包其实就包含了shiro的源码,解压压缩包后,一步步进入,直到出现多个文件夹,可以看到其中有个文件夹core,这里面包含的就是源码,将这个文件夹压缩成一个 .zip或 .jar文件,打开eclipse,选中想要查看的某个Shiro方法,单击右键,open Declaration(右键菜单从上向下第四项),如果,源码未添加,打开的界面会出现一个按钮,单击出现一个会话框,在对应的条目中将刚才压缩的包导入,,然后,你想要的源码就蹦出来了!
据库所有资源 PermissionVo vo = new PermissionVo(); ListPermission permissions = (ListPermission) permissionService.query(vo).getValue(); ListAu