本案例测试使用的是shiro1.13.0最新版本测试

1、shiro概述?

Apache Shiro是java的一个安全框架,能够实现:认证、授权、加密、会话管理、与Web集成、缓存等。

认证:本质就是判断你输入的用户名和密码跟数据库的是否相同。

授权:即访问控制,判断和控制谁对指定资源是否有访问权限。

2、shiro认证流程概述

1、当前端用户通过输入框输入用户名和密码的时候,后端获取数据后,会将用户名和密码封装成UsernamepasswordToken对象,并通过Subject.login(token);访问SecurityManager安全管理器。

2、SecurityManager安全管理器会将认证操作交给Authenticator(认证管理器),认证管理器会获取认证策略,如用户名和密码认证或者指纹认证登。

3、Authenticator将身份信息传递给Realm(这个Realm可以是系统自带的,也可以是用户自定义的,但是在实际的项目中肯定都是自定义的Realm)。这个Realm就是用来连接数据库验证数据是否正确的地方。

4、Realm认证后会将认证的结果返回给SecurityManager安全管理器,安全管理器会拿着这份数据与Subject中用户输入的数据比对,相同就验证成功,不同就验证失败。

shiro1.13认证流程核心-非框架整合版本-LMLPHP

3、shiro使用快速案例-非数据库版本

3.1、创建Maven工程导入shiro包信息

<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>org.example</groupId>
  <artifactId>shirobasedemo1</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>shirobasedemo1</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-all -->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-all</artifactId>
      <version>1.13.0</version>
      <type>pom</type>
    </dependency>


  </dependencies>
</project>

3.2、在resources目录中创建shiro.ini配置文件

这个使用使用的是默认的realm,直接从配置文件获取用户名和密码

shiro1.13认证流程核心-非框架整合版本-LMLPHP

[users]
shiyilang=123456
shierlang=456789

3.3、创建测试类,测试验证结果

此处使用新版本的测试方式

新版本中直接通过IniRealm去访问和解析ini配置文件

public class Test {
    public static void main(String[] args) {
        //创建securityManager安全管理器
        DefaultSecurityManager securityManager= new DefaultSecurityManager();
        //创建IniRealm
        IniRealm iniRealm=new IniRealm("classpath:shiro.ini");
        //解析shiro.ini文件
        securityManager.setRealm(iniRealm);
        //将SecurityManager绑定到当前运行环境中,让系统随时随地可以访问securityManager对象
        SecurityUtils.setSecurityManager(securityManager);
        //创建当前的登录主体,此时主体没有经过认证(Subject会给SecurityManager委托各种功能)
        Subject subject= SecurityUtils.getSubject();
        //绑定主体登录的身份凭证,即账号和密码
        UsernamePasswordToken token=new UsernamePasswordToken("shiyilang","123456");
        //主体登录
        subject.login(token);//login方法的内部,就回去安全管理器
        //判断登录是否成功
        System.out.println("验证是否成功:"+subject.isAuthenticated());
        //注销操作
        subject.logout();
        System.out.println("验证是否成功:"+subject.isAuthenticated());

    }
}

3.4、测试结果

shiro1.13认证流程核心-非框架整合版本-LMLPHP

3.5、上述程序源码下载

https://download.csdn.net/download/tangshiyilang/88677731

4、shiro快速使用案例—创建JdbcRealm

当我们的验证不需要很复杂的时候,系统为了方便用户的使用,直接提供了一个封装好的Realm,我们可以快速的使用数据库的方式验证用户名和密码是否正确。

4.1、JdbcRealm功能概述

JdbcRealm会使用内置的SQL语句,所有必须保证用户表的表名必须为 users, 用户名必须为 username, 密码必须为 password 字段。 users 表不一定只有这两个字段,但必须要保证有这两个字段,如果想加盐加密,还需要有password_salt 字段。

shiro1.13认证流程核心-非框架整合版本-LMLPHP

JdbcRealm部分源代码分析

从下面的源代码可以看出,我们创建的表名必须叫users,表字段中必须使用username,password等。需要与源码中的内容相合。

