【单Realm】
1) jar包
2) 实现自定义Realm
1 public class RealmOne implements Realm{ 2 /** 3 * 获取基本类名 4 */ 5 @Override 6 public String getName() { 7 // TODO Auto-generated method stub 8 System.out.println("className:" + this.getClass().getName()); 9 return this.getClass().getName(); 10 } 11 12 /** 13 * 判断token是否被支持 14 */ 15 @Override 16 public boolean supports(AuthenticationToken token) { 17 return token instanceof UsernamePasswordToken; 18 } 19 20 /** 21 * 执行登录验证 22 */ 23 @Override 24 public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) 25 throws AuthenticationException { 26 //获取用户名 27 String principal = String.valueOf(token.getPrincipal()); 28 System.out.println("principal = " + principal); 29 //获取密码 30 31 String credentials =String.valueOf((char[])token.getCredentials()); 32 System.out.println("credentials=" + credentials); 33 34 //验证用户名 35 if(!"admin".equals(principal)) 36 throw new UnknownAccountException("用户名不存在"); 37 38 //验证密码 39 if(!"123".equals(credentials)) 40 throw new IncorrectCredentialsException("密码错误!"); 41 42 return new SimpleAuthenticationInfo(principal, credentials, this.getName()); 43 } 44 }
3) 配置shiro
1 #声明realm 2 #变量名 = 类全名 3 realmOne =cn.hl.realm.RealmOne 4 5 #将realm分配给securityManager的realms属性 6 #securityManager = SecurityUtils.securityManager 7 #realms =RealmSecurityManager.realms 8 #securityManager.realms =$变量名1,$变量名2,...... 9 securityManager.realms=$realmOne
4) 测试
1 //定义日志对象 2 private static final transient Logger logger = LoggerFactory.getLogger(TestSingleRealm.class); 3 4 public static void main(String[] args) { 5 //1、获取Factory工厂类对象 6 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:single-shiro.ini"); 7 8 //2、通过工厂类获取SecurityManager对象 9 SecurityManager securityManager = factory.getInstance(); 10 11 //3、将SecurityManager托管到SecurityUtils进行管理 12 SecurityUtils.setSecurityManager(securityManager); 13 14 //4、获取Subject对象 15 Subject subject = SecurityUtils.getSubject(); 16 17 //5、通过Subject执行验证 18 UsernamePasswordToken token = new UsernamePasswordToken("admin", "1234"); 19 try{ 20 subject.login(token); 21 } 22 catch(UnknownAccountException ex){ 23 System.out.println("账号不存在"); 24 } 25 catch(IncorrectCredentialsException ex){ 26 System.out.println("密码错误"); 27 } 28 29 if(subject.isAuthenticated()) 30 System.out.println("用户登录成功"); 31 32 //注销用户 33 subject.logout(); 34 }
【多Realm】
1) 概述
多realm是为了满足不同登录验证方式而提供的,如:帐号、手机、邮箱等。
2) 自定义Realm
1 /** 2 * 通过邮件地址和密码进行验证 3 * @author Terry 4 * 5 */ 6 public class RealmTwo implements Realm{ 7 8 @Override 9 public String getName() { 10 return this.getClass().getName(); 11 } 12 13 @Override 14 public boolean supports(AuthenticationToken token) { 15 return token instanceof UsernamePasswordToken; 16 } 17 18 @Override 19 public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) 20 throws AuthenticationException { 21 //获取帐号信息 22 String principal = String.valueOf(token.getPrincipal()); 23 //获取密码 24 String credentials = String.valueOf((char[])token.getCredentials()); 25 26 //通过邮件地址进行验证 27 if(!"admin@163.com".equals(principal)) 28 throw new UnknownAccountException("帐号信息不存在"); 29 30 if(!"123456".equals(credentials)) 31 throw new IncorrectCredentialsException("密码错误"); 32 33 return new SimpleAuthenticationInfo(principal,credentials,this.getName()); 34 } 35 36 }
3) 配置shiro
1 #声明realm 2 #变量名 = 类全名 3 realmOne =cn.hl.realm.RealmOne 4 realmTwo =cn.hl.realm.RealmTwo 5 6 #将realm分配给securityManager的realms属性 7 #多realm情况下执行顺序与配置顺序直接相关 8 securityManager.realms=$realmOne,$realmTwo
4) 测试
1 //示例化Logger对象 2 private static final transient Logger logger = LoggerFactory.getLogger(TestMultiRealm.class); 3 4 public static void main(String[] args) { 5 //1、示例化工厂对象 6 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:multi-shiro.ini"); 7 8 //2、示例化SecurityManager对象 9 SecurityManager securityManager = factory.getInstance(); 10 11 //3、托管SecurityManager对象 12 SecurityUtils.setSecurityManager(securityManager); 13 14 //4、获取Subject对象 15 Subject subject = SecurityUtils.getSubject(); 16 17 //5、通过Subject实现用户登录验证 18 //UsernamePasswordToken token = new UsernamePasswordToken("admin","123"); 19 UsernamePasswordToken token = new UsernamePasswordToken("admin@163.com","123456"); 20 try{ 21 subject.login(token); 22 } 23 catch(UnknownAccountException ex){ 24 ex.printStackTrace(); 25 } 26 catch(IncorrectCredentialsException ex){ 27 ex.printStackTrace(); 28 } 29 30 if(subject.isAuthenticated()) 31 System.out.println("用户登录成功"); 32 33 //注销用户 34 subject.logout(); 35 }
【JdbcRealm】
1) 概述
Shiro框架中默认提供了对数据库的支持,通常我们可以直接配置JdbcRealm来实现使用数据库进行验证。
2) 包
3) 配置shiro
1 dataSource =com.mchange.v2.c3p0.ComboPooledDataSource 2 dataSource.driverClass =com.mysql.jdbc.Driver 3 dataSource.jdbcUrl =jdbc:mysql://localhost:3306/qqdb 4 dataSource.user =root 5 dataSource.password =123 6 7 #配置JdbcRealm 8 jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm 9 jdbcRealm.dataSource = $dataSource 10 11 #自定义验证Sql语句 12 #jdbcRealm.authenticationQuery=select password, password_salt from users where username = ? 13 jdbcRealm.authenticationQuery=select pwd from account where no=? 14 15 #自定义角色查询语句 16 #userRolesQuery = select role_name from user_roles where username = ? 17 18 #自定义权限查询语句 19 #permissionsQuery=select role_name from user_roles where username = ? 20 21 #配置SecurityManager的realms属性 22 securityManager.realms = $jdbcRealm
4)测试
1 //示例化Logger对象 2 private static final transient Logger logger = LoggerFactory.getLogger(TestJdbcRealm.class); 3 4 public static void main(String[] args) { 5 //1、示例化工厂对象 6 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:jdbc-shiro.ini"); 7 8 //2、示例化SecurityManager对象 9 SecurityManager securityManager = factory.getInstance(); 10 11 //3、托管SecurityManager对象 12 SecurityUtils.setSecurityManager(securityManager); 13 14 //4、获取Subject对象 15 Subject subject = SecurityUtils.getSubject(); 16 17 //5、通过Subject实现用户登录验证 18 //UsernamePasswordToken token = new UsernamePasswordToken("admin","123"); 19 UsernamePasswordToken token = new UsernamePasswordToken("23456789","123"); 20 try{ 21 subject.login(token); 22 } 23 catch(UnknownAccountException ex){ 24 ex.printStackTrace(); 25 } 26 catch(IncorrectCredentialsException ex){ 27 ex.printStackTrace(); 28 } 29 30 if(subject.isAuthenticated()) 31 System.out.println("用户登录成功"); 32 33 //注销用户 34 subject.logout(); 35 }
表数据: