国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當前位置: 首頁 > news >正文

四川華泰建設集團網站免費做網站網站

四川華泰建設集團網站,免費做網站網站,比較好的網站建設,南昌地寶網最新招聘一、權限管理 1.1 什么是權限管理 基本上只要涉及到用戶參數的系統(tǒng)都要進行權限管理,使用權限管理實現了對用戶訪問系統(tǒng)的控制,不同的用戶訪問不同的資源。按照安全規(guī)則或者安全策略控制用戶訪問資源,而且只能訪問被授權的資源 權限管理包括認…

?一、權限管理

1.1 什么是權限管理

  • 基本上只要涉及到用戶參數的系統(tǒng)都要進行權限管理,使用權限管理實現了對用戶訪問系統(tǒng)的控制,不同的用戶訪問不同的資源。按照安全規(guī)則或者安全策略控制用戶訪問資源,而且只能訪問被授權的資源
  • 權限管理包括認證和授權兩部分,當用戶訪問資源時先對其進行身份的認證,認證通過后即可訪問已經授權的資源。

1.2 身份認證

  • 用來判斷一個用戶是否合法的處理過程。用過用戶輸入的用戶名或者口令來和系統(tǒng)中存儲進行比較,從而認證用戶的身份是否正確

對于身份認證,也就是之前做的的登錄

1.3 授權

  • 用來控制認證過后的用戶可以訪問哪些資源。用戶身份認證后需要給該用戶分配可訪問的資源,如果沒有某個資源的權限,那么將無法訪問

二、Shiro架構

2.1 Shiro的理解

是一個功能強大且易實現的Java安全框架,使用Shiro可以執(zhí)行認證、授權、加密和會話管理。使用Shiro中提供的API可以快速輕松的保護任何程序

Shiro不依賴于WEB,即使是一個測試程序也能夠使用Shiro中的功能

2.2 Shiro的體系

官方圖示:

原理:

Subject

  • 表示主體,外部應用和Subject進行交互。Subject中記錄了當前操作用戶,這個用戶可以是一個發(fā)送請求的用戶,也可以是一個運行的程序
  • Subject在Shiro是一個接口,定義了很多認證授權的相關方法,外部程序通過Subject進行認證授權,Subject又是通過SecurityManager安全管理器就行認證管理

SecurityManager

  • 表示安全管理器,是Shiro中的核心,用來協(xié)調其托管的組件,以保證它們能夠順利協(xié)同工作。
  • 可以進行會話管理等

Authenticator

  • 表示身份認證器,負責執(zhí)行和響應用戶的身份認證嘗試的組件。當用戶進行登錄操作時,此組件進行處理

Authorizer

  • 表示授權器,負責控制用戶在系統(tǒng)中可以訪問哪些資源。在訪問資源時都需要該組件進行判斷當前用戶是否擁有這個資源的權限

Realm

  • 表示領域,充當Shiro與應用程序的安全數據之間的橋梁或者連接器,和DataSource數據源差不多,當需要和安全相關的數據(如用戶賬號)進行實際交互從而執(zhí)行認證和授權時,Shiro會從應用配置的一個或者多個Realm中查詢其中的內容
  • SecurityManager進行安全認證時需要通過Realm獲取到用戶權限數據
  • Realm不只是從數據庫取數據,還有認證和授權的相關邏輯代碼

SessionManager

  • 表示會話管理,知道如果創(chuàng)建和管理用戶生命周期,以便為所欲環(huán)境中的用戶提供強大的會話體驗
  • 不依賴WEB容器,所以Shiro可以使用在非WEB應用中也可以將分布式應用的會話集中在一點管理,次特征可以使它實現單點登錄

SessionDao

  • 表示會話Dao,是對session會話操作的一套接口

CacheManager

  • 表示緩存管理器,將用戶權限存儲到緩存中,從而提高性能

Cryptography

  • 表示密碼管理,Shiro中提供了一套加密/解密的組件,方便開發(fā)

三、Shiro中的認證

3.1 認證中的關鍵對象

  • Subject:主體

訪問系統(tǒng)的每一個用戶或者應用程序,經過認證的都成為主體

  • Principal:身份信息

是主體(Subject)進行身份證認證的表示,表示必須具有唯一性。比如用戶名/手機號/郵箱,一個主體(Subject)中可以有多個身份信息,但必須有一個主身份

  • Credential:憑證信息

3.2 認證流程

圖示:

文字:

  1. 收集使用者的Principal和Credential
  1. 提交進行身份驗證
  1. 如果驗證成功就允許訪問,否則重試身份證驗證或者阻止訪問

3.3 環(huán)境搭建

  1. 引入Shiro依賴
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.9.1</version>
</dependency>
  1. 在resources下創(chuàng)建.ini的配置文件,來臨時模擬數據庫存儲用戶的身份信息和憑證信息

[users]
admin=1234
tom=222
jack=456

  1. 編寫認證代碼
public class ShiroAuthentication {public static void main(String[] args) {// 1.創(chuàng)建SecurityManager安全管理器的實現類DefaultSecurityManager securityManager = new DefaultSecurityManager();// 2.將Realm中的數據設置到安全管理器中securityManager.setRealm(new IniRealm("classpath:shiro.ini")); // Realm去讀取ini中的主體與憑證信息// 3.將安全管理器設置到全局安全工具類中SecurityUtils.setSecurityManager(securityManager);// 4.獲取主體Subject subject = SecurityUtils.getSubject();// 5.認證if (!subject.isAuthenticated()) { // 是否已經認證// 如果沒有認證過,那么證明該用戶第一次登錄.收集使用者的身份信息和憑證信息UsernamePasswordToken token = new UsernamePasswordToken("admin","1234"); // 模擬前臺輸入// 提交身份信息和憑證信息subject.login(token);}}
}

3.4 處理結果

如果提交成功,執(zhí)行后續(xù)的邏輯代碼;提交過程中出現錯誤,那么Shiro將以拋異常的形式聲明錯誤

異常列表:

  • UnknowAccountException ?--> 未知賬號異?!居脩裘e誤】
  • IncorrectCredentialsException ?--> 憑證信息異常【密碼錯誤】
  • LockedAccountException ?--> 鎖定賬號異常
  • ExcessiveAttemptsException ?--> 過度嘗試異常
  • AuthenticationException ?--> 身份認證異常

修改以上程序:

try {// 開始認證subject.login(token);
}catch (UnknownAccountException e){System.out.println("賬號錯誤");
}catch (IncorrectCredentialsException e){System.out.println("密碼錯誤");
}

3.5 獲取主體身份信息與注銷

此操作必須保證認證通過

  • 獲取主體身份信息
if (subject.isAuthenticated()){ // 認證通過Object principal = subject.getPrincipal(); // 6. 獲取身份信息System.out.println(principal); // admin
}

  • 注銷
subject.logout();

3.6 底層實現

身份信息校驗

  • 在SimpleAccountRealm類中的doGetAuthenticationInfo方法判斷身份信息是否一致
  • 如果用戶名錯誤,那么返回的info==null,系統(tǒng)拋出UnknowAccountException異常

密碼校驗

  • 在AuthenticatingRealm類中的assertCredentialsMatch方法進行密碼(憑證信息)的校驗,Shiro中憑證信息默認的校驗規(guī)則是equals
  • 如果密碼錯誤,拋出IncorrectCredentialsException異常

3.7 自定義Realm

以后校驗用戶名肯定不能使用Shiro中定義的,需要連接數據庫,通過用戶名查詢。所以Shiro中也可以讓我們自定義Realm

Realm繼承圖

全部

主要部分

認證方法和授權方法都在AuthorizingRealm定義為抽象方法,等待子類繼承并重寫這兩個方法。

SimpleAccountRealm繼承了AuthorizingRealm,所以這個類里面有認證和授權功能,其兩個功能對應的方法為:

