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

三、Shiro基础

3.1 项目搭建

3.1.1 建立Maven项目

建立Java项目即可。

3.1.2 引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.newcapec</groupId>
    <artifactId>shiro01-base</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!--shiro-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.4.1</version>
        </dependency>
        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>
        <!-- 德鲁伊数据源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!-- 日志
 			slf4j:日志记录系统的简单外观,日志空实现(日志规范、日志接口)
			真正记录日志的框架(日志实现框架):log4j、logback等
			slf4j是一个日志标准,同时日志框架都会实现这个标准,因此使用slf4j可以极大的降低维护成本。
		-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.21</version>
        </dependency>
        <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

3.2 身份认证

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

3.2.1 认证流程

在这里插入图片描述

1、创建SecurityManager。

2、主体提交认证。

3、SecurityManager认证。

4、SecurityManager是用Authenticator来认证。

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

3.2.2 测试用例

public class HelloWorldTest {
    
    

    /**
     * 演示Shiro实现用户登录:身份认证
     */
    @Test
    public void run(){
    
    
        // 1.创建Shiro环境SecurityManager对象
        DefaultSecurityManager securityManager = new DefaultSecurityManager();

        // 2.创建Realm对象: SimpleAccountRealm管理账户的Realm
        SimpleAccountRealm simpleAccountRealm = new SimpleAccountRealm();
        // 设置基础用户信息(相当于数据库中存储的用户信息)
        simpleAccountRealm.addAccount("admin", "123");
        simpleAccountRealm.addAccount("tom", "111");

        // 3.设置指定Realm
        securityManager.setRealm(simpleAccountRealm);

        // 4.构建环境:把创建的SecurityManager和Realm告知给Shiro
        SecurityUtils.setSecurityManager(securityManager);

        // 5.获取当前操作的主体Subject
        Subject subject = SecurityUtils.getSubject();

        // 6.创建一个存储用户名与密码的令牌,用户输入用户名和密码
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("admin", "123");

        // 7.登录
        subject.login(usernamePasswordToken);

        System.out.println("身份认证结果:" + subject.isAuthenticated());
    }
}

3.2.3 认证异常

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

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].

	at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doSingleRealmAuthentication(ModularRealmAuthenticator.java:184)
	at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doAuthenticate(ModularRealmAuthenticator.java:267)
	at org.apache.shiro.authc.AbstractAuthenticator.authenticate(AbstractAuthenticator.java:198)
	at org.apache.shiro.mgt.AuthenticatingSecurityManager.authenticate(AuthenticatingSecurityManager.java:106)
	at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:275)
	at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:260)
	at com.newcapec.HelloWorldTest.run(HelloWorldTest.java:39)

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

org.apache.shiro.authc.IncorrectCredentialsException: Submitted credentials for token [org.apache.shiro.authc.UsernamePasswordToken - admin, rememberMe=false] did not match the expected credentials.

	at org.apache.shiro.realm.AuthenticatingRealm.assertCredentialsMatch(AuthenticatingRealm.java:603)
	at org.apache.shiro.realm.AuthenticatingRealm.getAuthenticationInfo(AuthenticatingRealm.java:581)
	at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doSingleRealmAuthentication(ModularRealmAuthenticator.java:180)
	at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doAuthenticate(ModularRealmAuthenticator.java:267)
	at org.apache.shiro.authc.AbstractAuthenticator.authenticate(AbstractAuthenticator.java:198)
	at org.apache.shiro.mgt.AuthenticatingSecurityManager.authenticate(AuthenticatingSecurityManager.java:106)
	at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:275)
	at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:260)
	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 测试用例

public class RoleTest {
    
    

    @Test
    public void run() {
    
    
        // 1.创建Shiro环境SecurityManager对象
        DefaultSecurityManager securityManager = new DefaultSecurityManager();

        // 2.创建Realm对象: SimpleAccountRealm管理账户的Realm
        SimpleAccountRealm simpleAccountRealm = new SimpleAccountRealm();
        // 设置基础用户信息,以及角色
        simpleAccountRealm.addAccount("admin", "123", "root", "user");
        simpleAccountRealm.addAccount("tom", "111", "user");

        // 3.设置指定Realm
        securityManager.setRealm(simpleAccountRealm);

        // 4.构建环境
        SecurityUtils.setSecurityManager(securityManager);

        // 5.获取当前操作的主体Subject
        Subject subject = SecurityUtils.getSubject();

        // 6.创建一个存储用户名与密码的令牌,用户输入用户名和密码
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("admin", "123");

        // 7.登录
        subject.login(usernamePasswordToken);

        // 判断当前用户是否身份认证成功
        System.out.println("身份认证结果:" + subject.isAuthenticated());
        // 判断当前用户是否用拥有指定的角色
        // 方式一、subject.hasRole(角色编码); 返回值boolean类型。判断是否拥有角色。
        System.out.println("是否拥有root角色:" + subject.hasRole("root"));
        System.out.println("是否拥有user角色:" + subject.hasRole("user"));

        // 方式二、subject.hasRoles(角色编码集合); 返回值boolean类型数组。判断是否拥有角色。其中返回数据为针对每个角色的鉴定结果。
        boolean[] roles = subject.hasRoles(Arrays.asList("root", "user"));
        System.out.println("是否拥有root、user角色:" + Arrays.toString(roles));

        // 方式三、subject.hasAllRoles(角色编码集合); 返回值boolean类型。判断段是否拥有所有的角色。
        System.out.println("是否同时拥有root、user角色:" + subject.hasAllRoles(Arrays.asList("root", "user")));

        // 方式四、subject.checkRole(角色编码); 无返回值。如果拥有指定角色程序不抛出异常,否则抛出异常。
        // subject.checkRole("root");
        // subject.checkRole("user");

        // 其他...

        // 8.登出
        subject.logout();
        System.out.println("身份认证结果:" + subject.isAuthenticated());
        System.out.println("是否拥有root角色:" + subject.hasRole("root"));
        System.out.println("是否拥有user角色:" + subject.hasRole("user"));
    }
}

猜你喜欢

转载自blog.csdn.net/ligonglanyuan/article/details/125677866