shiro配合html頁面完成細粒化權限控制
shiro是現在非常普遍使用的java權限框架了,因為其使用非常的簡便,適合快速的解決項目的權限需求問題。
現在我在自己項目中配置了shiro,項目前端是html靜態界面,動態數據都是由ajax完成。shiro中使用框架提供的jsp標簽完成頁面的細粒化權限控制,在我這個情況下無法配合使用,所以自己稍微拓展了一下,可以便捷的控制html頁面控件的權限。
在網上沒有查詢到類似的用法,所以這里分享一下自己的方法,順便也簡單記錄一下項目實戰中使用shiro快速的開發流程作為參考。
首先 數據庫中三個基本的表和基本的字段 下面是最簡化的建表
項目中使用的是mybatis與數據庫交互 mapper的xml文件中這樣寫分別獲取用戶 角色 權限
- <resultMap id="BaseResultMap" type="com.cyt.music.interfaces.pojo.user.UserInfo" >
- <id column="id" property="id" jdbcType="INTEGER" />
- <result column="userName" property="username" jdbcType="VARCHAR" />
- <result column="userStatus" property="userstatus" jdbcType="VARCHAR" />
- <result column="roleId" property="roleid" jdbcType="INTEGER" />
- <result column="password" property="password" jdbcType="VARCHAR" />
- </resultMap>
- <select id="getByUserName" parameterType="String" resultMap="BaseResultMap">
- select * from user_info where userName=#{userName}
- </select>
- <select id="getRoles" parameterType="String" resultType="String">
- select r.roleName from user_info u,user_role r where u.roleId=r.id and u.userName=#{userName}
- </select>
- <select id="getPermissions" parameterType="String" resultType="String">
- select p.permissionName from user_info u,user_role r,user_permission p where u.roleId=r.id and p.roleId=r.id and u.userName=#{userName}
- </select>
然后是shiro的核心 自定義realm 網上有很多教程都非常詳細的講解了realm 在這里也是非常簡化的自定義
- @Resource
- private UserService userService;
- /**
- * 為當限前登錄的用戶授予角色和權
- */
- @Override
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
- String userName=(String)principals.getPrimaryPrincipal();
- SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
- authorizationInfo.setRoles(userService.getRoles(userName));
- authorizationInfo.setStringPermissions(userService.getPermissions(userName));
- return authorizationInfo;
- }
- /**
- * 驗證當前登錄的用戶
- */
- @Override
- protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
- String userName=(String)token.getPrincipal();
- UserInfo user=userService.getByUserName(userName);
- if(user!=null){
- AuthenticationInfo authcInfo=new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),"xx");
- return authcInfo;
- }else{
- return null;
- }
- }
如何整合springmvc去配置自定義realm 和配置過濾器這些在網上都有非常詳細的配置說明
接下來就是自定義的html細粒化控制了
在前端每個頁面加載的時候都要向后台發出一次請求去請求到當前登錄用戶的角色
- $(document).ready(function () {
- //判斷角色
- judgeAuthority();
- });
- function judgeAuthority(){
- $.ajax({
- type: "post",
- url: "",
- contentType: 'application/json;charset=utf-8',
- success: function (data) {
- for(var i=0;i<data.length;i++){
- if(data[i]=="admin"){
- $(".admin").css("display","block");
- }
- }
- }
- })
- }
在你需要做隱藏的控件class中 加載你定義的角色名就可以了 在此處是admin 這兩個按鈕只有在擁有admin角色用戶登陸的時候才會顯示
最后controller層對角色進行控制,吧當前用戶擁有的角色json形式返回給前端,前端自己處理
- @RequestMapping("/session")
- public @ResponseBody List<String> session(HttpServletRequest request){
- Subject subject= SecurityUtils.getSubject();
- Session session=subject.getSession();
- List<String> roleList=new ArrayList<String>();
- if(subject.hasRole("admin")){
- roleList.add("admin");
- }
- if(subject.hasRole("teacher")){
- roleList.add("teacher");
- }
- return roleList;
- }
方法是能走通 勉強實現自己的需求,感覺可以做一個好點的封裝能把角色名暴露出來自定義,把前端操作暴露出來自定義不僅僅只是空間的顯示或者隱藏.這些都可以在后續做思考和修改。