我们先来探讨下授权需要继承那个类吧。
先来看Realm的继承关系:
Realm是他们的父类,继承AuthorizingRealm其也间接继承了 CachingRealm(带有缓存实现)。
通过源码分析,可以查看认证只是调doGetAuthorizationInfo
所用直接继承AuthorizingRealm即可:
那接下里我们就来写个例子吧:
项目路径:
myReal.java:
package com.yiyi.realm;
import java.util.HashSet;
import java.util.Set;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
/**
*
* @author kf0101
*
*/
public class MyRealm extends AuthorizingRealm {
/**
* 认证方法
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
System.out.println("1----------->"+token);
// 将AuthenticationToken对象转换成UsernamePasswordToken对象
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
// 获取UsernamePasswordToken中的用户名
String username = upToken.getUsername();
// 从数据库中查询 username 对应的用户记录
System.out.println("从数据库中查找" + username + "的信息");
// 若用户的信息不存在,则抛出UnknownAccountException异常。
if ("unknown".equals(username)) {
throw new UnknownAccountException("用户不存在");
}
// 根据用户的信息进行反馈,则抛出LockedAccountException异常。
if ("han".equals(username)) {
throw new LockedAccountException("用户被锁定");
}
// 根据用户的信息来封装SimpleAuthenticationInfo对象。
// 当前 realm 对象的 name
String realmName = getName();
// 认证的实体信息。
Object principal = username;
// 密码
Object hashedCredentials = null;
if("admin".equals(username)){
hashedCredentials = "2abec21dc41c75c88cb87e7306c5e75f";
}else if("zhao".equals(username)){
hashedCredentials = "399503120959cd94972d6d5f3a9d4c61";
}
//盐值
ByteSource credentialsSalt = ByteSource.Util.bytes(username);
SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(principal, hashedCredentials, credentialsSalt, realmName);
return info;
}
/**
* 授权方法:
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
//1. 从 PrincipalCollection 中来获取登录用户的信息
Object principal = principals.getPrimaryPrincipal();
//2. 利用登录的用户的信息来判定当前用户的角色或权限
Set<String> roles=new HashSet<String>();
roles.add("user");//不管是什么用户都添加user角色
if("admin".equals(principal)){
roles.add("admin");
}
//3. 创建 SimpleAuthorizationInfo, 并设置其 roles 属性.
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roles);
//4. 返回 SimpleAuthorizationInfo 对象.
return info;
}
/**
* 明文进行谜面进行加密
* @param args
*/
public static void main(String[] args) {
int hashIterations = 10000;//加密的次数
Object salt = "zhao";//盐值
Object credentials = "123456";//密码
String hashAlgorithmName = "MD5";//加密方式
Object simpleHash = new SimpleHash(hashAlgorithmName, credentials,
salt, hashIterations);
System.out.println("加密后的值----->" + simpleHash);
}
}
这时我们就可以来验证下这个授权代码,我们先以admin这个用户登录,测试发现,admin.jsp 和user.jsp页面都可以进行访问。但是呢?我们以 zhao这个用户登录的话,发现admin.jsp这个页面是不可以进行访问的。因为在代码中设置了任何一个用户登录的话都是授权于user角色,如果是admin用户则赋予admin角色。也就是在以后中我们写项目,好比OA项目,管理员可以看所用员工的信息,但是员工的话只是可以看自己的信息。