Shiro权限管理
1、权限管理
权限管理:不同角色的用户进入到系统能够完成的操作是不同的,对不同角色的用户进行的可执行操作的管理称为权限管理。
2、如何实现权限管理
基于主页的权限管理:不同的用户使用不同的主页,权限通过主页功能菜单进行限制
基于用户权限的访问控制:统权限表、用户权限表、用户表,比较冗余
基于用户角色的访问控制(RBAC):系统权限表、用户权限表、用户表、角色表、用户角色表
1、基于JavaSe的Shiro的基本使用
1、导入shiro依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.5.1</version>
</dependency>
但是出现了一点问题:就是引入这个依赖后pom文件就会报错,可以在pom文件中加入加入阿里云的代理仓库:
<repositories><!-- 阿里云代码库 -->
<repository>
<id>maven-ali</id>
<url>http://maven.aliyun.com/nexus/content/repositories/central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
</repository>
</repositories>
2、创建shiro配置文件:shiro.ini
[users]
zhangsan=123456,seller
lisi=666666,ckmgr
admin=222222,admin
[roles]
admin=*
seller=order-add,order-del,order-list
ckmgr=ck-add,ck-del,ck-list
3、shiro的基本使用
public class TestShiro {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String username = sc.nextLine();
System.out.println("请输入密码:");
String password = sc.nextLine();
//创建安全管理器
DefaultSecurityManager securityManager = new DefaultSecurityManager();
//创建realm
IniRealm realm = new IniRealm("classpath:shiro.ini");
//将realm设置给安全管理器
securityManager.setRealm(realm);
//将realm设置给SecurityUtils工具
SecurityUtils.setSecurityManager(securityManager);
//通过SecurityUtils获取subject对象
Subject subject = SecurityUtils.getSubject();
//认证流程
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
System.out.println(subject.isAuthenticated());//false
//完成认证
subject.login(token);
System.out.println(subject.isAuthenticated());//true
//授权
//判断是否有某个角色
subject.hasRole("seller");//true
//判断是否有某个权限
boolean permitted = subject.isPermitted("oredr-del");
System.out.println(permitted);//true
}
}
4、shiro认证授权流程
(1) 通过subject.login(token)进行登录,就会将token包含的用户信息(账号和密码)传递给SecurityManager
(2) SecurityManager会调用Authentication进行认证
(3) Authentication就会根据Realm安全信息进行认证校验
(4) Realm根据得到的token,调用doGetAuthenticationInfo()方法进行认证
(5) 认证完成后一层层返回到subject
2、SpringBoot整合shiro
- 1、导入shiro依赖:
- 2、配置shiro过滤器:拦截进行认证和授权的用户
- 3、配置SecurityManager到Spring容器
- 4、配置Realm(SecurityManager需要Realm)
1. 导入依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
2. 配置shiro过滤器
@Configuration
public class ShiroConfig {
//将Realm交给Spring容器创建
@Bean
public IniRealm getRealm() {
IniRealm iniRealm = new IniRealm("classpath:shiro.ini");
return iniRealm;
}
//将DefaultSecurityManager交给Spring容器来创建和管理
@Bean
public DefaultSecurityManager getDefaultSecurityManager(IniRealm iniRealm) {
//SecurityManager要完成认证和校验需要Realm
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(iniRealm);
return securityManager;
}
//配置shiro的过滤器
@Bean
public ShiroFilterFactoryBean shiroFilter(DefaultSecurityManager securityManager) {
//过滤器工厂
ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
//过滤器是进行权限校验的核心,进行认证和授权需要SecurityManager
filter.setSecurityManager(securityManager);
//设置拦截规则
//anon:匿名用户可以访问,authc:授权用户可以访问
Map<String, String> filterMap = new HashMap<>();
filterMap.put("/","anon"); //项目个根路径不拦截
filterMap.put("/login.html","anon"); //登录页面不拦截
filterMap.put("/register.html","anon"); //注册页面不拦截
filterMap.put("/user/login","anon"); //登录不拦截
filterMap.put("/user/regist","anon"); //注册不拦截
filterMap.put("/static
public class MyRealm extends AuthorizingRealm {
@Autowired
private UserDao userDao;
@Autowired
private RoleDao roleDao;
@Autowired
private PermissionDao permissionDao;
public String getName(){
return "myRealm";
}
@SneakyThrows
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
//从token中获取用户名
String username = token.getUsername();
//根据用户名到数据库中查询用户信息
User user = userDao.queryUserByUsername(username);
if(user==null){
return null;
}
//将查询出来的密码封装成安全信息给shiro
AuthenticationInfo info = new SimpleAuthenticationInfo(
username,//当前用户的用户名
user.getUserPwd(),//从数据库中查询出来的安全数据
getName()
);
return info;
}
@SneakyThrows
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获取用户的用户名
String username = (String)principalCollection.iterator().next();
//根据用户名查询用户的角色列表
Set<String> roleNames = roleDao.queryRoleNamesByUsername(username);
//根据用户名查询用户的权限列表
Set<String> ps = permissionDao.queryPermissionsByUsername(username);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setRoles(roleNames);
info.setStringPermissions(ps);
return info;
}
}
测试结果:
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。