中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

四川華泰建設(shè)集團(tuán)網(wǎng)站免費做網(wǎng)站網(wǎng)站

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

?一、權(quán)限管理

1.1 什么是權(quán)限管理

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

1.2 身份認(rèn)證

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

對于身份認(rèn)證,也就是之前做的的登錄

1.3 授權(quán)

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

二、Shiro架構(gòu)

2.1 Shiro的理解

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

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

2.2 Shiro的體系

官方圖示:

原理:

Subject

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

SecurityManager

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

Authenticator

  • 表示身份認(rèn)證器,負(fù)責(zé)執(zhí)行和響應(yīng)用戶的身份認(rèn)證嘗試的組件。當(dāng)用戶進(jìn)行登錄操作時,此組件進(jìn)行處理

Authorizer

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

Realm

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

SessionManager

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

SessionDao

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

CacheManager

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

Cryptography

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

三、Shiro中的認(rèn)證

3.1 認(rèn)證中的關(guān)鍵對象

  • Subject:主體

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

  • Principal:身份信息

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

  • Credential:憑證信息

3.2 認(rèn)證流程

圖示:

文字:

  1. 收集使用者的Principal和Credential
  1. 提交進(jìn)行身份驗證
  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的配置文件,來臨時模擬數(shù)據(jù)庫存儲用戶的身份信息和憑證信息

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

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

3.4 處理結(jié)果

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

異常列表:

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

修改以上程序:

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

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

此操作必須保證認(rèn)證通過

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

  • 注銷
subject.logout();

3.6 底層實現(xiàn)

身份信息校驗

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

密碼校驗

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

3.7 自定義Realm

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

Realm繼承圖

全部

主要部分

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

SimpleAccountRealm繼承了AuthorizingRealm,所以這個類里面有認(rèn)證和授權(quán)功能,其兩個功能對應(yīng)的方法為:

  • doGetAuthenticationInfo:認(rèn)證
  • doGetAuthorizationInfo:授權(quán)

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

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

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

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// getPrincipal()獲取身份信息String username = (String) token.getPrincipal();if ("admin".equals(username)){// 正確 返回AuthenticationInfo的實現(xiàn)類// 參數(shù):1.當(dāng)前用戶的身份信息 2.驗證主體的憑證信息[如果和前臺傳入的不一致,拋出IncorrectCredentialsException異常] 3.當(dāng)前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(鹽)+散列次數(shù)Md5Hash md5Hash2 = new Md5Hash("1234","f5gy",1024);}
}

整合認(rèn)證:

  1. 修改認(rèn)證方法
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// getPrincipal()獲取身份信息String username = (String) token.getPrincipal();if ("admin".equals(username)){// 正確 返回AuthenticationInfo的實現(xiàn)類/*參數(shù):1.當(dāng)前用戶的身份信息2.驗證主體的憑證信息[如果和前臺傳入的不一致,拋出IncorrectCredentialsException異常]3.鹽4.當(dāng)前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默認(rèn)實用的是simpleCredentialsMatcher中的doCredentialsMatcher方法,這個方法使用的是equals的方式進(jìn)行比較密碼。

CredentialsMatcher繼承圖:

使用HashedCredentialsMatcher這個類

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

四、Shiro中的授權(quán)

4.1 授權(quán)中的關(guān)鍵對象

  • Who

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

  • What

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

  • How

表示權(quán)限/許可,控制主體對資源的訪問

4.2 授權(quán)方式

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

4.3 權(quán)限字符串

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

4.4 校驗角色

  1. 在doGetAuthorizationInfo方法中設(shè)置當(dāng)前主體的角色
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// 獲取主題中的身份信息[用戶名]String principal = (String) principals.getPrimaryPrincipal();// 返回AuthorizationInfo的實現(xiàn)類SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();// 給當(dāng)前主體添加角色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 校驗權(quán)限字符串

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

  1. 模擬前臺測試

五、整合SpringBoot

5.1 整合思路

5.2 環(huán)境搭建

  1. 導(dǎo)入springboot和shiro整合的依賴包
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-starter</artifactId><version>1.4.0</version>
</dependency>
  1. 創(chuàng)建一個類,繼承AuthorizingRealm類,重寫授權(quán)和認(rèn)證方法
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設(shè)置到Filter中shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);return shiroFilterFactoryBean;}@Beanpublic DefaultWebSecurityManager defaultWebSecurityManager(Realm realm){DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();// 給安全管理器設(shè)置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設(shè)置到Filter中shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);//設(shè)置受限資源Map<String,String> map = new HashMap<>();/*** authc:該路徑資源需要認(rèn)證和授權(quán)*/map.put("/**","authc"); // "/**"代表所有的資源路徑都攔截shiroFilterFactoryBean.setFilterChainDefinitionMap(map);return shiroFilterFactoryBean;
}
  1. 訪問資源跳轉(zhuǎn)到login.jsp,修改默認(rèn)跳轉(zhuǎn)路徑
