1.环境
jdk1.7
spring.version4.2.2.RELEASE
shiro.version1.2.5
开发工具 eclipseMars.1 Release (4.5.1)
2.pom引入
<!-- shiro相关 应用shiro 需要在web.xml中配置shiro的过滤器 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<!-- 添加shiro web支持 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>${shiro.version}</version>
</dependency>
<!-- 添加shiro spring支持 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
<!-- 添加shiro ehcache支持 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro.version}</version>
</dependency>
<!-- 添加shiro 会话验证调度器 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-quartz</artifactId>
<version>${shiro.version}</version>
</dependency>
3.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-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.2.xsd " default-lazy-init="true">
<description>Shiro安全配置</description>
<!-- 自定义Realm -->
<bean id="loanAuthorizingRealm" class="com.yasinyt.loan.admin.shiro.LoanAuthorizingRealm"/>
<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="loanAuthorizingRealm"/>
<!--将缓存管理器,交给安全管理器-->
<property name="cacheManager" ref="shiroEhcacheManager"/>
</bean>
<bean id="roleOrFilter" class="com.yasinyt.loan.admin.shiro.CustomRolesAuthorizationFilter"/>
<!-- Shiro过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- Shiro的核心安全接口,这个属性是必须的 -->
<property name="securityManager" ref="securityManager"/>
<!-- 身份认证失败,则跳转到登录页面的配置 -->
<property name="loginUrl" value="/login"/>
<!-- <property name="successUrl" value="/rwd"/> -->
<!-- 权限认证失败,则跳转到指定页面 -->
<property name="unauthorizedUrl" value="/error/unauth"/>
<!-- 自定义过滤链的定义 -->
<property name="filters">
<map>
<entry key="roleOR" value-ref="roleOrFilter"/>
</map>
</property>
<!-- Shiro连接约束配置,即过滤链的定义
perms表示,这个url需要有对应的权限才能进入
authc表示,这这个mapping代表的url需要登陆之后才能查看
anon表示,这个mapping代表的url全部放行,所以可以看到所有js文件与image文件都被放行了
-->
<property name="filterChainDefinitions">
<value>
/error/unauth = anon
/logout = anon
/login = anon
/dologin = anon
/statics/** = anon
/sys/yzm/getYzm = anon
/favicon* = anon
/sys/admin** = authc,roles[maintenance_admin]
/rwd/** = authc,roleOR[maintenance_admin,maintenance_rwd]
/rwfq/** = authc,roleOR[maintenance_admin,maintenance_rwfq]
/repaymentEdit/rwfq/** = authc,roleOR[maintenance_admin,maintenance_rwfq]
/repaymentEdit/rwd/** = authc,roleOR[maintenance_admin,maintenance_rwd]
/** = authc,roles[maintenance_admin]
</value>
</property>
</bean>
<!-- 用户授权信息Cache, 采用EhCache -->
<bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:/spring/ehcache-shiro.xml"/>
</bean>
<!-- 在方法中 注入 securityManager ,进行代理控制 -->
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>
<property name="arguments" ref="securityManager"/>
</bean>
<!-- Shiro生命周期处理器 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<!-- AOP式方法级权限检查 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor"/>
<!-- 启用shrio授权注解拦截方式 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
</beans>
4.ehcache-shiro.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false" name="shiroCache">
<diskStore path="java.io.tmpdir" />
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
/>
</ehcache>
5.web.xml
<!-- Spring 的监听器可以通过这个上下文参数来获取spring-mybatis.xml的位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring/spring-*.xml</param-value>
</context-param>
<!-- 创建Spring的监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring MVC servlet -->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring/app-spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<!-- 此处可以配置成*.do,对应struts的后缀习惯 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
CustomRolesAuthorizationFilter.java
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
/**
* @projectName loan-admin-shiro
* @packageName com.yasinyt.loan.admin.shiro
* @author E-mail: liuzongyang@yasinyt.com
* @date 2017年10月23日 下午7:09:54
* @version 1.0
* @description TODO
*/
public class CustomRolesAuthorizationFilter extends AuthorizationFilter {
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception {
Subject subject = getSubject(request, response);
String[] rolesArray = (String[]) mappedValue;
if (rolesArray == null || rolesArray.length == 0) {
return true;
}
for (int i = 0; i < rolesArray.length; i++) {
if (subject.hasRole(rolesArray[i])) {
return true;
}
}
return false;
}
}
LoanAuthorizingRealm.java
import java.util.Set;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yasinyt.loan.admin.entity.User;
import com.yasinyt.loan.admin.service.UserService;
/**
* @projectName loan-admin-shiro
* @packageName com.yasinyt.loan.admin.interceptor
* @author E-mail: liuzongyang@yasinyt.com
* @date 2017年10月21日 上午10:56:31
* @version 1.0
* @description TODO
*/
@Service
public class LoanAuthorizingRealm extends AuthorizingRealm {
// private static final Logger log = LoggerFactory.getLogger(AuthorizingRealm.class);
@Autowired
private UserService userService;
/**
* 为当前登陆成功的用户授予权限和角色,已经登陆成功了
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo authInfo = new SimpleAuthorizationInfo();
User user = (User) principals.getPrimaryPrincipal();
// 查询用户权限
Set<String> roles = userService.getRoles(user.getUserName());
Set<String> perms = userService.getPermissions(user.getUserName());
authInfo.addRoles(roles);
authInfo.addStringPermissions(perms);
return authInfo;
}
/**
* 验证当前登录的用户,获取认证信息
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken)authcToken;
String userName = token.getUsername();
User user = userService.getByUserName(userName);
// 账号不存在
if (user == null) {
throw new UnknownAccountException("账号不存在");
// throw new IncorrectCredentialsException("用户名或密码错误");
}
// 账号不可用
if (user.getStatus() != User.STATUS_ACTIVATION) {
throw new DisabledAccountException("该账号不可用");
}
return new SimpleAuthenticationInfo(
user, user.getPassword().toCharArray(), getName());
}
}
工程目录: