对于shiro框架我们之前已经分别叙述了shiro在.ini文件中的认证,shiro代码中硬编码的认证实现,以及我们将shiro与springboot整合的认证实现,还有我们将shiro与springboot整合之后,连接数据库的认证实现,接下来我们继续为大家展开来研究一下shiro与springboot整合之后连接数据库的授权方面的实现,其实与之前shiro连接数据库做认证的实现思路相似,我们也首先来理一下思路。
一、关于shiro与springboot整合的授权实现思路
首先,shiro这个安全框架为我们提供了三种授权方式:
第一:我们可以基于编码的方式授权:
//编程式
Subject subject = SeurityUtils.getSubject();
if(subject.hasRole("admin")){
//有权限
} else {
//无权限
}
第二:我们可以基于标签的方式授权(即:在页面中使用shiro的标签进行授权):
JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成:
<shiro:hasRole name="admin">
<!-有权限->
</shiro:hasRole>
tip:Thymeleaf 中使用shiro需要额外集成
第三:我们可以基于shiro在代码中为我们提供的相应的注解进行授权。
//注解式
@RequiresRole("admin")
public void hello(){
//有权限
}
未做权限控制
我们先来看一下我们没有做权限控制的首页内容:
目前来看我们首页有四个大的菜单模块,相对应的在大模块下面又分别有几个小模块,现在不论我们以哪个用户登录进来所看到的内容都是一样的,这样明显是有问题的,在一个完整的系统中,我们以不同的身份登录看到的内容应该是不一样的,比如我是卖家,我就应该能看到物流管理,订单,商品三个模块,再比如我是物流公司我就应该只能看到物流管理模块,或者我是平台的管理者,我就应该能看到所有的模块来进行操作,所有,有了这样的需求我们就要对菜单对不同的用户登录进来做不同的权限的限制或者是不同角色的限制,由此我们就需要对用户进行授权。
那么在授权时呢我们就需要拿着用户的身份信息,去数据库查询用户的角色信息以及对应的权限信息。
在我们的程序中,在拿权限信息时,我们实际上走的是自定义Realm中的doGetAuthorizationInfo这个方法获取权限信息,如果没有权限则直接返回null。如果有相应的角色或者权限,那么我们在页面中就可以根据相应的角色以及权限来实现对资源的控制。
二、将权限信息首先写在代码中
接下来编写我们的自定义Realm,首先上一段编写之前的自定义Realm的代码:
编写前:
/**
* 自定义Realm
*/
public class MyRealm extends AuthorizingRealm {
/**
* 授权
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
/**
* 认证
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//拿到用户名
String principal = (String) authenticationToken.getPrincipal();
//用获取容器中对象的工具类拿到userService对象
UserService userService = (UserService) ApplicationContextUtils.getBean("userService");
//调用方法拿到user对象
User user = userService.findByUsername(principal);
//如果user对象不为空
if (!StringUtils.isEmpty(user)){
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(), ByteSource.Util.bytes(user.getSalt()),this.getName());
return simpleAuthenticationInfo;
}
return null;
}
}
可以看到的是,我们之前只是对用的认证做了处理,并没有对权限进行处理,那么接下来我们就要进行权限的处理
添加权限认证
首先我们先对数据库中的admin用户进行授权:
/**
* 自定义Realm
*/
public class MyRealm extends AuthorizingRealm {
/**
* 授权
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//首先拿到用户的主身份信息
String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
//如果是admin登录
if ("admin".equals(primaryPrincipal)){
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//给admin权限(最高权限)
simpleAuthorizationInfo.addRole("admin");
//返回权限信息
return simpleAuthorizationInfo;
}
return null;
}
/**
* 认证
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//拿到用户名
String principal = (String) authenticationToken.getPrincipal();
//用获取容器中对象的工具类拿到userService对象
UserService userService = (UserService) ApplicationContextUtils.getBean("userService");
//调用方法拿到user对象
User user = userService.findByUsernam