  • doGetAuthenticationInfo:認證
  • doGetAuthorizationInfo:授權

以后自定義的Realm只需要繼承AuthorizingRealm,然后重寫這兩個方法

/**
* 自定義Realm,繼承AuthorizingRealm類
*/
public class LoginRealm extends AuthorizingRealm {/*授權*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {return null;}/*認證*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {return null;}
}

在doGetAuthenticationInfo方法中獲取用戶的身份信息,然后校驗是否和數據庫中的一致

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// getPrincipal()獲取身份信息String username = (String) token.getPrincipal();if ("admin".equals(username)){// 正確 返回AuthenticationInfo的實現類// 參數:1.當前用戶的身份信息 2.驗證主體的憑證信息[如果和前臺傳入的不一致,拋出IncorrectCredentialsException異常] 3.當前Realmreturn new SimpleAuthenticationInfo(username,"1234",super.getName());}// 不正確返回一個null, info == null 拋出UnknownAccountException異常return null;
}

3.8 加密

測試程序:

public class MD5Test {public static void main(String[] args) {// 加密Md5Hash md5Hash = new Md5Hash("1234");// 加密+salt(鹽)Md5Hash md5Hash1 = new Md5Hash("1234", "f5gy");// 加密+salt(鹽)+散列次數Md5Hash md5Hash2 = new Md5Hash("1234","f5gy",1024);}
}

整合認證:

  1. 修改認證方法
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// getPrincipal()獲取身份信息String username = (String) token.getPrincipal();if ("admin".equals(username)){// 正確 返回AuthenticationInfo的實現類/*參數:1.當前用戶的身份信息2.驗證主體的憑證信息[如果和前臺傳入的不一致,拋出IncorrectCredentialsException異常]3.鹽4.當前Realm*/String password = "75b323294effa42ed07f895f37f9a192";String salt = "f5gy";return new SimpleAuthenticationInfo(username,password, ByteSource.Util.bytes(salt),super.getName());}// 不正確返回一個null, info == null 拋出UnknownAccountException異常return null;
}

  1. 修改密碼比較器

Shiro默認實用的是simpleCredentialsMatcher中的doCredentialsMatcher方法,這個方法使用的是equals的方式進行比較密碼。

CredentialsMatcher繼承圖:

使用HashedCredentialsMatcher這個類

LoginRealm realm = new LoginRealm();
HashedCredentialsMatcher hash = new HashedCredentialsMatcher();
// 設置算法
hash.setHashAlgorithmName("MD5");
// 設置散列次數
hash.setHashIterations(1024);
// 設置到Realm中
realm.setCredentialsMatcher(hash);

四、Shiro中的授權

4.1 授權中的關鍵對象

  • Who

表示主體,主題需要系統(tǒng)中的資源

  • What

表示資源,這個資源可以是一個按鈕、菜單等。資源又分為資源實例和資源類型

  • How

表示權限/許可,控制主體對資源的訪問

4.2 授權方式

  • 基于角色的訪問控制(Role-Based Access Control):以角色為中心進行權限控制
  • 基于資源的訪問控制(Resource-Based Access Control):以資源為中心進行權限控制

4.3 權限字符串

權限字符串的規(guī)則:資源標識符:操作,意思是對哪個資源進行哪些操作。":"是分割符,權限字符串可以使用"*"來表示通配符

4.4 校驗角色

  1. 在doGetAuthorizationInfo方法中設置當前主體的角色
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// 獲取主題中的身份信息[用戶名]String principal = (String) principals.getPrimaryPrincipal();// 返回AuthorizationInfo的實現類SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();// 給當前主體添加角色info.addRole("admin");info.addRole("user");return info;
}

  1. 模擬前臺測試
