一.简介
Apache Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和 会话管理等功能。
对于任何一个应用程序,Shiro都可以提供全面的安全管理服务。其不仅可 以用在JavaSE环境,也可以用在JavaEE环境。
二.架构图
1.从外部来看Shiro,即从应用程序角度来观察如何使用Shiro完成工作。如 下图:
2.2.从Shiro内部看Shiro的架构,如下图所示:
三、Shiro配置文件详解
shiro.ini文件放在classpath下,shiro会自动查找。其中格式是key/value 键值对配置。INI配置文件一般适用于用户少且不需要在运行时动态创建的 情景下使用。 ini文件中主要配置有四大类:main,users,roles,urls
main主要配置shiro的一些对象,例如securityManager ,Realm, authenticator,authcStrategy
[users]允许你配置一组静态的用户,包含用户名,密码,角色,一个用户 可以有多个角色,可以配置多个角色
[roles]将角色和权限关联起来,格式为:角色名=权限字符串1,权限字符 串2…..
[urls] 这部分配置主要在web应用中,格式为:url=拦截器[参数],拦截器[参 数]
四、Shiro环境搭建实现简单认证
1.实现步骤
导入jar包
新建文件shiro.ini放到src下,进行配置
[users]
victor=123456
编写测试代码
//实现简单验证
public class AuthenticationTest {
@Test
public void testauthentication() {
//1.构建securityManager工厂
IniSecurityManagerFactory securityManagerFactory = new IniSecurityManagerFactory("classpath:shiro.ini");
//2.通过securityManagerFactory工厂获取SecurityManager实例
SecurityManager securityManager = securityManagerFactory.getInstance();
//3.将securityManager设置到运行环境当中
SecurityUtils.setSecurityManager(securityManager);
//4.获取subject实例
Subject subject = SecurityUtils.getSubject();
//5.创建用户名密码验证令牌Token
UsernamePasswordToken token = new UsernamePasswordToken("victor","123456");
//6.进行身份验证
subject.login(token);
//7.判断是否认证通过
System.out.println(subject.isAuthenticated());
}
}
五、JDBCRealm
Shiro默认使用自带的IniRealm,IniRealm从ini配置文件中读取用户的信息。 大部分情况下需要从系统的数据库中读取用户信息,所以需要使用 JDBCRealm或自定义Realm。
需求:使用JDBCRealm提供数据源,从而实现认证 。
实现步骤:
1建users表(表名、字段对应上)
在数据库中新建users表,添加id、username、password。
2添加jar包(数据库驱动、数据库连接池、beanutils等)
3编写shiro.ini
[main]
#配置realm
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
#配置数据源
dataSource=com.mchange.v2.c3p0.ComboPooledDataSource
dataSource.driverClass=com.mysql.jdbc.Driver(连接数据库)
dataSource.jdbcUrl=jdbc:mysql:///test(数据库名)
dataSource.user=root(账户)
dataSource.password=数据库密码
jdbcRealm.dataSource=$dataSource
#将Realm注入给SecurityManager
securityManager.realm = $jdbcRealm
4编写测试代码
同上(简单验证测试代码);区别:数据库获取信息。
六、如何自定义Realm
自定义Realm,可以注入给securityManager更加灵活的安全数据源(例如, JDBCRealm中表和字段都限定了) 通过实现Realm接口,或根据需求继承他的相应子类即可。
实现步骤:
1添加jar包
2编写自定义Realm
public class CustomRealm extends AuthenticatingRealm {
private String principal;
private String credentials;
private ResultSet rs;
private Statement state;
private Connection conn;
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//使用JDBC,从数据库获取数据
try {
//1.注册驱动
Driver driver = new Driver();
DriverManager.registerDriver(driver);
//2.获取连接对象
String url ="jdbc:mysql:///test";
String user = "root";
String password = "123456";
conn = DriverManager.getConnection(url , user , password );
state = conn.createStatement();
//4.执行sql语句
String sql = "select userName,passwd from starLogin";
rs = state.executeQuery(sql );
//5.处理结果集
while (rs.next()) {
principal = rs.getString("userName");
credentials = rs.getString("passwd");
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(state != null){
try {
state.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(principal, credentials, "customRealm");
return simpleAuthenticationInfo;
}
}
3编写shiro.ini
[main]
#配置Realm
customRealm = 全限定列名
#将Realm注入给SecurityManager
securityManager.realm = $customRealm
4编写测试类
七、Shiro之加密
1.几种常见加密算法比较
对称加密算法(加密与解密密钥相同)
非对称算法(加密密钥和解密密钥不同)
对称与非对称算法比较
散列算法比较
2.MD5加密、加盐与迭代
加盐: 使用MD5存在一个问题,相同的password生产的Hash值是相同的,如 果两个用户设置了相同的密码,那么数据库当就会存储相同的值,这样是极 不安全的。 加Salt可以一定程度上解决这一问题。所谓加Salt方法,就是加点 “佐料”。其基本想法是这样的:当用户首次提供密码时(通常是注册时), 由系统自动往这个密码里撒一些“佐料”,然后再散列。而当用户登录时, 系统为用户提供的代码撒上同样的“佐料”,然后散列,再比较散列值,来 确定密码是否正确。
加盐原理: 给原文加入随机数生成新的MD5值。
迭代:加密的次数
//MD5加密,加盐以及迭代
public class MD5Test {
@Test
public void testMD5() {
//MD5加密
Md5Hash md5 = new Md5Hash("123456");
System.out.println(md5);
//加盐
md5 = new Md5Hash("123456","dd");
System.out.println(md5);
//迭代
md5=new Md5Hash("123456","dd",3);
System.out.println(md5);
}
}
3.凭证匹配器
在Realm接口的实现类AuthenticatingRealm中有credentialsMatcher属性。 意为凭证匹配器。常用来设置加密算法及迭代次数等。
八、Shiro之授权
1.授权,又称作为访问控制,是对资源的访问管理的过程。即对于 认证通过的用户,授予他可以访问某些资源的权限。
2.Shiro 支持三种方式的授权:代码触发、注解触发、标签触发 。