最基础的是Realm接口,CachingRealm负责缓存处理,AuthenticationRealm负责认证,AuthorizingRealm负责授权,通常自定义的realm继承AuthorizingRealm。
jdk版本:1.7.0_72 eclipse:elipse-indigo
log4j.rootLogger=debug, 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
[main] #自定义 realm customRealm=cn.itcast.shiro.authentication.realm.CustomRealm1 #将realm设置到securityManager securityManager.realms=$customRealm
@Override public String getName() { return "customRealm1"; } //支持UsernamePasswordToken @Override public boolean supports(AuthenticationToken token) { return token instanceof UsernamePasswordToken; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token) throws AuthenticationException { //从token中 获取用户身份信息 String username = (String) token.getPrincipal(); //拿username从数据库中查询 //.... //如果查询不到则返回null if(!username.equals("zhang")){//这里模拟查询不到 return null; } //获取从数据库查询出来的用户密码 String password = "123";//这里使用静态数据模拟。。 //返回认证信息由父类AuthenticatingRealm进行认证 SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo( username, password, getName()); return simpleAuthenticationInfo; } //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { // TODO Auto-generated method stub return null; } }
@Test public void testCustomerAuthenticationRealm() { // 构建SecurityManager工厂,IniSecurityManagerFactory可以从ini文件中初始化SecurityManager环境 Factoryfactoty = new IniSecurityManagerFactory
("classpath:shiro-realm.ini"); // 通过工厂创建SecurityManager SecurityManager securityManager = factoty.getInstance(); // 将securityManager设置到运行环境中 SecurityUtils.setSecurityManager(securityManager); // 创建一个Subject实例,该实例认证要使用上边创建的securityManager进行 Subject subject = SecurityUtils.getSubject(); // 创建token令牌,记录用户认证的身份和凭证即账号和密码 UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123"); try { subject.login(token); } catch (AuthenticationException e) { e.printStackTrace(); } boolean authenticated = subject.isAuthenticated(); System.out.println("用户认证状态"+authenticated); }
// 授权 @Override protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { // 获取身份信息 String username = (String) principals.getPrimaryPrincipal(); // 根据身份信息从数据库中查询权限数据 //....这里使用静态数据模拟 Listpermissions = new ArrayList permissions.add("user:create"); permissions.add("user.delete"); //将权限信息封闭为AuthorizationInfo SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); for(String permission:permissions){ simpleAuthorizationInfo.addStringPermission(permission); } return simpleAuthorizationInfo; }();
@Test public void testCustomerAuthorizationRealm() { // 构建SecurityManager工厂,IniSecurityManagerFactory可以从ini文件中初始化SecurityManager环境 Factoryfactoty = new IniSecurityManagerFactory("classpath:shiro-realm.ini"); // 通过工厂创建SecurityManager SecurityManager securityManager = factoty.getInstance(); // 将securityManager设置到运行环境中 SecurityUtils.setSecurityManager(securityManager); // 创建一个Subject实例,该实例认证要使用上边创建的securityManager进行 Subject subject = SecurityUtils.getSubject(); // 创建token令牌,记录用户认证的身份和凭证即账号和密码 UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123"); try { subject.login(token); } catch (AuthenticationException e) { e.printStackTrace(); } boolean authenticated = subject.isAuthenticated(); System.out.println("用户认证状态"+authenticated); // 基于资源的授权,调用isPermitted方法会调用CustomRealm从数据库查询正确权限数据 // isPermitted传入权限标识符,判断user:create:1是否在CustomRealm查询到权限数据之内 boolean permitted = subject.isPermitted("user:create:1"); System.out.println("单个权限的判断:"+permitted); boolean permittedAll = subject.isPermittedAll("user:create","item:add"); System.out.println("多个权限的判断:"+permittedAll); // 使用check方法进行授权,如果授权不通过会抛出异常 subject.checkPermission("items:add:1"); }
1、 执行subject.isPermitted("user:create") 2、 securityManager通过ModularRealmAuthorizer进行授权 3、 ModularRealmAuthorizer调用realm获取权限信息 4、 ModularRealmAuthorizer再通过permissionResolver解析权限字符串,校验是否匹配
源码下载地址:点击打开链接