Shiro 学习笔记(1)-Helloworld 和 身份认证
2015-12-15 18:27
435 查看
Shiro 入门与身份认证
用户信息存放在内存中
用户信息存放在数据库中
“身份认证”是 Shiro 里很重要的概念。“认证”就是通过输入用户名和密码,到内存中或者到数据库中去查询是否有这个用户名的信息(且密码也匹配)。
项目结构:
创建 maven 项目。
1、引入 gav 依赖:
如果使用 gradle 构建,则坐标为
2、编写 shiro 核心配置文件 shiro.ini
3、编写 HelloWorld 代码
这里要特别注意:
4、引入 slf4j 的 log4j 实现配置文件:log4j.properties
Subject 认证主体包含两个信息:
Principals:身份,可以是用户名,邮件,手机号码等等,用来标识一个登录主体身份;(我们可以理解成用户名)
Credentials:凭证,常见有密码,数字证书等等;(我们可以理解成密码)
Realm 的意思是域,Shiro 从 Realm 中获取验证数据。
只须要对上面的代码稍稍作修改就可以实现将用户信息存放在数据库中,通过数据库中的用户信息进行登录匹配。既然使用的是 JdbcRealm,就须要使用到 jdbc 的相关技术。
首先我们引入依赖:
再向数据库里写入数据:
这里的表名和字段名都是固定的,这一点我们通过看 JdbcRealm 的源代码就可以知道。不过显然这样的方式显然是不灵活的。
配置文件 jdbc_realm.ini:
配置文件解释:
测试代码(和上一节没有什么不同,只是配置文件不一样而已):
补充:在
总结:
使用 Shiro 进行身份认证的流程是:将用户的用户名和密码信息存放在一个
此时 Shiro 框架会去 shiro.ini 文件中找指定的安全数据源
用户名是否存在,用户名存在的前提下密码是否也匹配,这个操作是由 Shiro 帮助我们完成的。
用户信息存放在内存中
用户信息存放在数据库中
Shiro 入门与身份认证
本节介绍了 Shiro 的入门示例程序。“身份认证”是 Shiro 里很重要的概念。“认证”就是通过输入用户名和密码,到内存中或者到数据库中去查询是否有这个用户名的信息(且密码也匹配)。
用户信息存放在“内存”中
用户信息存放在“内存”中,意即将用户的用户名和密码信息存放在一个名为 shiro.ini 的文件中。更多的情况是,我们把用户的用户名和密码信息存放在数据库中,这也是我们以前做的项目的绝大多数情况下的做法。项目结构:
创建 maven 项目。
1、引入 gav 依赖:
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.4</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.13</version> </dependency>
如果使用 gradle 构建,则坐标为
dependencies { testCompile group: 'junit', name: 'junit', version: '4.11' compile 'org.apache.shiro:shiro-core:1.2.4' compile 'org.slf4j:slf4j-log4j12:1.7.13' }
2、编写 shiro 核心配置文件 shiro.ini
[users] liwei=123456 wudi=wudi huzhenyu=huzhenyu
3、编写 HelloWorld 代码
这里要特别注意:
SecurityManager所在的包名应该是
org.apache.shiro.mgt。
package com.liwei.shiro; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; import sun.org.mozilla.javascript.internal.SecurityUtilities; /** * Created by Liwei on 2015/12/15. */ public class HelloWorld { public static void main(String[] args) { // 读取配置文件,初始化 SecurityManager 工厂 // 注意:这里 SecurityManager 所在的包名 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); // 获取 SecurityManager 的实例 SecurityManager securityManager = factory.getInstance(); // 把 securityManager 的实例绑定到 SecurityUtils 上 SecurityUtils.setSecurityManager(securityManager); // 得到当前执行的用户 Subject currentUser = SecurityUtils.getSubject(); // 自己创建一个令牌,输入用户名和密码 // UsernamePasswordToken token = new UsernamePasswordToken("liwei","123456"); UsernamePasswordToken token = new UsernamePasswordToken("huzhenyu","huzhenyu"); try { // 身份认证(该方法会抛出异常) currentUser.login(token); System.out.println("身份认证成功!"); } catch (AuthenticationException e) { e.printStackTrace(); System.out.println("身份认证失败!"); } // 退出 currentUser.logout(); } }
4、引入 slf4j 的 log4j 实现配置文件:log4j.properties
# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # log4j.rootLogger=INFO, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n # General Apache libraries log4j.logger.org.apache=WARN # Spring log4j.logger.org.springframework=WARN # Default Shiro logging log4j.logger.org.apache.shiro=TRACE # Disable verbose logging log4j.logger.org.apache.shiro.util.ThreadContext=WARN log4j.logger.org.apache.shiro.cache.ehcache.EhCache=WARN
Subject 认证主体包含两个信息:
Principals:身份,可以是用户名,邮件,手机号码等等,用来标识一个登录主体身份;(我们可以理解成用户名)
Credentials:凭证,常见有密码,数字证书等等;(我们可以理解成密码)
用户信息存放在数据库中
下面我们介绍使用 JdbcRealm。那么什么是 Realm 呢?Realm 可以理解为主体的数据源(数据来源,里面存放的都是正确的用户名和密码)。Realm 的意思是域,Shiro 从 Realm 中获取验证数据。
只须要对上面的代码稍稍作修改就可以实现将用户信息存放在数据库中,通过数据库中的用户信息进行登录匹配。既然使用的是 JdbcRealm,就须要使用到 jdbc 的相关技术。
首先我们引入依赖:
compile 'mysql:mysql-connector-java:5.1.38' compile 'c3p0:c3p0:0.9.1.2' compile 'commons-logging:commons-logging:1.2'
再向数据库里写入数据:
这里的表名和字段名都是固定的,这一点我们通过看 JdbcRealm 的源代码就可以知道。不过显然这样的方式显然是不灵活的。
DROP TABLE IF EXISTS users; CREATE TABLE users ( id int(11) NOT NULL AUTO_INCREMENT, userName varchar(20) DEFAULT NULL, password varchar(20) DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; insert into users(userName,password) values ('liwei','123456'); insert into users(userName,password) values ('zhouguang','123456');
配置文件 jdbc_realm.ini:
[main] jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm dataSource=com.mchange.v2.c3p0.ComboPooledDataSource dataSource.jdbcUrl=jdbc:mysql://localhost:3306/db_shiro dataSource.password=123456 dataSource.user=root dataSource.driverClass=com.mysql.jdbc.Driver jdbcRealm.dataSource=$dataSource securityManager.realm=$jdbcRealm
配置文件解释:
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm表示实例化右边字符串表示的类,赋给左边字符串表示的变量。
dataSource.jdbcUrl=jdbc:mysql://localhost:3306/db_shiro表示对 dataSource 这个变量设置属性值 jdbcUrl ,这个属性值是一个字符串。
jdbcRealm.dataSource=$dataSource表示对 jdbcRealm 这个变量设置属性值 dataSource , 这个 dataSource 属性是上面实例化的一个对象,所以表示这个对象要使用前缀
$。
测试代码(和上一节没有什么不同,只是配置文件不一样而已):
public class JdbeReamlTest { /** * 这一节的内容是 身份认证 * @param args */ public static void main(String[] args) { // 注意:这里 SecurityManager 所在的包名 // 读取配置文件,初始化SecurityManager工厂 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:jdbc_realm.ini"); SecurityManager securityManager = factory.getInstance(); // 把 securityManager 的实例绑定到 SecurityUtils 上 SecurityUtils.setSecurityManager(securityManager); // 得到当前执行的用户 Subject currentUser = SecurityUtils.getSubject(); // 自己创建一个令牌 UsernamePasswordToken token = new UsernamePasswordToken("zhouguang","123456"); try { // 身份认证 currentUser.login(token); System.out.println("身份认证成功"); } catch (AuthenticationException e) { e.printStackTrace(); } System.out.println("退出登录"); // 最后别忘了退出登录(shiro还会做很多操作,从控制台就可以看出) currentUser.logout(); System.out.println("退出登录成功"); } }
补充:在
currentUser.login(token);这一行捕获的异常,这里只是简单地捕获了
AuthenticationException这个异常,我们还可以具体地捕获用户名不存在异常和密码不存在异常。
总结:
使用 Shiro 进行身份认证的流程是:将用户的用户名和密码信息存放在一个
UsernamePasswordToken对象中,通过
Subject的
login()方法把
UsernamePasswordToken对象传进去。
此时 Shiro 框架会去 shiro.ini 文件中找指定的安全数据源
Realm。默认是 IniRealm ,如果我们配置了 JdbcRealm ,就使用 JdbcRealm。
用户名是否存在,用户名存在的前提下密码是否也匹配,这个操作是由 Shiro 帮助我们完成的。
相关文章推荐
- Apache Shiro 使用手册(一) Shiro架构介绍
- Apache Shiro 使用手册(二) Shiro 认证
- Apache Shiro 使用手册(五) Shiro 配置说明
- Apache Shiro 使用手册(四) Realm 实现
- 让Apache Shiro保护你的应用
- 基于Spring框架的Shiro配置方法
- 使用Shiro实现登录成功后跳转到之前的页面
- Spring+mybatis+shiro+freemarker+ehcache+ldap+mongo
- 第四章 INI配置
- 第五章 编码/加密
- 第六章 Realm及相关对象
- Shiro预览
- JFinal-Beetl-Shiro(JdbcRealm)-例子
- springrain技术详解
- S2SH整合Shiro之:SessionContext must be an HTTP compatible implementation
- S2SH整合Shiro之:java.lang.NoSuchMethodException: com.sun.proxy.$Proxy25
- 让Apache Shiro保护你的应用
- 第二章 身份验证——《跟我学Shiro》
- 第三章 授权——《跟我学Shiro》
- 第四章 INI配置——《跟我学Shiro》