簡介
通過修改shiroFilter的class來實現。通過繼承org.apache.shiro.spring.web.ShiroFilterFactoryBean類,並把繼承類配置到shiro的配置文件中既可。
FilterChainDefinitionsService.java
package com.shiro;
import java.util.Map;
import javax.annotation.Resource;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.stereotype.Service;
@Service("filterChainDefinitionsService")
public class FilterChainDefinitionsService {
@Resource
private ShiroPermissionFactory permissionFactory;
public void reloadFilterChains() {
synchronized (permissionFactory) { //強制同步,控制線程安全
AbstractShiroFilter shiroFilter = null;
try {
shiroFilter = (AbstractShiroFilter) permissionFactory.getObject();
PathMatchingFilterChainResolver resolver = (PathMatchingFilterChainResolver) shiroFilter
.getFilterChainResolver();
// 過濾管理器
DefaultFilterChainManager manager = (DefaultFilterChainManager) resolver.getFilterChainManager();
// 清除權限配置
manager.getFilterChains().clear();
permissionFactory.getFilterChainDefinitionMap().clear();
// 重新設置權限
permissionFactory.setFilterChainDefinitions(ShiroPermissionFactory.definition);//傳入配置中的filterchains
Map<String, String> chains = permissionFactory.getFilterChainDefinitionMap();
//重新生成過濾鏈
if (!CollectionUtils.isEmpty(chains)) {
chains.forEach((url, definitionChains) -> {
manager.createChain(url, definitionChains.trim().replace(" ", ""));
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
ShiroPermissionFactory.java
package com.shiro;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.apache.shiro.config.Ini;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.web.config.IniFilterChainResolverFactory;
import com.pojo.Permission;
import com.service.IPermissionService;
public class ShiroPermissionFactory extends ShiroFilterFactoryBean {
@Resource
private IPermissionService permissionService;
/** 記錄配置中的過濾鏈 */
public static String definition = "";
/**
* 初始化設置過濾鏈
*/
@Override
public void setFilterChainDefinitions(String definitions) {
definition = definitions;// 記錄配置的靜態過濾鏈
List<Permission> permissions = permissionService.getPermissions();
Map<String, String> otherChains = new HashMap<String, String>();
permissions.forEach(permiss -> {
otherChains.put(permiss.getUrl(), permiss.getName());
});
otherChains.put("/**", "authc");
// 加載配置默認的過濾鏈
Ini ini = new Ini();
ini.load(definitions);
Ini.Section section = ini.getSection(IniFilterChainResolverFactory.URLS);
if (CollectionUtils.isEmpty(section)) {
section = ini.getSection(Ini.DEFAULT_SECTION_NAME);
}
// 加上數據庫中過濾鏈
section.putAll(otherChains);
setFilterChainDefinitionMap(section);
}
}
shiro部分配置文件
<!-- 配置shiro的過濾器工廠類,id- shiroFilter要和我們在web.xml中配置的過濾器一致 -->
<bean id="shiroFilter" class="com.shiro.ShiroPermissionFactory">
<!-- 調用我們配置的權限管理器 -->
<property name="securityManager" ref="securityManager" />
<!-- 配置我們的登錄請求地址 -->
<property name="loginUrl" value="/login.jsp" />
<!-- 配置我們在登錄頁登錄成功後的跳轉地址,如果你訪問的是非/login地址,則跳到您訪問的地址 -->
<property name="successUrl" value="/Adduser.jsp" />
<!-- 如果您請求的資源不再您的權限範圍,則跳轉到/403請求地址 -->
<property name="unauthorizedUrl" value="/unauthorized" />
<property name="filters">
<util:map>
<entry key="logout" value-ref="logoutFilter" />
</util:map>
</property>
<!-- 權限配置 -->
<property name="filterChainDefinitions">
<value>
/login=anon
/icon/**=anon
/js/**=anon
/logout=logout
</value>
</property>
</bean>
<bean id="logoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter">
<property name="redirectUrl" value="/login.jsp" />
PermissionServiceImpl.java
package com.serviceImpl;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.dao.PermissionMapper;
import com.pojo.Permission;
import com.service.IPermissionService;
import com.shiro.FilterChainDefinitionsService;
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 5)
@Service("permissionService")
public class PermissionServiceImpl implements IPermissionService {
@Resource
private FilterChainDefinitionsService definitionService;
@Resource
private PermissionMapper permissionmapper;
public Permission createPermission(Permission permission) {
permissionmapper.addpermission(permission);
definitionService.reloadFilterChains();//重新加載權限過濾鏈
return permission;
}
public void deletePermission(int permissionId) {
permissionmapper.deletepermission(permissionId);
definitionService.reloadFilterChains();//重新加載權限過濾鏈
}
public List<Permission> getPermissions() {
return permissionmapper.getPermissions();
}
public Permission getPermissionByid(int permissionid) {
return permissionmapper.getPermissionByid(permissionid);
}
public Permission updatePermission(Permission permission) {
permissionmapper.updatePermission(permission);
definitionService.reloadFilterChains();//重新加載權限過濾鏈
return permission;
}
public void deletePermissions(int permissionId) {
permissionmapper.deletePermissionsByid(permissionId);
definitionService.reloadFilterChains();//重新加載權限過濾鏈
}
}