Shiro之溫故而知新


Shiro分爲認證和授權
在這裏插入圖片描述

認證中抽象出來的對象

Subject:主體

訪問系統的用戶,主體可以是用戶,程序等。進行認證的都成爲主體。

Principal:身份信息

是主體(subject)進行身份認證的標識,標識必須具有唯一性,如用戶名、手機號、郵箱地址等,一個主體可以
有多個身份,但是必須有一個主身份(Primary Principal),比如手機號登錄,或者賬戶登錄。

Credential:憑證信息

是隻有主體自己知道的安全信息,如密碼、證書等。

授權中抽象出來的對象

授權可簡單理解爲who對what(which)進行How操作:

Who,即主體(Subject)

主體需要訪問系統中的資源。

What,即資源(Resource)

如系統菜單、頁面、按鈕、類方法、系統商品信息等。資源包括資源類型和資源實例,比如商品信息爲資源類型,類型爲t01的商品爲資源實例,編號爲001的商品信息也屬於資源實例。

How,權限/許可(Permission)

規定了主體對資源的操作許可,權限離開資源沒有意義,如用戶查詢權限、用戶添加權限、某個類方法的調用權限、編號爲001用戶的修改權限等,通過權限可知主體對哪些資源都有哪些操作
許可。

權限分爲粗顆粒和細顆粒,粗顆粒權限是指對資源類型的權限,細顆粒權限是對資源實例的權限

shiro架構圖

在這裏插入圖片描述

權限模型

在這裏插入圖片描述

shiro的授權

subject.isAuthenticated()							//登錄是否成功
subject.hasRole("admin")							//驗證是否有admin角色
subject.hasAllRoles(Arrays.asList("admin","super"))		//驗證是否包含所有角色
subject.hasRoles(Arrays.asList("admin","super"))		//驗證是否有某一個角色
subject.isAuthenticated()							//驗證是否登錄成功
subject.isPermitted("user:delete")					//驗證用戶是否有該權限

web頁面shiro標籤

<shiro:authenticated></shiro:authenticated>			//已經認證
<shiro:notAuthenticated></shiro:notAuthenticated>	//未認證
<shiro:principal></shiro:principal>					//獲取主身份信息

<shiro:hasRole name="admin"></shiro:hasRole>						//判斷是否有該角色
<shiro:hasAnyRoles name="admin,super"></shiro:hasAnyRoles>		//判斷是否有某一個角色(有一個就可執行)

<shiro:hasPermission name="banner:delete"></shiro:hasPermission>		//判斷是否有該權限

認證和授權流程圖

在這裏插入圖片描述

SpringBoot整合Shiro

引入依賴

 <dependency>
     <groupId>org.apache.shiro</groupId>
     <artifactId>shiro-spring-boot-web-starter</artifactId>
     <version>1.4.1</version>
 </dependency>

在這裏插入圖片描述
創建shiro過濾器

package cn.czboy.shiro;

import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;

@Configuration
public class ShiroFilter {

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
        System.out.println("===========shiroFilter");
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        HashMap<String,String> map = new HashMap<>();
        map.put("/subject/**","anon");
        map.put("/login.jsp","anon");
        map.put("/index.jsp","anon");
        map.put("/**","authc");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        shiroFilterFactoryBean.setLoginUrl("/login.jsp");//設置攔截後跳轉的網頁
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        return shiroFilterFactoryBean;
    }

    @Bean
    public DefaultWebSecurityManager securityManager(MyRealm myRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        MemoryConstrainedCacheManager cache = new MemoryConstrainedCacheManager();
        securityManager.setCacheManager(cache);
        securityManager.setRealm(myRealm);
        return securityManager;
    }

    @Bean
    public MyRealm myRealm() {
        MyRealm myRealm = new MyRealm();
        return myRealm;
    }
}

創建自定義Realm

package cn.czboy.shiro;

import cn.czboy.entity.Role;
import cn.czboy.entity.Subject;
import cn.czboy.mapper.SubjectDao;
import cn.czboy.utils.SpringContextUtil;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

public class MyRealm extends AuthorizingRealm {


    /**授權*/
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = (String)principalCollection.getPrimaryPrincipal();
        SubjectDao subjectDao = (SubjectDao)SpringContextUtil.getBean(SubjectDao.class);
        //根據主體獲取角色
        List<Role> roles = subjectDao.findByRole(username);
		
       	HashSet<String> set = new HashSet<>();
        ArrayList<String> arrayList = new ArrayList<>();
       
        SimpleAuthorizationInfo authorizationInfo = null;
        if(primaryPrincipal.equals(admin.getUsername())){
            authorizationInfo = new SimpleAuthorizationInfo();

            for(RoleDto role:roles){
                arrayList.add(role.getRoleName());
                String id = role.getId();
                //根據角色查權限
                List<String> permissionss = adminService.findByPermission(id);
                for(String key:permissionss){
                    set.add(key);
                }
            }

            authorizationInfo.addStringPermissions(set);//權限賦值
            authorizationInfo.addRoles(arrayList);//角色賦值
        }

        return authorizationInfo;
    }

    /**認證*/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String username = (String)authenticationToken.getPrincipal();
        String password = new String((char[]) authenticationToken.getCredentials());
        SubjectDao subjectDao = (SubjectDao)SpringContextUtil.getBean(SubjectDao.class);
        Subject subject = subjectDao.findByUserName(username);
        AuthenticationInfo authenticationInfo = null;
        if (subject == null) {
            throw new UnknownAccountException("賬戶不存在!");
        }
        if (!subject.getUsername().equals(username)) {
            throw new UnknownAccountException("用戶名錯誤!");
        }
        if (!subject.getPassword().equals(password)) {
            throw new IncorrectCredentialsException("密碼錯誤!");
        }
        authenticationInfo  = new SimpleAuthenticationInfo(subject.getUsername(), subject.getPassword(), this.getName());
        System.out.println("================="+subject);
        return authenticationInfo;
    }
}

SubjectController

package cn.czboy.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/subject")
public class SubjectController {

    /**用戶登陸*/
    @RequestMapping("/login")
    public String login(String username,String password) {
        System.out.println("========="+username);
        System.out.println("========="+password);
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            subject.login(token);
            return "yes";
        } catch (UnknownAccountException e) {
            System.out.println(e.getMessage());
            return "no";
        } catch (IncorrectCredentialsException e) {
            System.out.println(e.getMessage());
            return "no";
        }
    }
}

發佈了33 篇原創文章 · 獲贊 14 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章