简介
通过修改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();//重新加载权限过滤链
}
}