if (subject.isAuthenticated()){// 校驗單個角色System.out.println(subject.hasRole("admin")); // 是否有admin角色// 校驗多個角色System.out.println(subject.hasAllRoles(Arrays.asList("admin", "user"))); // 是否同時有admin user角色// 校驗 多次 角色boolean[] booleans = subject.hasRoles(Arrays.asList("admin", "user", "super"));for (boolean b : booleans) {System.out.println(b);}
}

4.5 校驗權限字符串

  1. 在doGetAuthorizationInfo方法中設置當前主體的權限字符串
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// 獲取主題中的身份信息[用戶名]String principal = (String) principals.getPrimaryPrincipal();// 返回AuthorizationInfo的實現類SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();// 給當前主體添加權限字符串info.addStringPermission("user:update");info.addStringPermission("product:select");return info;
}

  1. 模擬前臺測試

五、整合SpringBoot

5.1 整合思路

5.2 環(huán)境搭建

  1. 導入springboot和shiro整合的依賴包
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-starter</artifactId><version>1.4.0</version>
</dependency>
  1. 創(chuàng)建一個類,繼承AuthorizingRealm類,重寫授權和認證方法
public class MyRealm extends AuthorizingRealm {@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {return null;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {return null;}
}
  1. 編寫shiro和springboot整合的配置
@Configuration
public class ShiroConfig {@Beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();// 將SecurityManager設置到Filter中shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);return shiroFilterFactoryBean;}@Beanpublic DefaultWebSecurityManager defaultWebSecurityManager(Realm realm){DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();// 給安全管理器設置RealmdefaultWebSecurityManager.setRealm(realm);return defaultWebSecurityManager;}@Beanpublic Realm Realm(){LoginRealm loginRealm = new LoginRealm();return loginRealm;}
}
  1. 在ShiroFilter過濾器中配置需要攔截的資源URL
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();// 將SecurityManager設置到Filter中shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);//設置受限資源Map<String,String> map = new HashMap<>();/*** authc:該路徑資源需要認證和授權*/map.put("/**","authc"); // "/**"代表所有的資源路徑都攔截shiroFilterFactoryBean.setFilterChainDefinitionMap(map);return shiroFilterFactoryBean;
}
  1. 訪問資源跳轉到login.jsp,修改默認跳轉路徑
shiroFilterFactoryBean.setLoginUrl("/doLogin");@Controller
public class IndexController {@GetMapping("/doLogin")public String doLogin(){return "login";}
}
  1. 攔截后訪問/doLogin路徑

5.3 ShiroFilter過濾列表

Shiro中提供了多個默認的過濾器,用這些過濾器來控制指定URL路徑下的資源

配置縮寫

對應過濾器

描述

anon

AnonymousFilter

指定URL路徑下的資源可以匿名訪問

authc

FormAuthenticationFilter

指定URL路徑下的資源需要認證過后才能訪問

authcBasic

BasicHttpAuthenticationFilter

指定URL路徑下的資源需要basic登錄

logout

LogoutFilter

注銷過濾器,只需配置對應的URL路徑即可實現

noSessionCreation

NoSessionCreationFilter

禁止創(chuàng)建Session會話

perms

PermissionsAuthorizationFilter

需要有該URL資源對應的權限字符串才能訪問

port

PortFilter

指定某個端口可以訪問

rest

HttpMethodPermissionFilter

將HTTP請求轉換成相對應的動詞來構建權限字符串

roles

RolesAuthorizationFilter

需要有指定角色才能訪問

ssl

SslFilter

需要https請求才能訪問

user

UserFilter

需要已登錄或者"記住我"的用戶才能訪問

六、連接數據庫完成認證

6.1 注冊

  1. 表設計

  1. 注冊頁面
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><h1>注冊頁面</h1><hr><form action="/user/register" method="post">用戶名 : <input type="text" name="username"><br>密碼 : <input type="password" name="password"> <br><input type="submit" value="注冊"></form></body>
</html>
  1. 實體類POJO
