Shiro繼承spring
1.需要所有的springmvc.xml的配置
2.需要所有的web.xml的配置
3.需要所有的pom.xml的依賴
4.需要所有的spring.xml的配置
5.jdbc.properties文件
Web.xml配置
<!-- 配置shiro的代理過濾器 filter-name的名字和spring中bean的id一樣 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<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>
在spring.xml中配置realm
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- ref="myDbRealm" 自定義類MyDbRealm加註解@component繼承AuthorizingRealm -->
<property name="realm" ref="myDbRealm"/>
</bean>
<!-- 後置處理器(用來註銷securityManager) -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
在spring.xml中配置ini
<!-- spring 配置ini bean的id與web.xml中filter-name一樣-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/login.html"/>
<property name="unauthorizedUrl" value="/un.html"/>
<property name="filterChainDefinitions">
<value>
/login.html = anon
/scu.jsp = authc
</value>
</property>
</bean>
加入依賴:
1. <dependency>
2. <groupId>org.apache.shiro</groupId>
3. <artifactId>shiro-spring</artifactId>
4. <version>1.4.0</version>
5. </dependency>
自定義filter實現動態配置url攔截
package cn.et.shiro.conf;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import cn.et.shiro.dao.UserMapper;
import cn.et.shiro.entity.Menu;
@Component
public class MyFilter extends AuthorizationFilter {
@Autowired
private ShiroFilterFactoryBean sffb;
/**
* 匹配指定過濾器規則的url
* @param regex
* @param url
* @return
*/
public static boolean matchUrl(String regex,String url){
regex=regex.replaceAll("/+", "/");
if(regex.equals(url)){
return true;
}
regex=regex.replaceAll("\\.", "\\\\.");
// /login.html /l*.html
regex=regex.replaceAll("\\*", ".*");
// /**/login.html /a/b/login.html
if(regex.indexOf("/.*.*/")>=0){
regex=regex.replaceAll("/\\.\\*\\.\\*/", "((/.*/)+|/)");
}
System.out.println(regex+"----"+url);
return Pattern.matches(regex, url);
}
@Autowired
UserMapper userMapper;
/**
* 測試
* @param args
*/
public static void main(String[] args) {
System.out.println(matchUrl("/**/s*.html","/t/g/login.html"));
}
/**
* isAccessAllowed用於判斷當前url的請求是否能驗證通過 如果驗證失敗 調用父類的onAccessDenied決定跳轉到登錄失敗頁還是授權失敗頁面
*/
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception {
HttpServletRequest req=(HttpServletRequest)request;
String contextPath=req.getContextPath();
//獲取用戶訪問的資源的路徑
String url=req.getRequestURI();
url=url.split(contextPath)[1];
//獲取哪些url需要哪些認證
//List<Menu> queryMenu=userMapper.queryMenuByUrl(url);
List<Menu> queryMenu=userMapper.qieryMenu();
if(queryMenu.size()==0){
return false;
}
String urlAuth=null;
for(Menu menu:queryMenu){
if(matchUrl(menu.getMenuUrl(),url)){
//取出權限
urlAuth=menu.getMenuFilter();
}
}
//通數據庫沒有配置當前url的授權
if(urlAuth==null){
return false;
}
//配置的過濾器是anon 直接放過
if(urlAuth.startsWith("anon")){
return true;
}
//配置的是authc 判斷當前用戶是否認證通過
Subject subject = getSubject(request, response);
if(urlAuth.startsWith("authc")){
return subject.isAuthenticated();
}
//授權認證 也需要判斷是否登錄 沒有登錄返回 登錄繼續下面的驗證
boolean ifAuthc=subject.isAuthenticated();
if(!ifAuthc)
return ifAuthc;
//如果是定義的roles過濾器 獲取所有的roles 一般是roles[a,b]
if(urlAuth.startsWith("roles")){
String[] rolesArray=urlAuth.split("roles\\[")[1].split("\\]")[0].split(",");
if (rolesArray == null || rolesArray.length == 0) {
return true;
}
Set<String> roles = CollectionUtils.asSet(rolesArray);
return subject.hasAllRoles(roles);
}
if(urlAuth.startsWith("perms")){
String[] perms=urlAuth.split("perms\\[")[1].split("\\]")[0].split(",");
boolean isPermitted = true;
if (perms != null && perms.length > 0) {
if (perms.length == 1) {
if (!subject.isPermitted(perms[0])) {
isPermitted = false;
}
} else {
if (!subject.isPermittedAll(perms)) {
isPermitted = false;
}
}
}
return isPermitted;
}
return false;
}
}
認證登錄實現AuthorizingRealm
package cn.et.shiro.conf;
import java.util.Set;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAccount;
import org.apache.shiro.authc.UsernamePasswordToken;
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 org.springframework.stereotype.Component;
import cn.et.shiro.dao.UserMapper;
import cn.et.shiro.entity.UserInfo;
@Component
public class MyDbRealm extends AuthorizingRealm {
@Autowired
UserMapper userMapper;
/**
* 認證
* 將登陸輸入的用戶名和密碼和數據庫中的用戶名和密碼對比 是否相等
* 返回值null表示認證失敗 非null認證通過
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//獲取從頁面傳入的token
UsernamePasswordToken upt=(UsernamePasswordToken)token;
//從數據庫中查詢userinfo對象
UserInfo queryUser=userMapper.queryUser(upt.getUsername());
//如果對象不爲空,且密碼相等 可以登錄
if(queryUser!=null && queryUser.getPassword().equals(new String(upt.getPassword()))){
SimpleAccount sa=new SimpleAccount(upt.getUsername(),upt.getPassword(),"MyDbRealm");
return sa;
}
return null;
}
/**
* 獲取當前文件的授權數據
* 將當前用戶在數據庫的角色和權限 加載到AuthorizationInfo
* 默認在進行授權認證的調用 檢查權限調用checkRole checkPerm
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//獲取用戶名
String userName=principals.getPrimaryPrincipal().toString();
//獲取角色
Set<String> roleList=userMapper.queryRoleByName(userName);
//獲取權限
Set<String> permsList=userMapper.queryPermsByName(userName);
SimpleAuthorizationInfo sa=new SimpleAuthorizationInfo();
sa.setRoles(roleList);
sa.setStringPermissions(permsList);
return sa;
}
}