public class JdbcRealm extends AuthorizingRealm {
    protected static final String DEFAULT_AUTHENTICATION_QUERY = "select password from users where username = ?";
    protected static final String DEFAULT_SALTED_AUTHENTICATION_QUERY = "select password, password_salt from users where username = ?";
    protected static final String DEFAULT_USER_ROLES_QUERY = "select role_name from user_roles where username = ?";
    protected static final String DEFAULT_PERMISSIONS_QUERY = "select permission from roles_permissions where role_name = ?";
    private static final Logger log = LoggerFactory.getLogger(JdbcRealm.class);
    protected DataSource dataSource;
    protected String authenticationQuery = "select password from users where username = ?";
    protected String userRolesQuery = "select role_name from user_roles where username = ?";
    protected String permissionsQuery = "select permission from roles_permissions where role_name = ?";
    protected boolean permissionsLookupEnabled = false;
    protected SaltStyle saltStyle;
    protected boolean saltIsBase64Encoded;
}

4.2、在MySQL中创建user表

CREATE TABLE `users` (
  `userid` varchar(30) DEFAULT NULL,
  `username` varchar(30) DEFAULT NULL,
  `useraddr` varchar(60) DEFAULT NULL,
  `userage` varchar(20) DEFAULT NULL,
  `PASSWORD` varchar(50) DEFAULT NULL,
  `password_salt` varchar(50) DEFAULT NULL,
  `STATUS` varchar(5) DEFAULT NULL,
  `remark` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `users` */

insert  into `users`(`userid`,`username`,`useraddr`,`userage`,`PASSWORD`,`password_salt`,`STATUS`,`remark`) values 
('1001','雾林小妖','安徽合肥','30','123456',NULL,'1','有点小帅');

4.3、创建maven工程引入配置信息

核心是

shiro-all:我这里使用的是shiro1.13.0版本

mysql驱动包:我的数据库是mysql5.7版本,你可以使用自己版本对应的包版本。

<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>org.example</groupId>
  <artifactId>shirojdbcrealmdemo1</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>shirojdbcrealmdemo1</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-all</artifactId>
      <version>1.13.0</version>
      <type>pom</type>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.49</version>
    </dependency>

    <dependency>
      <groupId>com.mchange</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.5.4</version>
    </dependency>


  </dependencies>
</project>

4.4、创建JdbcRealm中数据源配置类

public class DataSourceUtil {
    public static DataSource getDataSource() throws SQLException {
        //创建连接池核心工具类
        ComboPooledDataSource dataSource=new ComboPooledDataSource();
        //设置连接参数:url,驱动,用户密码,初始连接数,最大连接数
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/shiro?useSSL=false&serverTimezone=UTC");
        dataSource.setDataSourceName("com.mysql.jdbc.Driver");
        dataSource.setUser("root");
        dataSource.setPassword("123456");
        dataSource.setInitialPoolSize(3);
        dataSource.setMaxPoolSize(6);
        dataSource.setMaxIdleTime(1000);

        return dataSource;
    }
}

4.5、创建测试类测试JdbcRealm

public class Test {
    public static void main(String[] args) throws SQLException {
        //创建securityManager安全管理器
        DefaultSecurityManager securityManager= new DefaultSecurityManager();
        //创建JdbcRealm
        JdbcRealm jdbcRealm=new JdbcRealm();
        //配置JdbcRealm连接数据库参数
        jdbcRealm.setDataSource(DataSourceUtil.getDataSource());
        //将Realm绑定到securityManager
        securityManager.setRealm(jdbcRealm);
        //将SecurityManager绑定到当前运行环境中
        SecurityUtils.setSecurityManager(securityManager);
        //创建当前的登录主体,此时主体没有经过认证(Subject会给SecurityManager委托各种功能)
        Subject subject= SecurityUtils.getSubject();
        //绑定主体登录的身份凭证,即账号和密码
        UsernamePasswordToken token=new UsernamePasswordToken("1001","1001");
        try{
            subject.login(token);
            //判断用户是否登录成功
            if(subject.isAuthenticated()){
                System.out.println("用户:"+token.getUsername()+", 登录成功");
            }
        }catch (Exception e) {
            e.printStackTrace();
            System.out.println("没有此账号");
        }
        //退出程序
        subject.logout();
        System.out.println("用户是否登录成功:"+subject.isAuthenticated());


    }
}

4.6、测试结果

shiro1.13认证流程核心-非框架整合版本-LMLPHP

12-29 19:21