【权限管理】基于shiro的权限管理开发实现

上篇博客中简单介绍了一下权限管理的原理,其中包括最主要的两部分认证和授权。这篇博客中简单介绍一下shiro的认证和授权过程。

 

什么是shiro

Shiroapache旗下一个开源框架,它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权、加密、会话管理等功能,组成了一个通用的安全认证框架。

 

为什么要用shiro

既然可以基于url实现权限的管理,为什么还要用shiro呢??

1.shiro将安全认证相关的功能抽取出来组成一个框架,使用shiro就可以非常快速的完成认证、授权等功能的开发,降低系统成本。最主要的就是方便了我们的开发。

2.shiro使用广泛,shiro可以运行在web应用,非web应用,集群分布式应用中越来越多的用户开始使用shiro

 

shiro认证

认证流程:

【权限管理】基于shiro的权限管理开发实现_第1张图片

实例:

1.创建一个java工程,并加入shiro-corejar包以及它的依赖包。

【权限管理】基于shiro的权限管理开发实现_第2张图片

2.自定义realm

Shiro有自带的IniRealmIniRealmini配置文件中读取用户的信息,大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义realm

public class CustomRealm extends AuthorizingRealm {

	@Override
	public String getName() {
		return "customRealm";
	}

	// 用于认证
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken token) throws AuthenticationException {

		// token是用户输入的
		// 第一步从token中取出身份信息
		String userCode = (String) token.getPrincipal();

		// 第二步:根据用户输入的userCode从数据库中查询
		// 模拟从数据库查询到密码
		String password = "111111";

		// 如果查询到返回认证信息AuthenticationInfo

		SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
				userCode, password, this.getName());
		return simpleAuthenticationInfo;
	}
}

3.配置shiro-realm.ini文件


[main]
#自定义realm
customRealm=cn.itcast.shiro.realm.CustomRealm
#将realm设置到securityManager,相当于spring中注入
securityManager.realms=$customRealm

4.创建认证代码

 // 用户登录和退出
@Test
public void testCustomRealm() {

	// 创建securityManager工厂,通过ini配置文件创建securityManager工厂
	Factory factory = new IniSecurityManagerFactory(
				"classpath:shiro-realm.ini");

	// 通过工厂创建SecurityManager
	SecurityManager securityManager = factory.getInstance();

	// 将securityManager设置到运行环境中
	SecurityUtils.setSecurityManager(securityManager);

	// 创建一个Subject实例,该实例认证要使用上边创建的securityManager进行
	Subject subject = SecurityUtils.getSubject();

	// 创建token令牌,记录用户认证的身份和凭证即账号和密码
	UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",
				"111111");

	try {
		// 用户登陆
		subject.login(token);
	} catch (AuthenticationException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}

	// 用户认证状态

	Boolean isAuthenticated = subject.isAuthenticated();

	System.out.println("用户认证状态:" + isAuthenticated);

	// 用户退出

	subject.logout();

	isAuthenticated = subject.isAuthenticated();

	System.out.println("用户认证状态:" + isAuthenticated);

}

5.认证流程

1)创建token令牌,token中有用户提交的认证信息即账号和密码

2)执行subject.login(token),最终由securityManager通过Authenticator进行认证

3Authenticator的实现ModularRealmAuthenticator调用realm从数据库中取用户真实的账号和密码

4CustomRealm先根据token中的账号去数据库中找该账号,如果找不到则给ModularRealmAuthenticator返回null,如果找到则匹配密码,匹配密码成功则认证通过。

6.测试

【权限管理】基于shiro的权限管理开发实现_第3张图片

登录时用户认证成功,退出时用户认证失败。


shiro授权

授权流程

【权限管理】基于shiro的权限管理开发实现_第4张图片


授权方式

shiro支持三种方式的授权:

1.编程式

Subject subject = SecurityUtils.getSubject();
if(subject.hasPermission(“admin”)) {
//有权限
} else {
//无权限
}

2.注解式

@RequiresPermissions("admin")
public void hello() {
//有权限
}

3.JSP/GSP标签




web系统集成中使用后两种方式,我在这儿举个简单的例子就用第一种方式了。

实例

1.自定义realm

    // 用于授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		// 获取身份信息
		//将getPrimaryPrincipal方法返回值转为真实身份类型(在上边的doGetAuthenticationInfo认证通过填充到Simpl)
		String username = (String) principals.getPrimaryPrincipal();
		
		// 根据身份信息从数据库中查询权限数据
		// ....这里使用静态数据模拟
		List permissions = new ArrayList();
		permissions.add("user:create");
		permissions.add("user:delete");

		// 将权限信息封闭为AuthorizationInfo
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		for (String permission : permissions) {
			simpleAuthorizationInfo.addStringPermission(permission);
		}

		return simpleAuthorizationInfo;

	}

2.配置shiro-realm.ini文件与上面认证配置文件相同

3.创建授权代码

 // 自定义realm进行资源授权测试
	@Test
	public void testAuthorizationCustomRealm() {

		// 从ini文件中创建SecurityManager工厂
		Factory factory = new IniSecurityManagerFactory(
				"classpath:shiro-realm.ini");

		// 创建SecurityManager
		SecurityManager securityManager = factory.getInstance();

		// 将securityManager设置到运行环境
		SecurityUtils.setSecurityManager(securityManager);

		// 创建主体对象
		Subject subject = SecurityUtils.getSubject();

		// 对主体对象进行认证
		// 用户登陆
		// 设置用户认证的身份(principals)和凭证(credentials)
		UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",
				"111111");
		try {
			subject.login(token);
		} catch (AuthenticationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// 用户认证状态
		Boolean isAuthenticated = subject.isAuthenticated();

		System.out.println("用户认证状态:" + isAuthenticated);

		// 授权检测,失败则抛出异常
		// subject.checkRole("role22");

		// 基于资源授权
		System.out.println("是否拥有某一个权限:" + subject.isPermitted("user:delete"));
		System.out.println("是否拥有多个权限:"
				+ subject.isPermittedAll("user:update", "user:delete"));

		// 检查权限
		subject.checkPermission("user:delete");

	}

4.授权流程

1)执行subject.isPermitted("user:delete")

2securityManager通过ModularRealmAuthorizer进行授权

3ModularRealmAuthorizer调用realm获取权限信息

4ModularRealmAuthorizer再通过permissionResolver解析权限字符串,校验是否匹配

5.测试

【权限管理】基于shiro的权限管理开发实现_第5张图片

表明该用户拥有delete权限但是不拥有update权限。

 

现在只是跟着燕青老师做了几个简单的demo而已,接下来要好好研究一下与ITOO项目的整合,还需要继续努力!再次再推荐一下,燕青老师讲的这套视频真心不错。





你可能感兴趣的:(●项目流程和架构设计,-----【权限管理】)