Shiro 安全框架-简单使用

Shiro 简介概述

​Apache Shiro 是 Java 的一个安全框架。目前,使用 Apache Shiro 的人越来越多,因为它相当简单,对比 Spring Security,可能没有 Spring Security 做的功能强大,但是在实际工作时可能并不需要那么复杂的东西,所以使用小而简单的 Shiro 就足够了。对于它俩到底哪个好,这个不必纠结,能更简单的解决项目问题就好了。

image.png
常用功能

  • Authentication:身份认证 / 登录,验证用户是不是拥有相应的身份;
  • Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;
  • Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;

核心组件:Subject (当前操作用户及其操作)、SecurityManager(安全管理器)、Realms(数据源,操作数据源)。
image.png

RBAC权限模型

RBAC(Rela Based Access Controller 基于角色访问的),在数据库中就是角色表、行为表、权限表之间的关系绑定,权限绑定角色和行为。
image.png

Shiro 基本使用

框架搭建

  1. 引入相关依赖
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-core</artifactId>
  <version>1.7.0</version>
</dependency>
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-web</artifactId>
  <version>1.7.0</version>
</dependency>
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-spring</artifactId>
  <version>1.7.0</version>
</dependency>
  1. 定义数据源
@Component()
public class CustomRealm extends AuthorizingRealm {
    
    //认证信息
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }
    
    //授权信息
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        return null;
    }
}
  1. 创建配置文件

@Configuration
public class ShiroConfig {
    
    
    /**
    * 配置数据源,实则可以在服务层将数据传递进来
    * @return
    */
    @Bean("realm")
    public Realm realm(CustomRealm realm){
        return realm;
    }
    
    /**
    * 创建安全管理器,并配置数据源
    * @param realm 数据源
    * @return
    */
    @Bean("securityManager")
    public DefaultWebSecurityManager securityManager (@Qualifier("realm") Realm realm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(realm);
        return securityManager;
    }
    
    /**
    * 创建请求过滤器
    * @param securityManager 安全管理器
    * @return
    */
    @Bean("shiroFilterFactoryBean")
    public ShiroFilterFactoryBean shiroFilterFactoryBean (@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        
        //注册过滤器
        shiroFilterFactoryBean.setFilters();
        
        //用户认证时path
        shiroFilterFactoryBean.setLoginUrl("path");
        //用户认证成功后的path
        shiroFilterFactoryBean.setSuccessUrl("path");
        
        //设置未授权跳转path
        shiroFilterFactoryBean.setUnauthorizedUrl("path");
        
        //注入securityManager
        factoryBean.setSecurityManager(securityManager);
        return factoryBean;
    }
    
}

认证授权

  1. 配置数据源
//从Mysql中读取数据,配置数据源

@Component()
public class CustomRealm extends AuthorizingRealm {
    
    //认证信息
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        
        //创建授权对象
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        
        //获取主体也就是->用户名
        String username = (String) principalCollection.getPrimaryPrincipal();
        
        //根据获取的用户名查询访问权限(访问路径)->从底层数据库中读取
        List<Strinrg> privileges = userService.findPrivilegedByUsername(username); 
        
        //绑定用户和权限
        simpleAuthorizationInfo.addRoles(privileges);
       
        return simpleAuthorizationInfo;
    }
    
    //授权信息
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        
        //获取传递过来的用户名->也就是登录时的用户名
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String username = token.getUsername()
        
        //通过得到的用户名查询数据库存储的密码->在此之前可以确认用户名是否存在
        String password = userServer.findPassword(username);
        
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password, this.getName());
        return info;
    }
}
  1. 身份验证
//获取用户账号和密码
UsernamePasswordToken token = new UsernamePasswordToken(username, password);

//创建委托人
Subject currentUser = SecurityUtils.getSubject();

//查看处理结果
try {
    subject.login(token);
} catch (UnknownAccountException e) {
    error = "用户名/密码错误";
} catch (IncorrectCredentialsException e) {
    error = "用户名/密码错误";
} catch (AuthenticationException e) {
    //其他错误,比如锁定,如果想单独处理请单独catch处理
    error = "其他错误:" + e.getMessage();
}
  1. 授权管理
//使用注解 @RequiresAuthentication 需要完成用户登录 或者 @RequiresPermissions() 需要对应的权限
@RequestMapping("/user")
public class ProjectController {
    
    /**
    * 使用@RequiresAuthentication注解,检验是否完成用户登录
    * 使用@RequiresPermissions() 需要对应的权限
    */
    @RequiresPermissions("/queryAllPrincipal")
    @PostMapping("/queryAllPrincipal")
    public ResponseResult searchAllLikePrincipal(@RequestBody FrontProject frontProject, @RequestParam(required = false,defaultValue = "1") int pageNum, @RequestParam(required = false,defaultValue = "10") int pageSize){
        ResponseResult result = new ResponseResult();
        result.setData(this.projectService.queryAllPrincipal(frontProject,pageNum,pageSize));
        return result;
    }
    
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值