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("\n", "<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
