转载

shiro学习笔记

Apache Shiro 是一个强大易用的 Java 安全框架,提供了认证、授权、加密和会话管理等功能,对于任何一个应用程序,Shiro 都可以提供全面的安全管理服务。并且相对于其他安全框架,Shiro 要简单的多。

入门示例代码

引入pom文件的依赖

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-core -->
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>1.3.2</version>
    </dependency>
</dependencies>

单元测试代码

@Test
public void demoIni(){
	IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
	SecurityManager securityManager = factory.createInstance();
	SecurityUtils.setSecurityManager(securityManager);
	Subject subject = SecurityUtils.getSubject();
	UsernamePasswordToken token = new UsernamePasswordToken("admin","123456");
	subject.login(token);
    org.junit.Assert.assertEquals(true,subject.isAuthenticated());
    subject.logout();
}

配置文件shiro.ini

[users]
admin=123456

理解

由配置文件,生成密码默认的密码验证器。

通过subject来验证密码是否正确

自定义Realm(域)示例

自己定义Realm

写明如何去验证,及支持的方式

public class MyRealm implements Realm {
	@Override
	public String getName() {
		return "MyRealm";
	}
	@Override
	public boolean supports(AuthenticationToken token) {
		return token instanceof UsernamePasswordToken;
	}
	@Override
	public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String username = (String) token.getPrincipal();
		String password = new String((char[]) token.getCredentials());
		if (!username.equals("admin")) {
			throw new UnknownAccountException();
		}
		if (!password.equals("321321")) {
			throw new IncorrectCredentialsException();
		}
		return new SimpleAuthenticationInfo(username, password, getName());
	}
}

配置文件

shiro-realm.ini 用来指明securityManager中对验证对象

[main]
myrealm=com.example.testshiro.MyRealm
securityManager.realms=$myrealm

测试用例

@Test
public void demoCustomRealm(){
	IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro-realm.ini");
    SecurityManager securityManager=factory.getInstance();
    SecurityUtils.setSecurityManager(securityManager);
    Subject subject=SecurityUtils.getSubject();
    UsernamePasswordToken token=new UsernamePasswordToken("admin","321321");
    subject.login(token);
    org.junit.Assert.assertEquals(true,subject.isAuthenticated());
    subject.logout();
}

jdbc realm

依赖的pom文件

<!--jdbcrealm依赖 start-->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>6.0.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.3</version>
</dependency>
<!--jdbcrealm依赖 end-->

配置文件

shiro-jdbc-realm.ini 用于jdbcRealm的初始化

[main]
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
dataSource=com.alibaba.druid.pool.DruidDataSource
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql://localhost:3306/shirotest
dataSource.username=root
dataSource.password=root
jdbcRealm.dataSource=$dataSource
securityManager.realms=$jdbcRealm

数据库表文件

shirotest.sql

create table users (
  id bigint auto_increment,
  username varchar(100),
  password varchar(100),
  password_salt varchar(100),
  constraint pk_users primary key(id)
) charset=utf8 ENGINE=InnoDB;
create unique index idx_users_username on users(username);
  
create table user_roles(
  id bigint auto_increment,
  username varchar(100),
  role_name varchar(100),
  constraint pk_user_roles primary key(id)
) charset=utf8 ENGINE=InnoDB;
create unique index idx_user_roles on user_roles(username, role_name);
  
create table roles_permissions(
  id bigint auto_increment,
  role_name varchar(100),
  permission varchar(100),
  constraint pk_roles_permissions primary key(id)
) charset=utf8 ENGINE=InnoDB;
create unique index idx_roles_permissions on roles_permissions(role_name, permission);
  
insert into users(username,password)values('admin','123');

单元测试代码

@Test
public void demoJdbcRealm(){
	IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro-jdbc-realm.ini");
    SecurityManager securityManager=factory.getInstance();
    SecurityUtils.setSecurityManager(securityManager);
    Subject subject=SecurityUtils.getSubject();
    UsernamePasswordToken token=new UsernamePasswordToken("admin","123");
       subject.login(token);
    org.junit.Assert.assertEquals(true,subject.isAuthenticated());
    subject.logout();
}

一点心得

  • IniSecurityManagerFactory是用org.apache.shiro.config.ReflectionBuilder这个工具把配置文件中的配置实例化的
  • 默认的Realm、自己定义的Realm、jdbc的Realm,使用工厂方式,把实际需要的Realm构造出来。
  • 验证主体是subject,这些框架看看代码,了解下结构,还是比较好掌握的。

参考

  • 极客学院教程
  • 入门示例
  • 教程目录
原文  https://blog.fengcl.com/2018/04/21/shiro/
正文到此结束
Loading...