1.shiro.inil初始化自定义的realm(很多都可以初始化。。。)
[main]
#自定义 realm
customRealm=cn.cjq.util.shiro.UserRealm
#将realm设置到securityManager
securityManager.realms=$customRealm
2.web.xml开启shiro拦截
<!-- 添加 Shiro 相关配置 -->
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 -->
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.springmvc配置开启aop代理,初始化自定义异常类:获取用户无权限异常
<aop:aspectj-autoproxy/>
<!-- 自定义异常处理-->
<bean id="exceptionResolver" class="cn.cjq.util.MyExceptionResolver"></bean>
4.shiro的xml配置:启用aop代理,启用shiro注解
<?xml version="1.0" encoding="GB2312"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<description>== Shiro Components ==</description>
<!-- 缓存管理器 使用Ehcache实现 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
</bean>
<!-- 凭证匹配器 未使用-->
<bean id="credentialsMatcher" class="cn.cjq.util.shiro.RetryLimitHashedCredentialsMatcher">
<constructor-arg ref="cacheManager"/>
<property name="hashAlgorithmName" value="md5"/>
<property name="hashIterations" value="2"/>
<property name="storedCredentialsHexEncoded" value="true"/>
</bean>
<!-- rememberMeManager管理器,写cookie,取出cookie生成用户信息 -->
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
<property name="cookie" ref="rememberMeCookie" />
</bean>
<!-- 记住我cookie -->
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<!-- rememberMe是cookie的名字 -->
<constructor-arg value="rememberMe" />
<!-- 记住我cookie生效时间30天 -->
<property name="maxAge" value="2592000" />
</bean>
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/login/toLogin.do"/>
<property name="unauthorizedUrl" value="/login/toLogin.do"/> //无验证权限跳转
<property name="filters">
<map>
<entry key="authc" value-ref="formAuthenticationFilter"/>
</map>
</property>
<property name="filterChainDefinitions">
<value>
/login/**=anon
/api/** = authc
/person/** = authc
</value>
</property>
</bean>
<!-- 会话ID生成器 -->
<bean id="sessionIdGenerator"
class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>
<!-- 会话Cookie模板 -->
<bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="sid"/>
<property name="httpOnly" value="true"/>
<property name="maxAge" value="1800000"/>
</bean>
<!-- 会话DAO -->
<bean id="sessionDAO"
class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
<property name="activeSessionsCacheName" value="shiro-activeSessionCache"/>
<property name="sessionIdGenerator" ref="sessionIdGenerator"/>
</bean>
<bean id="sessionValidationScheduler"
class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler">
<property name="sessionValidationInterval" value="1800000"/>
<property name="sessionManager" ref="sessionManager"/>
</bean>
<!-- 会话管理器 -->
<bean id="sessionManager"
class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="globalSessionTimeout" value="1800000"/>
<property name="deleteInvalidSessions" value="true"/>
<property name="sessionValidationSchedulerEnabled" value="true"/>
<property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
<property name="sessionDAO" ref="sessionDAO"/>
<property name="sessionIdCookieEnabled" value="true"/>
<property name="sessionIdCookie" ref="sessionIdCookie"/>
</bean>
<bean id="formAuthenticationFilter" class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">
<property name="usernameParam" value="username"/>
<property name="passwordParam" value="password"/>
<property name="rememberMeParam" value="rememberMe"/>
</bean>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- Single realm app. If you have multiple realms, use the 'realms' property instead. -->
<property name="realm" ref="myShiroRealm"/>
<property name="sessionManager" ref="sessionManager"/>
<property name="cacheManager" ref="cacheManager"/>
<!-- 记住我 -->
<property name="rememberMeManager" ref="rememberMeManager"/>
</bean>
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<!-- 自定义的realm -->
<bean id="myShiroRealm" class="cn.cjq.util.shiro.UserRealm">
<!-- <property name="userservice" ref="userservice"/>-->
<property name="cachingEnabled" value="true"/>
<property name="authenticationCachingEnabled" value="true"/>
<property name="authenticationCacheName" value="authenticationCache"/>
<property name="authorizationCachingEnabled" value="true"/>
<property name="authorizationCacheName" value="authorizationCache"/>
</bean>
<!-- 开启Shiro注解 -->
<bean
class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager" />
</bean>
</beans>
5.自定义realm
package cn.cjq.util.shiro;
import cn.cjq.entity.User;
import cn.cjq.mapper.UserMapper;
import cn.cjq.service.user.UserService;
import cn.cjq.util.SpringContextUtil;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
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 java.util.List;
import java.util.Set;
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserMapper userMapper;
/**
* 认证信息
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
String username = (String)token.getPrincipal();
UserService userService = (UserService) SpringContextUtil.getBean("userServiceImpl");
User user = null;
try {
user = userService.findByUserName(username);
} catch (Exception e) {
e.printStackTrace();
}
if(user == null) {
throw new IncorrectCredentialsException();//没找到帐号
}
//交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,如果觉得人家的不好可以自定义实现
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
user.getUsername(), //用户名
user.getPassword(), //密码
getName() //realm name
);
return authenticationInfo;
}
/**
* 授权信息
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String)principals.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
// UserService userService = (UserService) SpringContextUtil.getBean("userServiceImpl");
try {
authorizationInfo.setRoles(userMapper.findUserRoles(username));
authorizationInfo.setStringPermissions(userMapper.findUserPermissions(username));
} catch (Exception e) {
e.printStackTrace();
}
return authorizationInfo;
}
@Override
public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
super.clearCachedAuthorizationInfo(principals);
}
@Override
public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
super.clearCachedAuthenticationInfo(principals);
}
@Override
public void clearCache(PrincipalCollection principals) {
super.clearCache(principals);
}
public void clearAllCachedAuthorizationInfo() {
getAuthorizationCache().clear();
}
public void clearAllCachedAuthenticationInfo() {
getAuthenticationCache().clear();
}
public void clearAllCache() {
clearAllCachedAuthenticationInfo();
clearAllCachedAuthorizationInfo();
}
}
6.自定义异常处理类,在springmvc中的bean定义authorizationInfo中存入的值有关
package cn.cjq.util;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* 类名称:MyExceptionResolver.java
* 类描述:
* @author cjq
* @version 1.0
*/
public class MyExceptionResolver implements HandlerExceptionResolver {
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
// TODO Auto-generated method stub
System.out.println("==============shiro权限异常开始=============");
//如果是shiro无权操作,因为shiro 在操作auno等一部分不进行转发至无权限url
if(ex instanceof UnauthorizedException){
ModelAndView mv = new ModelAndView("/403");
return mv;
}
ex.printStackTrace();
System.out.println("==============shiro权限异常结束=============");
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex.toString().replaceAll(" ", "<br/>"));
return mv;
}
}
7.实例,注解一个url方法,跟自定义realm授权
package cn.cjq.controller;
import cn.cjq.entity.Menu;
import cn.cjq.entity.User;
import cn.cjq.service.user.UserService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@Controller
@RequestMapping("/person")
public class PersonalController {
@Resource
private UserService userServiceImpl;
/**
* 个人中心
* @return
*/
@RequestMapping(value = {"/main"}, method = RequestMethod.GET)
@RequiresPermissions("1dd44f6f850944898d0220314eb955a1")
public String index(HttpServletRequest request) throws Exception{
//用户信息
User user=(User) request.getSession().getAttribute("user");
request.setAttribute("user",user);
//菜单列表
List<Menu> Menulist=userServiceImpl.ListMenuByUserId(user.getUerid());
request.setAttribute("Menulist",Menulist);
return "personalmain";
}
}
---------------------------------------------------------------------------------------------------------------------
附录
anon,authc,authcBasic,user是第一组认证过滤器
perms,port,rest,roles,ssl是第二组授权过滤器
相关url:http://www.cppblog.com/guojingjia2006/archive/2014/05/14/206956.html