从Web.xml入手。代码片段:
<context-param>
<param-name>shiroEnvironmentClass</param-name>
<param-value>com.jfaker.framework.security.shiro.ShiroIniWebEnvironment</param-value>
</context-param>
<context-param>
<param-name>shiroConfigLocations</param-name>
<param-value>classpath:jfaker-shiro.ini</param-value>
</context-param>
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>
需要留意的是com.jfaker.framework.security.shiro.ShiroIniWebEnvironment
该类继承IniWebEnvironment ,并以init方法作为着手点。
public void init() {
super.init();
FilterChainResolver resolver = getFilterChainResolver();
if(resolver != null && resolver instanceof PathMatchingFilterChainResolver) {
PathMatchingFilterChainResolver pathResolver = (PathMatchingFilterChainResolver)resolver;
ShiroPlugin.setFilterChainManager(pathResolver.getFilterChainManager());
}
}
由于采用路径匹配的方式进行授权管控,通过ShiroPlugin插件作为中介与JFinal集成。并把FilterChainManager传递到ShiroPlugin,再由JFinal从数据库加载所有配置好的URL及权限信息到Shiro。
public class ShiroPlugin implements IPlugin {
private static Logger log = LoggerFactory.getLogger(ShiroPlugin.class);
public static final String PREMISSION_FORMAT = "perms[\"{0}\"]";
private static FilterChainManager manager = null;
@Override
public boolean start() {
if(manager == null) return false;
List<Resource> resources = Resource.dao.getWithAuthAll();
for(Resource resource : resources) {
String source = resource.getStr("source");
String authority = resource.getStr("authorityName");
if(StringUtils.isEmpty(source)) {
continue;
}
if(source.indexOf(";") != -1) {
String[] sources = source.split(";");
for(String singleSource : sources) {
createChain(manager, singleSource, authority);
}
} else {
createChain(manager, source, authority);
}
}
manager.createChain("/**", "user");
return true;
}
@Override
public boolean stop() {
return true;
}
private void createChain(FilterChainManager manager, String key, String value) {
log.info("add authority url[url=" + key + "\tvalue=" + value + "]");
manager.createChain(key, MessageFormat.format(PREMISSION_FORMAT, value));
}
public static void setFilterChainManager(FilterChainManager manager) {
ShiroPlugin.manager = manager;
}
}
大概的流程如图:
不知理解是否正确,请大家批评指正。