[Shiro from entry to actual combat tutorial] Chapter 3 Shiro Basics

3. Shiro Basics

3.1 Project Construction

3.1.1 Establish Maven project

Just create a Java project.

3.1.2 Introducing dependencies

<?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 Identity authentication

Identity authentication: user identity recognition, commonly known as "user login".

3.2.1 Certification process

insert image description here

1. Create a Security Manager.

2. The subject submits the certification.

3. Security Manager authentication.

4. SecurityManager uses Authenticator to authenticate.

5. Authenticator authentication is to obtain authentication data through Realm for final authentication.

3.2.2 Test cases

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 Authentication exception

Exception thrown when username is provided incorrectly:

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)

Exception thrown when wrong password is provided:

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 Authorization Identification

3.3.1 Authentication process

insert image description here

1. Create a Security Manager.

2. Subject authorization.

3. SecurityManager performs authorization.

4. Authorizer performs authorization.

5. Realm obtains role permission data.

3.3.2 Test cases

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"));
    }
}

Guess you like

Origin blog.csdn.net/ligonglanyuan/article/details/125677866