【shiro从入门到实战教程】第三章 Shiro基础

爱被打了一巴掌 2024-04-28 13:23 194阅读 0赞

三、Shiro基础

3.1 项目搭建

3.1.1 建立Maven项目

建立Java项目即可。

3.1.2 引入依赖

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>com.newcapec</groupId>
  7. <artifactId>shiro01-base</artifactId>
  8. <version>1.0-SNAPSHOT</version>
  9. <properties>
  10. <maven.compiler.source>8</maven.compiler.source>
  11. <maven.compiler.target>8</maven.compiler.target>
  12. </properties>
  13. <dependencies>
  14. <!--shiro-->
  15. <dependency>
  16. <groupId>org.apache.shiro</groupId>
  17. <artifactId>shiro-core</artifactId>
  18. <version>1.4.1</version>
  19. </dependency>
  20. <!-- mysql驱动 -->
  21. <dependency>
  22. <groupId>mysql</groupId>
  23. <artifactId>mysql-connector-java</artifactId>
  24. <version>5.1.49</version>
  25. </dependency>
  26. <!-- 德鲁伊数据源 -->
  27. <dependency>
  28. <groupId>com.alibaba</groupId>
  29. <artifactId>druid</artifactId>
  30. <version>1.1.10</version>
  31. </dependency>
  32. <!-- 日志
  33. slf4j:日志记录系统的简单外观,日志空实现(日志规范、日志接口)
  34. 真正记录日志的框架(日志实现框架):log4j、logback等
  35. slf4j是一个日志标准,同时日志框架都会实现这个标准,因此使用slf4j可以极大的降低维护成本。
  36. -->
  37. <dependency>
  38. <groupId>org.slf4j</groupId>
  39. <artifactId>slf4j-log4j12</artifactId>
  40. <version>1.7.21</version>
  41. </dependency>
  42. <!-- junit -->
  43. <dependency>
  44. <groupId>junit</groupId>
  45. <artifactId>junit</artifactId>
  46. <version>4.12</version>
  47. <scope>test</scope>
  48. </dependency>
  49. </dependencies>
  50. </project>

3.2 身份认证

身份认证:用户身份识别,俗称为“用户登录”。

3.2.1 认证流程

在这里插入图片描述

1、创建SecurityManager。

2、主体提交认证。

3、SecurityManager认证。

4、SecurityManager是用Authenticator来认证。

5、authenticator认证是通过Realm获取认证数据做最终的认证。

3.2.2 测试用例

  1. public class HelloWorldTest {
  2. /**
  3. * 演示Shiro实现用户登录:身份认证
  4. */
  5. @Test
  6. public void run(){
  7. // 1.创建Shiro环境SecurityManager对象
  8. DefaultSecurityManager securityManager = new DefaultSecurityManager();
  9. // 2.创建Realm对象: SimpleAccountRealm管理账户的Realm
  10. SimpleAccountRealm simpleAccountRealm = new SimpleAccountRealm();
  11. // 设置基础用户信息(相当于数据库中存储的用户信息)
  12. simpleAccountRealm.addAccount("admin", "123");
  13. simpleAccountRealm.addAccount("tom", "111");
  14. // 3.设置指定Realm
  15. securityManager.setRealm(simpleAccountRealm);
  16. // 4.构建环境:把创建的SecurityManager和Realm告知给Shiro
  17. SecurityUtils.setSecurityManager(securityManager);
  18. // 5.获取当前操作的主体Subject
  19. Subject subject = SecurityUtils.getSubject();
  20. // 6.创建一个存储用户名与密码的令牌,用户输入用户名和密码
  21. UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("admin", "123");
  22. // 7.登录
  23. subject.login(usernamePasswordToken);
  24. System.out.println("身份认证结果:" + subject.isAuthenticated());
  25. }
  26. }

3.2.3 认证异常

用户名提供错误时抛出的异常:

  1. org.apache.shiro.authc.UnknownAccountException: Realm [org.apache.shiro.realm.SimpleAccountRealm@5594a1b5] was unable to find account data for the submitted AuthenticationToken [org.apache.shiro.authc.UsernamePasswordToken - jerry, rememberMe=false].
  2. at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doSingleRealmAuthentication(ModularRealmAuthenticator.java:184)
  3. at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doAuthenticate(ModularRealmAuthenticator.java:267)
  4. at org.apache.shiro.authc.AbstractAuthenticator.authenticate(AbstractAuthenticator.java:198)
  5. at org.apache.shiro.mgt.AuthenticatingSecurityManager.authenticate(AuthenticatingSecurityManager.java:106)
  6. at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:275)
  7. at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:260)
  8. at com.newcapec.HelloWorldTest.run(HelloWorldTest.java:39)

