ssm整合shiro許可權管理-乾貨
一、 表結構(表關係)
user、role、user_role、permission、role_permission,使用者,角色,許可權相互之間多對多
二、配置檔案
1、spring-shiro.xml
loginUrl是認證前可以訪問的URL,通常是登入頁面或者登入的方法路徑
successUrl是認證成功之後跳轉的URL(可以是頁面路徑,也可以是方法)
unauthorizedUrl是經過認證後,沒有許可權的跳轉路徑
<bean id="shiroFilter"class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager"
<property name="loginUrl" value="/login"/>
<property name="successUrl" value="/userLogin" />
<property name="unauthorizedUrl" value="/login" />
<!-- 基本系統級別許可權配置 -->
<property name="filterChainDefinitions">
<value>
/css/* = anon
/js/* = anon
/img/* = anon
/jsp/login.jsp = anon
/userLogin = anon <!-- 登入相關不攔截 -->
/addUser = roles[admin]
/** = authc
</value>
</property>
<!-- 自定義shiro的 Filter-->
<!--<property name="filters"> <util:map> <entrykey="login" value-ref="login"></entry>
</util:map></property> -->
</bean>
<!--安全管理器-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!--設定自定義Realm-->
<property name="realm"ref="myRealm"/>
<!--將快取管理器,交給安全管理器-->
<property name="cacheManager"ref="shiroEhcacheManager"/>
<!-- 注入session管理器
<propertyname="sessionManager"ref="sessionManager" />-->
<!-- 記住密碼管理 -->
<!-- <propertyname="rememberMeManager"ref="rememberMeManager"/>-->
</bean>
<!-- 專案自定義的Realm -->
<bean id="myRealm" class="com.snowlink.realm.MyRealm"/>
<bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile"value="classpath:shiro-cache.xml"></property>
</bean>
2、spring配置檔案
Spring配置檔案中其他配置按照框架正常配置,只需要引入shiro的配置檔案
<!--匯入shiro的配置檔案 -->
<importresource="spring-shiro.xml"/>
3、spring-mvc的配置檔案
在springMVC的配置檔案中其他按照springMVC的正常配置,只需加入shiro的註解掃描和註解支援
<!-- 開啟aop,對類代理 -->
<aop:configproxy-target-class="true"></aop:config>
<!--開啟shiro註解支援 -->
<beanclass="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<propertyname="securityManager"ref="securityManager"/>
</bean>4、web.xml配置
注意:在web.xml中加入shiro的過濾器時一定要放在DispatcherServlet過濾器之前,否則要經過許可權檢驗的路徑會被springmvc的前端控制器過濾,很大可能會出錯
<!--shiroFilter -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>5、Ehcache的快取配置
<ehcacheupdateCheck="false"name="shiroCache">
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"></defaultCache>
</ehcache>
6、pom.xml中需要引入的jar依賴
<!-- shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.2.3</version>
</dependency>
三、Shiro的執行流程和原理
ApplicationCode:應用程式程式碼,由開發人員負責開發
Subject:當前使用者
SecurityManager:安全管理器,管理所有的使用者,認證、授權等。
Realm:安全資料橋,類似於Dao,負責訪問安全資料
從上圖中可以看出shiro的核心控制元件就是SecurityManager(安全管理器)
四、ApplicationCode
通過subject(當前使用者)呼叫login()方法,安全管理器呼叫Realm進行認證和授權
publicclass MyRealmextends AuthorizingRealm{
@Resource
private UserMappingUserMapping;
@Resource
private UserServiceuserService;
//授權
@Override
protected AuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipalCollection) {
Cache<Object,AuthorizationInfo>shiroCache = getAuthorizationCache();
//TODO Auto-generated method stub
User loginUser = (User) principalCollection.getPrimaryPrincipal();
List<Role> roleList = userService.getRole(loginUser);
List<String> roles = new ArrayList<>();
List<String> permissions = new ArrayList<>();
if (roleList.size() > 0) {
for (Rolerole :roleList) {
List<Permission>pList =userService.getPermissions(role);
for (Permissionpermission :pList) {
permissions.add(permission.getP_name());
}
roles.add(role.getRole_name());
}
}
SimpleAuthorizationInfoinfo =new SimpleAuthorizationInfo();
info.addRoles(roles);
info.addStringPermissions(permissions);
returninfo;
}
//認證
@Override
protected AuthenticationInfodoGetAuthenticationInfo(AuthenticationTokentoken)throws AuthenticationException {
//TODO Auto-generated method stub
UsernamePasswordTokenusernamePasswordToken = (UsernamePasswordToken)token;
String username = usernamePasswordToken.getUsername();
char[]password =usernamePasswordToken.getPassword();
User user = UserMapping.findUserByName(username);
if (user ==null) {
returnnull;
}
SimpleAuthenticationInfoinfo =newSimpleAuthenticationInfo(user,user.getPassword(),this.getClass().getName());
returninfo;
}
}