@Data
public class User {private Long id;private String username;private String password;private String salt;
}
  1. 編寫Controller,調用service處理業(yè)務邏輯
@Controller
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/doRegister")public String doRegister(){return "register";}@PostMapping("/register")public String register(User user){int count = userService.register(user);if (count > 0)return "redirect:/doLogin";elsereturn "redirect:/doRegister";}
}
  1. 在ShiroFilter放過這些URL路徑
map.put("/user/register","anon");
map.put("/user/doRegister","anon");
  1. service中完成加密和散列鹽,調用Mapper完成注冊
@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;@Overridepublic int register(User user) {String salt = "ga*n";Md5Hash md5Hash = new Md5Hash(user.getPassword(),salt,1024);user.setPassword(md5Hash.toHex());user.setSalt(salt);return userMapper.insert(user);}
}
  1. Mapper接口和SQL語句
public interface UserMapper {int insert(User user);
}
<mapper namespace="com.jiuxiao.mapper.UserMapper"><insert id="insert">insert into t_user(id,username,password,salt) values(null,#{username},#{password},#{salt})</insert>
</mapper>
  1. 啟動類上添加@MapperScan注解,掃描Mapper包
@SpringBootApplication
@MapperScan("com.jiuxiao.mapper")
public class ShiroApp {public static void main(String[] args) {SpringApplication.run(ShiroApp.class,args);}
}
  1. 注冊頁面輸入用戶信息后,完成注冊

6.2 認證

  1. 在Shiro配置中修改密碼比較器
@Bean
public Realm realm(){LoginRealm loginRealm = new LoginRealm();HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();matcher.setHashAlgorithmName("MD5");matcher.setHashIterations(1024);loginRealm.setCredentialsMatcher(matcher);return loginRealm;
}
  1. 在自定義的Realm的doGetAuthenticationInfo方法中編寫認證邏輯
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {@Autowiredprivate UserService userService;// 獲取主體中的身份信息String principal = (String) authenticationToken.getPrincipal();// 調用service查詢數據庫User user = userService.selectByUsername(principal);if (!ObjectUtils.isEmpty(user)){// 如果可以查詢到,校驗密碼return new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(), ByteSource.Util.bytes(user.getSalt()),super.getName());}// 查詢不到直接返回nullreturn null;
}
  1. service調用Mapper
@Override
public User selectByUsername(String principal) {return userMapper.selectByUsername(principal);
}
  1. Mapper接口與SQL語句
User selectByUsername(String principal);
<select id="selectByUsername" resultType="com.jiuxiao.pojo.User">select * from t_user where username = #{username}
</select>
  1. 登錄頁面代碼
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>$Title$</title></head><body><h1>登錄頁面</h1><hr><form action="/user/login" method="post">用戶名: <input type="text" name="username"> <br>密碼: <input type="password" name="password"> <br><input type="submit" value="登錄"></form></body>
</html>
  1. 在Controller中編寫對應URL,封裝token,并處理異常結果
@Controller
@RequestMapping("/user")
public class UserController {@PostMapping("/login")public String login(String username,String password){Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(username, password);try {subject.login(token);return "index"; // 登陸成功跳轉到首頁} catch (UnknownAccountException e) {e.printStackTrace();System.out.println("用戶名錯誤");}catch (IncorrectCredentialsException e){e.printStackTrace();System.out.println("密碼錯誤");}return "login"; // 登錄失敗跳轉到登錄頁面}
}
  1. 首頁代碼
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>$Title$</title>
</head>
<body><h1>首頁</h1><hr><ul><li><a href="">用戶管理</a></li><li><a href="">商品管理</a></li><li><a href="">菜單管理</a></li><li><a href="">物流管理</a></li></ul>
</body>
</html>
  1. 在ShiroFilter過濾器中放過登錄URL
map.put("/user/login","anon");
  1. 頁面登錄成功后,進入到index.html

6.3 注銷

① 配置方式

  1. 在ShiroFilter過濾器中添加注銷的URL
map.put("/user/logout","logout");
  1. 在頁面直接輸入這個URL即可注銷

② 代碼方式

調用subject的logout方法完成注銷,頁面訪問該Controller的URL

七、授權的基本使用

7.1 校驗角色

在自定義的Realm的doGetAuthorizationInfo方法中給當前主體賦予角色

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {// 獲取主體中的身份信息String principal = (String) principalCollection.getPrimaryPrincipal();if ("jiuxiao".equals(principal)){ // 給jiuxiao用戶賦予admin和user角色SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();// 增加admin和user角色simpleAuthorizationInfo.addRole("admin");simpleAuthorizationInfo.addRole("user");return simpleAuthorizationInfo;}return null;
}

① 編碼方式

單個角色:使用subject中的hasRole方法

@Controller
@RequestMapping("/user")
public class UserController {@GetMapping("/save")@ResponseBodypublic String save(){Subject subject = SecurityUtils.getSubject();if (!subject.hasRole("admin")) { // 校驗當前角色是否有admin這個角色return "權限不足";}else{return "訪問成功"; ??}}
}

多個角色:使用subject中的hasAllRoles方法【這些角色都有才能訪問】

@Controller
@RequestMapping("/user")
public class UserController {@GetMapping("/save")@ResponseBodypublic String save(){List<String> roles = Arrays.asList("admin", "user");if (SecurityUtils.getSubject().hasAllRoles(roles)) {return "訪問成功";}else{return "權限不足";}}
}

② 注解方式

單個角色:直接在注解參數中寫入對應的角色即可

@Controller
@RequestMapping("/user")
public class UserController {@GetMapping("/save")@ResponseBody@RequiresRoles("admin")public String save(){return "訪問成功";}
}

多個角色:在注解中以數組的形式寫入多個角色【這些角色都有才能訪問】

@GetMapping("/save")
@ResponseBody
@RequiresRoles(value = {"admin","user"})
public String save(){return "訪問成功";
}

7.2 校驗權限字符串

在自定義的Realm的doGetAuthorizationInfo方法中給當前主體賦予權限字符串

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {String principal = (String) principalCollection.getPrimaryPrincipal();System.out.println("執(zhí)行授權:"+principal);if ("jiuxiao".equals(principal)){SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();// 添加權限字符串simpleAuthorizationInfo.addStringPermission("user:update");simpleAuthorizationInfo.addStringPermission("product:create");return simpleAuthorizationInfo;}return null;
}

① 編碼方式

調用subject中的isPermittedAll方法,參數為可變長參數(可以傳一個或者多個)【如果是多個,那么這個主體需要擁有參數里面所有的權限字符串才能訪問】

@Controller
@RequestMapping("/user")
public class UserController {@GetMapping("/save")@ResponseBodypublic String save(){Subject subject = SecurityUtils.getSubject();// if (subject.isPermittedAll("user:update")){ // 判斷當前主體使用擁有對user資源的001實例的更新操作if (subject.isPermittedAll("user:update","product:update")){return "訪問成功";}else{return "權限不足";}}
}

② 注解方式

單個權限字符串:直接在注解參數中寫入需要校驗的權限字符串即可

@GetMapping("/save")
@ResponseBody
@RequiresPermissions("user:update")
public String save(){return "訪問成功";
}

多個權限字符串:在注解中以數組的形式寫入多個權限字符串【當前主體主要擁有這些權限字符串才能訪問】

@GetMapping("/save")
@ResponseBody
@RequiresPermissions(value = {"user:update","product:create"})
public String save(){return "訪問成功";
}

③ 配置方式

在ShiroFilter過濾器使用perms進行權限的校驗

map.put("/user/save","perms[user:update,product:delete]"); // 數組中添加權限字符串

如果權限不足,頁面拋出401錯誤

在ShiroFilter中定義權限不足后跳轉的URL

注意:定義權限不足跳轉URL的方式只限制配置方式,別的方式都不能使用,權限不足時會拋出AuthorizationException異常

八、連接數據庫完成授權

8.1 表設計:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for role_perms
-- ----------------------------
DROP TABLE IF EXISTS `role_perms`;
CREATE TABLE `role_perms` ?(`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',`roleid` int(11) NULL DEFAULT NULL COMMENT '角色id',`permid` int(11) NULL DEFAULT NULL COMMENT '權限id',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_croatian_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for role_user
-- ----------------------------
DROP TABLE IF EXISTS `role_user`;
CREATE TABLE `role_user` ?(`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',`roleid` int(11) NULL DEFAULT NULL COMMENT '角色id',`userid` int(11) NULL DEFAULT NULL COMMENT '用戶id',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_croatian_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for t_perms
-- ----------------------------
DROP TABLE IF EXISTS `t_perms`;
CREATE TABLE `t_perms` ?(`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',`perm` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_croatian_ci NULL DEFAULT NULL COMMENT '權限字符串',`url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_croatian_ci NULL DEFAULT NULL COMMENT '資源URL',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_croatian_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for t_role
-- ----------------------------
DROP TABLE IF EXISTS `t_role`;
CREATE TABLE `t_role` ?(`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_croatian_ci NULL DEFAULT NULL COMMENT '角色',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_croatian_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` ?(`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵',`username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_croatian_ci NULL DEFAULT NULL COMMENT '用戶名(身份信息)',`password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_croatian_ci NULL DEFAULT NULL COMMENT '密碼(憑證信息)',`salt` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_croatian_ci NULL DEFAULT NULL COMMENT '鹽',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_croatian_ci ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;

8.2 POJO

User

@Data
public class User {private Long id;private String username;private String password;private String salt;private List<Role> roles;
}

Role

@Data
public class Role {private Integer id;private String name;private List<Perms> perms;
}

Perms

@Data
public class Perms {private Integer id;private String perm;private String url;
}

8.3 授權角色

  1. Mapper接口與SQL語句
List<Role> selectRoleNameByUserId(String username);
<select id="selectRoleNameByUserId" resultType="com.jiuxiao.pojo.Role">select r.id,r.namefrom t_user uleft join role_user ru on ru.userid = u.idleft join t_role r on r.id = ru.roleidwhere u.username = #{username}
</select>
  1. Service
@Override
public List<Role> getRoleNameByUsername(String username) {return userMapper.selectRoleNameByUsername(username);
}
  1. 自定義Realm中進行授權
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {String principal = (String) principalCollection.getPrimaryPrincipal();List<Role> roles = userService.getRoleNameByUsername(principal);if(!CollectionUtils.isEmpty(roles)){SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();roles.forEach(role-> simpleAuthorizationInfo.addRole(role.getName()));return simpleAuthorizationInfo;}return null;
}

8.4 授權字符串

  1. Mapper接口與SQL語句
?List<String> selectPermByRoleId(Integer id);
<select id="selectPermByRoleId" resultType="string">select p.permfrom t_role rleft join role_perms rp on r.id = rp.roleidleft join t_perms p on rp.permid = p.idwhere r.id = #{id}
</select>
  1. Service
@Override
public List<String> getPermByRoleId(Integer id) {return userMapper.selectPermByRoleId(id);
}
  1. 自定義Realm進行授權
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {String principal = (String) principalCollection.getPrimaryPrincipal();List<Role> roles = userService.getRoleNameByUsername(principal);if(!CollectionUtils.isEmpty(roles)){SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();roles.forEach(role-> simpleAuthorizationInfo.addRole(role.getName()));roles.forEach(role->{List<String> perms = userService.getPermByRoleId(role.getId());simpleAuthorizationInfo.addStringPermissions(perms);});return simpleAuthorizationInfo;}return null;
}

九、Shiro與thymeleaf整合

9.1 導入依賴

<dependency><groupId>com.github.theborakompanioni</groupId><artifactId>thymeleaf-extras-shiro</artifactId><version>2.0.0</version>
</dependency>

9.2 配置方言

@Bean
public ShiroDialect shiroDialect(){return new ShiroDialect();
}

9.3 引入工作空間

<html lang="en" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">

9.4 常用標簽使用

<!-- 驗證當前用戶是否為"訪客",即未認證的用戶 -->
<p shiro:guest="">未認證</p><!-- 認證通過或者已經"記住我"的用戶 -->
<p shiro:user="">hello</p><!-- 認證通過的用戶 -->
<p shiro:authenticated="">hello</p><!-- 輸出當前用戶信息,通常為賬號登錄信息 -->
<p shiro:principal></p><!-- 判斷當前用戶是否擁有該角色 -->
<p shiro:hasRole="admin">擁有該角色</p><!-- 當前用戶沒有該角色認證通過 -->
<p shiro:lacksRole="user">沒有改角色</p><!-- 判斷當前用戶是否擁有以下所有角色 -->
<p shiro:hasAllRoles="admin,user"></p><!-- 判斷當前用戶是否擁有以下任意一個角色 -->
<p shiro:hasAnyRoles="admin,user"></p><!-- 判斷當前用戶是否擁有以下權限字符串 -->
<p shiro:hasPermission="user:add"></p><!-- 當前用戶沒有該權限字符串認證通過 -->
<p shiro:lacksPermission="user:add"></p>

http://m.aloenet.com.cn/news/34862.html

相關文章:

  • wordpress 評論框 提示網頁優(yōu)化方案
  • 英文網站建設方法網站怎么收錄到百度
  • 信陽網站建設策劃方案廣東今日最新疫情通報
  • 酒類網站建設方案海南seo排名優(yōu)化公司
  • 黃石做網站的公司網絡營銷實施計劃
  • wordpress主題下新建頁面網站seo站外優(yōu)化
  • 杭州百度推廣公司有幾家手機優(yōu)化軟件排行
  • 網站建設的公司哪家是上市公司電商培訓基地
  • 網站建設公司怎么做業(yè)務aso優(yōu)化教程
  • 瀘州市住房與城鄉(xiāng)建設局網站google免費入口
  • 珠海網站制作首頁上線了建站
  • 怎么購買網站空間免費廣告發(fā)布平臺
  • 2023年企業(yè)年報入口推動防控措施持續(xù)優(yōu)化
  • wordpress+4.5+多站點手機百度免費下載
  • 網站設計怎么做創(chuàng)建自己的網站怎么弄
  • 閔行網站設計seo專家是什么意思
  • 六安建設局網站百度搜索關鍵詞數據
  • bec聽力哪個網站做的好網站制作公司排名
  • wordpress tag 別名北京優(yōu)化seo公司
  • 石家莊百度推廣家莊網站建設提高搜索引擎檢索效果的方法
  • 成都網站排名 生客seo自己搭建網站
  • 網站內地圖位置怎么做制作app軟件平臺
  • wordpress如何上傳超過2m合肥seo網站排名
  • 公安廳網站 做10道相關題目2022年小學生新聞摘抄十條
  • 河南網站制作線上銷售平臺有哪些
  • 貴州省網站節(jié)約化建設通知公司網址怎么制作
  • php網站開發(fā)需要什么軟件友情鏈接獲取的途徑有哪些
  • 網站后臺視頻app開發(fā)公司哪家好
  • 有關做聚合物電池公司的網站什么是網絡營銷渠道
  • 河南網站推廣網站seo好學嗎