shiroFilterFactoryBean.setLoginUrl("/doLogin");@Controller
public class IndexController {@GetMapping("/doLogin")public String doLogin(){return "login";}
}
  1. 攔截后訪問/doLogin路徑

5.3 ShiroFilter過濾列表

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

配置縮寫

對應(yīng)過濾器

描述

anon

AnonymousFilter

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

authc

FormAuthenticationFilter

指定URL路徑下的資源需要認(rèn)證過后才能訪問

authcBasic

BasicHttpAuthenticationFilter

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

logout

LogoutFilter

注銷過濾器,只需配置對應(yīng)的URL路徑即可實現(xiàn)

noSessionCreation

NoSessionCreationFilter

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

perms

PermissionsAuthorizationFilter

需要有該URL資源對應(yīng)的權(quán)限字符串才能訪問

port

PortFilter

指定某個端口可以訪問

rest

HttpMethodPermissionFilter

將HTTP請求轉(zhuǎn)換成相對應(yīng)的動詞來構(gòu)建權(quán)限字符串

roles

RolesAuthorizationFilter

需要有指定角色才能訪問

ssl

SslFilter

需要https請求才能訪問

user

UserFilter

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

六、連接數(shù)據(jù)庫完成認(rèn)證

6.1 注冊

  1. 表設(shè)計

  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,調(diào)用service處理業(yè)務(wù)邏輯
@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中完成加密和散列鹽,調(diào)用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 認(rèn)證

  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方法中編寫認(rèn)證邏輯
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {@Autowiredprivate UserService userService;// 獲取主體中的身份信息String principal = (String) authenticationToken.getPrincipal();// 調(diào)用service查詢數(shù)據(jù)庫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調(diào)用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中編寫對應(yīng)URL,封裝token,并處理異常結(jié)果
@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"; // 登陸成功跳轉(zhuǎn)到首頁} catch (UnknownAccountException e) {e.printStackTrace();System.out.println("用戶名錯誤");}catch (IncorrectCredentialsException e){e.printStackTrace();System.out.println("密碼錯誤");}return "login"; // 登錄失敗跳轉(zhuǎn)到登錄頁面}
}
  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. 頁面登錄成功后,進(jìn)入到index.html

6.3 注銷

① 配置方式

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

② 代碼方式

調(diào)用subject的logout方法完成注銷,頁面訪問該Controller的URL

七、授權(quán)的基本使用

7.1 校驗角色

在自定義的Realm的doGetAuthorizationInfo方法中給當(dāng)前主體賦予角色

@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")) { // 校驗當(dāng)前角色是否有admin這個角色return "權(quán)限不足";}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 "權(quán)限不足";}}
}

② 注解方式

單個角色:直接在注解參數(shù)中寫入對應(yīng)的角色即可

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

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

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

7.2 校驗權(quán)限字符串

在自定義的Realm的doGetAuthorizationInfo方法中給當(dāng)前主體賦予權(quán)限字符串

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

① 編碼方式

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

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

② 注解方式

單個權(quán)限字符串:直接在注解參數(shù)中寫入需要校驗的權(quán)限字符串即可

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

多個權(quán)限字符串:在注解中以數(shù)組的形式寫入多個權(quán)限字符串【當(dāng)前主體主要擁有這些權(quán)限字符串才能訪問】

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

③ 配置方式

在ShiroFilter過濾器使用perms進(jìn)行權(quán)限的校驗

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

如果權(quán)限不足,頁面拋出401錯誤

在ShiroFilter中定義權(quán)限不足后跳轉(zhuǎn)的URL

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

八、連接數(shù)據(jù)庫完成授權(quán)

8.1 表設(shè)計:

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 '權(quán)限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 '權(quán)限字符串',`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 授權(quán)角色

  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中進(jìn)行授權(quán)
@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 授權(quán)字符串

  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進(jìn)行授權(quán)
@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 導(dǎo)入依賴

<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 常用標(biāo)簽使用

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

http://www.risenshineclean.com/news/34862.html

相關(guān)文章:

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