Shiro学习笔记之自定义Realm实现认证和授权

为什么要自定义Realm

我们之前通过配置文件去获取用户角色权限的信息,但是有些时候希望从数据库中读取权限信息,此时就需要用到自定义Realm。

创建实体类


public class User {
	
	private String username;
	private String password;
	
	
	public String getUsername() {
		return username;
	}
	
	public void setUsername(String username) {
		this.username = username;
	}
	
	public String getPassword() {
		return password;
	}
	
	public void setPassword(String password) {
		this.password = password;
	}
	
	@Override
	public String toString() {
		return "User [username=" + username + ", password=" + password + "]";
	}
	

}

创建自定义的UserRealm

CachingRealm:带有缓存实现
AuthenticatingRealm:认证Realm
AuthorizingRealm:授权Realm
一般我们直接继承AuthorizingRealm,因为它继承了AuthenticatingRealm,
继承AuthorizingRealm可以同时实现认证和授权功能。Realm层次结构图


public class UserRealm extends AuthorizingRealm{

	
	/**
	 *授权
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		
		System.out.println("----进入授权----");
		//获取凭证 用户名
		String username = (String)principals.getPrimaryPrincipal();
		System.out.println("username:" + username);
		if (username == null) {
			return null;
		}
		
		//模拟权限,手动添加
		List<String> priList = new ArrayList<String>();
		
		//权限列表
		priList.add("user:add");
		priList.add("user:query");
		
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		
		//添加角色
		info.addRole("role1");
		
		for (String string : priList) {
			//添加权限
			info.addStringPermission(string);
			System.out.println("----添加权限---- " + string);
		}
		
		System.out.println("----授权完成---- ");
		
		return info;
	}
	
	
	
	/**
	 * 认证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		
		System.out.println("----进入认证----");
		//获取用户输入的用户名称
		String username = token.getPrincipal().toString(); 
		System.out.println("username:" + username);
		
		//获取密码   从数据库查询得到,这里直接获取
		String password = "123456";
		
		
		//将获取到的信息进行封装,第一个参数:身份,第二个参数:证明,第3个参数是当前类名
		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password, this.getName());
		System.out.println("----认证完成----");
		return info;
	}
	
	
}

测试UserRealm

public class UserRealmTest {

	@Test
	public void test1() {
		// 创建安全管理器的工厂对象
		Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");

		// 通过工厂获取安全管理器对象
		SecurityManager securityManager = factory.getInstance();
		System.out.println(securityManager.getClass().getSimpleName());
		
		//创建UserRealm
		UserRealm userRealm =new UserRealm();
		
		//给SecurityManager注入UserRealm,也可在ini文件中配置
		((RealmSecurityManager) securityManager).setRealm(userRealm);

		// 将安全管理器绑定到当前线程
		SecurityUtils.setSecurityManager(securityManager);

		// 使用SecurityUtils得到当前主体对象
		Subject subject = SecurityUtils.getSubject();

		// 封装用户验证信息
		AuthenticationToken token = new UsernamePasswordToken("张三", "123456");

		// 认证
		try {
			subject.login(token);
			System.out.println("登陆成功");
			
			System.out.println("是否拥有role1: " +subject.hasRole("role1"));
			System.out.println("是否拥有role2: " +subject.hasRole("role2"));
			
			//判断是否具有某些权限
			System.out.println("是否拥有权限user:add" + subject.isPermitted("user:add"));
			System.out.println("是否拥有权限user:query" + subject.isPermitted("user:query"));
			System.out.println("是否拥有权限user:delete" + subject.isPermitted("user:delete"));
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("用户名或密码不正确");
		}
		
	}

}

这里面使用代码注入自定义的Realm,如果使用配置文件的话

注释掉UserRealmTest类的以下两行

//创建UserRealm
UserRealm userRealm =new UserRealm();
		
//给SecurityManager注入UserRealm,也可在ini文件中配置
((RealmSecurityManager) securityManager).setRealm(userRealm);

新建shiro.ini配置文件

输入以下内容,UserRealm的全限定类名需要按照自己的来写。

[main]
#配置自定义Realm
UserRealm=com.sks.realm.UserRealm
#注入自定义的Realm
securityManager.realm=$UserRealm

类名=全限定类名:会自动创建一个类实例
变量名.属性=值:会自动调用相应的setter方法进行赋值
$变量名:引用之前的一个对象实例

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值