密码提供错误时抛出的异常:

  1. org.apache.shiro.authc.IncorrectCredentialsException: Submitted credentials for token [org.apache.shiro.authc.UsernamePasswordToken - admin, rememberMe=false] did not match the expected credentials.
  2. at org.apache.shiro.realm.AuthenticatingRealm.assertCredentialsMatch(AuthenticatingRealm.java:603)
  3. at org.apache.shiro.realm.AuthenticatingRealm.getAuthenticationInfo(AuthenticatingRealm.java:581)
  4. at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doSingleRealmAuthentication(ModularRealmAuthenticator.java:180)
  5. at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doAuthenticate(ModularRealmAuthenticator.java:267)
  6. at org.apache.shiro.authc.AbstractAuthenticator.authenticate(AbstractAuthenticator.java:198)
  7. at org.apache.shiro.mgt.AuthenticatingSecurityManager.authenticate(AuthenticatingSecurityManager.java:106)
  8. at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:275)
  9. at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:260)
  10. at com.newcapec.HelloWorldTest.run(HelloWorldTest.java:39)

3.3 权限鉴定

3.3.1 鉴权流程

在这里插入图片描述

1、创建SecurityManager。

2、主体授权。

3、SecurityManager执行授权。

4、Authorizer执行授权。

5、Realm获取角色权限数据。

3.3.2 测试用例

  1. public class RoleTest {
  2. @Test
  3. public void run() {
  4. // 1.创建Shiro环境SecurityManager对象
  5. DefaultSecurityManager securityManager = new DefaultSecurityManager();
  6. // 2.创建Realm对象: SimpleAccountRealm管理账户的Realm
  7. SimpleAccountRealm simpleAccountRealm = new SimpleAccountRealm();
  8. // 设置基础用户信息,以及角色
  9. simpleAccountRealm.addAccount("admin", "123", "root", "user");
  10. simpleAccountRealm.addAccount("tom", "111", "user");
  11. // 3.设置指定Realm
  12. securityManager.setRealm(simpleAccountRealm);
  13. // 4.构建环境
  14. SecurityUtils.setSecurityManager(securityManager);
  15. // 5.获取当前操作的主体Subject
  16. Subject subject = SecurityUtils.getSubject();
  17. // 6.创建一个存储用户名与密码的令牌,用户输入用户名和密码
  18. UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("admin", "123");
  19. // 7.登录
  20. subject.login(usernamePasswordToken);
  21. // 判断当前用户是否身份认证成功
  22. System.out.println("身份认证结果:" + subject.isAuthenticated());
  23. // 判断当前用户是否用拥有指定的角色
  24. // 方式一、subject.hasRole(角色编码); 返回值boolean类型。判断是否拥有角色。
  25. System.out.println("是否拥有root角色:" + subject.hasRole("root"));
  26. System.out.println("是否拥有user角色:" + subject.hasRole("user"));
  27. // 方式二、subject.hasRoles(角色编码集合); 返回值boolean类型数组。判断是否拥有角色。其中返回数据为针对每个角色的鉴定结果。
  28. boolean[] roles = subject.hasRoles(Arrays.asList("root", "user"));
  29. System.out.println("是否拥有root、user角色:" + Arrays.toString(roles));
  30. // 方式三、subject.hasAllRoles(角色编码集合); 返回值boolean类型。判断段是否拥有所有的角色。
  31. System.out.println("是否同时拥有root、user角色:" + subject.hasAllRoles(Arrays.asList("root", "user")));
  32. // 方式四、subject.checkRole(角色编码); 无返回值。如果拥有指定角色程序不抛出异常,否则抛出异常。
  33. // subject.checkRole("root");
  34. // subject.checkRole("user");
  35. // 其他...
  36. // 8.登出
  37. subject.logout();
  38. System.out.println("身份认证结果:" + subject.isAuthenticated());
  39. System.out.println("是否拥有root角色:" + subject.hasRole("root"));
  40. System.out.println("是否拥有user角色:" + subject.hasRole("user"));
  41. }
  42. }

发表评论

表情:
评论列表 (有 0 条评论,194人围观)

还没有评论,来说两句吧...

相关阅读