介绍
Apache Shiro 是一个强大易用的 Java 安全框架,提供了认证、授权、加密和会话管理等功能,对于任何一个应用程序,Shiro 都可以提供全面的安全管理服务。并且相对于其他安全框架,Shiro 要简单的多。
入门示例代码
引入pom文件的依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.3.2</version> </dependency> </dependencies>
|
单元测试代码
1 2 3 4 5 6 7 8 9 10 11
| @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
理解
由配置文件,生成密码默认的密码验证器。
通过subject来验证密码是否正确
自定义Realm(域)示例
自己定义Realm
写明如何去验证,及支持的方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 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中对验证对象
1 2 3
| [main] myrealm=com.example.testshiro.MyRealm securityManager.realms=$myrealm
|
测试用例
1 2 3 4 5 6 7 8 9 10 11
| @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文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.6</version> </dependency>
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.3</version> </dependency>
|
配置文件
shiro-jdbc-realm.ini
用于jdbcRealm的初始化
1 2 3 4 5 6 7 8 9
| [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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| 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');
|
单元测试代码
1 2 3 4 5 6 7 8 9 10 11
| @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,这些框架看看代码,了解下结构,还是比较好掌握的。
参考