shiro是一個特別簡單,易用的框架,在此記錄一下shiro的使用配置。
首先,創建四張表:user role user_role permission,分別爲用戶、角色、用戶與角色關係表和權限表。
user表結構:
role表結構:
user_role
permission
當然,表結構如何設計是沒有關係的,你可以根據自己偏好設計。
web.xml中加入shiro的過濾器:
<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>
然後配置shiro,可以寫在spring的配置文件中,也可以另起一個配置文件,配置內容如下:
<!-- 配置權限管理器 -->
<bean id="myShiro" class="com.itmayong.util.MyShrio"></bean>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- 我們自定義的realm -->
<property name="realm" ref="myShiro"/>
<!-- 緩存管理器 -->
<property name="cacheManager" ref="cacheManager"/>
</bean>
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 權限管理器 -->
<property name="securityManager" ref="securityManager"/>
<!-- 登錄地址 -->
<property name="loginUrl" value="/login.jsp"/>
<!-- 登錄後跳轉到業務頁面 -->
<property name="successUrl" value="/main.jsp"/>
<!-- 錯誤頁面 -->
<property name="unauthorizedUrl" value="/error.jsp"/>
<!-- 權限配置 -->
<property name="filterChainDefinitions">
<value>
<!-- anon無權限訪問請求,此處是登錄頁面和登錄請求 -->
/login.do = anon
/static/**=anon
<!-- 需要權限爲add的用戶才能訪問此請求-->
/user=perms[user:add]
<!-- 需要管理員角色才能訪問此頁面 -->
/user/add=roles[admin]
<!--攔截非靜態資源的所有請求-->
/** = authc
</value>
</property>
</bean>
<bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
上面的配置文件我們指定了自定義的realm,內容如下:
public class MyShrio extends AuthorizingRealm{
@Autowired
private UserServiceIf userService;
/**
* 權限認證,獲取登錄用戶的權限
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
String loginName=(String) principalCollection.fromRealm(getName()).iterator().next();
//此處連庫匹配了登錄用戶的數據,具體怎麼做,需要根據個人需求而定
User user=userService.findByName(loginName);
List<Role> list = user.getRoleList();
if(user!=null){
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
//獲取用戶的角色名稱
info.setRoles(user.getRolesName());
//獲取用戶的權限
List<Role> roleList=user.getRoleList();
for (Role role : roleList) {
info.addStringPermissions(role.getPermissionsName());
}
return info;
}
return null;
}
/**
* 登錄認證,創建用戶的登錄信息
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token=(UsernamePasswordToken) authenticationToken;
//判斷用戶登錄狀態
User user=userService.findByName(token.getUsername());
if(user!=null){
//保存用戶登錄信息到認證中
return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
}
return null;
}
}
最後,你可以寫一個頁面和Controller進行測試了,當然也可以細分一下權限和角色,以應用到實際更復雜的場景中。
頁面內容可以使用下邊的方式對需要角色和權限控制的內容進行包裹,以達到權限控制的目的。
<shiro:hasRole name="admin">需要管理員角色</shiro:hasRole>
<shiro:hasPermission name="add">需要add權限</shiro:hasPermission>