这只是笔记
web.xml中引入 spring-shiro.xml
spring-shiro.xml :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<description>Shiro 配置</description>
<!-- 权限配置对照表
* @see /admin=authc,roles[admin] 表示用户必需已通过认证,并拥有admin角色才可以正常发起'/admin'请求
数据库权限格式admin:list
* @see /edit=authc,perms[admin:edit] 表示用户必需已通过认证,并拥有admin:edit权限才可以正常发起'/edit'请求
* @see /home=user 表示用户不一定需要已经通过认证,只需要曾经被Shiro记住过登录状态就可以正常发起'/home'请求
* @see /admins/**=anon 无参,表示可匿名使用,可以理解为匿名用户或游客
* @see /admins/user/**=authc 无参,表示需认证才能使用
* @see /admins/user/**=authcBasic 无参,表示httpBasic认证
* @see /admins/user/**=user 无参,表示必须存在用户,当登入操作时不做检查
* @see /admins/user/**=ssl 无参,表示安全的URL请求,协议为https
* @see /admins/user/**=perms[user:add:*]
* @see 参数可写多个,多参时必须加上引号,且参数之间用逗号分割,如/admins/user/**=perms["user:add:*,user:modify:*"]
* @see 当有多个参数时必须每个参数都通过才算通过,相当于isPermitedAll()方法
* @see /admins/user/**=port[8081]
* @see 当请求的URL端口不是8081时,跳转到schemal://serverName:8081?queryString
* @see 其中schmal是协议http或https等,serverName是你访问的Host,8081是Port端口,queryString是你访问的URL里的?后面的参数
* @see /admins/user/**=rest[user]
* @see 根据请求的方法,相当于/admins/user/**=perms[user:method],其中method为post,get,delete等
* @see /admins/user/**=roles[admin] 参数可写多个,多个时必须加上引号,且参数之间用逗号分割,如/admins/user/**=roles["admin,guest"]
* @see 当有多个参数时必须每个参数都通过才算通过,相当于hasAllRoles()方法 -->
<!-- 权限配置 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/direct.html" />
<property name="successUrl" value="/index.html" />
<property name="unauthorizedUrl" value="/403.html" /> <!-- 无权限跳转页面 -->
<property name="filters">
<util:map>
<entry key="authc">
<bean class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter"/>
<!-- <bean class="com.hbs.dipper.interceptor.MethodAuthenticationFilter"/> -->
</entry>
</util:map>
</property>
<property name="filterChainDefinitions">
<value>
<!-- 静态文件控制 -->
/css/** = anon
/images/** = anon
/js/** = anon
/index.html = user
/direct.html = anon
/403.html = anon
/login.html = anon
<!-- 用户管理权限 -->
/user/logout = anon <!-- 无需控制 -->
/user/getCurrentUser = user <!-- 登陆即不做检查 -->
/user/updatePwd = user
/user/login/** = anon
/user/get*/** = perms[user:view] <!-- 查看权限 -->
/view/user/** = perms[user:view] <!-- html权限控制 -->
/user/add*/** = perms[user:add] <!-- 添加权限 -->
/user/delete*/** = perms[user:delete] <!-- 删除权限 -->
/user/update*/** = perms[user:update] <!-- 修改权限 -->
/user/changeStatus/** = perms[user:enableOrDisable] <!-- 启用禁用用户 -->
/user/resetPassword/** = perms[user:resetPwd] <!-- 重制密码 -->
<!-- 部门权限 -->
/company/get*/** = perms[company:view] <!-- 查看权限 -->
/view/company/** = perms[company:view] <!-- html权限控制 -->
/company/add*/** = perms[company:add] <!-- 添加权限 -->
/company/delete*/** = perms[company:delete] <!-- 删除权限 -->
/company/update*/** = perms[company:update] <!-- 修改权限 -->
<!-- 角色权限 -->
/role/get*/** = perms[role:view] <!-- 查看权限 -->
/view/role/** = perms[role:view] <!-- html权限控制 -->
/role/add*/** = perms[role:add] <!-- 添加权限 -->
/role/delete*/** = perms[role:delete] <!-- 删除权限 -->
/role/update*/** = perms[role:update] <!-- 修改权限 -->
<!-- 权限管理 -->
/permission/get*/** = perms[permission:view] <!-- 查看权限 -->
/view/permission/** = perms[permission:view] <!-- html权限控制 -->
/permission/add*/** = perms[permission:add] <!-- 添加权限 -->
/permission/delete*/** = perms[permission:delete] <!-- 删除权限 -->
/permission/update*/** = perms[permission:update] <!-- 修改权限 -->
/**=rest[authc]<!-- 拦截所有get、post请求 -->
</value>
<!-- /**=rest[authc] 验证所有后台如get、post请求 -->
</property>
</bean>
<bean id="logout" class="org.apache.shiro.web.filter.authc.LogoutFilter">
<property name="redirectUrl" value="/login" />
</bean>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="monitorRealm" />
<!-- 需要使用cache的话加上这句
<property name="cacheManager" ref="shiroEhcacheManager" />
-->
</bean>
<!-- depends-on 表示在实例化该对象之前先实例化 depends-on中的对象 -->
<bean id="monitorRealm" class="com.hbs.dipper.interceptor.MonitorRealm" />
<!-- 启用spring注解方式拦截shiro权限 -->
<bean
class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager" />
</bean>
<!-- 自定义角色过滤器 支持多个角色可以访问同一个资源 eg:/home.jsp = authc,roleOR[admin,user] 用户有admin或者user角色 就可以访问-->
<!-- <bean id="roleOR" class="com.yale.app.security.OneRoleAuthorizationFilter"/> -->
<!-- srping注解配置 Post processor that automatically invokes init() and destroy() methods -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<!-- 启用shiro为spring配置的bean注释,只运行在lifecycleBeanProcessor之后 -->
<bean id="annotationProxy" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true" />
</bean>
<!-- 用户授权信息Cache, 采用EhCache,需要的话就配置上此信息
<bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml" />
</bean>
-->
<!-- spring对ehcache的缓存工厂支持 -->
<!-- <bean id="ehCacheManagerFactory"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml" />
</bean> -->
</beans>
shiro加载权限具体实现类
package com.hbs.dipper.interceptor;
import java.util.List;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Component;
import com.hbs.dipper.system.model.Permission;
import com.hbs.dipper.system.model.Role;
import com.hbs.dipper.system.model.User;
import com.hbs.dipper.system.service.PermissionService;
import com.hbs.dipper.system.service.RoleService;
import com.hbs.dipper.system.service.UserService;
import com.hbs.dipper.util.SpringContextUtil;
@Component
public class MonitorRealm extends AuthorizingRealm {
//由于shiro是在其他service之前加载,所以必须在运行时加载
UserService userService;
RoleService roleService;
PermissionService permissionService;
private Logger logger = Logger.getLogger(MonitorRealm.class);
/**
* 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用.
* 将权限查出来
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) {
logger.debug("get permissions================================>");
Subject currentUser =SecurityUtils.getSubject();
Session session = currentUser.getSession();
User user = (User) session.getAttribute("user");
if( user != null ) {
SimpleAuthorizationInfo info = (SimpleAuthorizationInfo) session.getAttribute("info");
if(info==null){
info = new SimpleAuthorizationInfo();
if(user.getUserId().equals(1)){//超级管理员,查出所有权限
info.addRole("admin");
List<Permission> permissions = permissionService.getList(null);
addPermission(info,permissions);
}else{//从数据库查出权限并添加
List<Role> roles = roleService.getRoleByUser(user.getUserId());
for (Role role : roles) {
info.addRole(role.getRoleName());
List<Permission> permissions = permissionService.getPermissionByRole(role.getRoleId());
for (Permission permission : permissions) {
info.addStringPermission(permission.getPermissionCode());
}
}
}
session.setAttribute("info", info);//缓存到session中
}
return info;
} else {
throw new AuthorizationException("login user is null!");
}
}
/**
* @Title: addPermission
* @Description: TODO(迭代添加权限)
* @param @param info
* @param @param list 参数
* @return void 返回类型
* @throws
*/
public void addPermission(SimpleAuthorizationInfo info,List<Permission> list){
for (Permission permission : list) {
info.addStringPermission(permission.getPermissionCode());
if(permission.getChildren()!=null&&permission.getChildren().size()>0)
addPermission(info,permission.getChildren());
}
}
/**
* 认证回调函数,登录时调用.
* 经测试登陆时会调用两次。。。
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken) throws AuthenticationException {
bind();
logger.debug("login=================================>");
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
String password = String.valueOf(token.getPassword());
//调用操作数据库的方法查询user信息
User user = userService.getByLoginName(token.getUsername()) ;
if( user != null ) {
if(password.equals(user.getPassword())){
return new SimpleAuthenticationInfo(user.getUserId(), user.getPassword(), getName());
}else{
return null;
}
} else {
return null;
}
}
private void bind(){
if(userService==null)
userService = (UserService) SpringContextUtil.getBean("userService");
if(roleService==null)
roleService = (RoleService) SpringContextUtil.getBean("roleService");
if(permissionService==null)
permissionService = (PermissionService) SpringContextUtil.getBean("permissionService");
}
public void clearCachedAuthorizationInfo(String principal) {
SimplePrincipalCollection principals =
new SimplePrincipalCollection(principal, getName());
clearCachedAuthorizationInfo(principals);
}
}
尚未解决的问题: 无法在shiro的Realm中使用注解 ,报空异常,初步判断是在spring加载其他bean之前执行了