springboot + shiro快速入门,五分钟教会你如何在springboot中使用shiro

目录

一、依赖

二、配置类

三、自定义 realm 类

四、控制器中的操作

五、定义登录认证规则

六、授权

1、使用编程式进行授权

2、使用注解式进行授权

七、总结:


一、依赖

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.3.2</version>
        </dependency>

二、配置类

---ShiroConfig.java

@Configuration
public class ShiroConfig{
    /**
     * ShiroFilterFactoryBean
     * 获取shiro过滤器
     * 主要配置需要拦截的路径
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Autowired DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();

        //关联DefaultWeSecurityManager 安全管理器对象
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);

        /*
            添加shiro的内置过滤器
            用于添加需要拦截的路径,并设置拦截级别
            拦截级别:,
              anon :无需认证就可以访问
              authc:必须认证了才能访问,
              user: 必须拥有 remeberMe(记住我)功能才能访问
              perms:拥有对某个资源的权限才能访问
              roles: 拥有某个角色才能访问
         */
        Map<String,String> interceptMap=new HashMap<>();

        //例如 拦截 修改个人资料 功能,设置为需要登录认证才能访问
        //interceptMap.put("/user/add","authc");

        //此处设置放行路径
        interceptMap.put("/user/*","anon");
        //使用通配符拦截所有请求
        interceptMap.put("/**","authc");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(interceptMap);


        return shiroFilterFactoryBean;
    }


    //DefaultWeSecurityManager
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(@Autowired ShiroRealm shiroRealm){
        DefaultWebSecurityManager webSecurityManager=new DefaultWebSecurityManager();

        //关联自定义realm对象
        webSecurityManager.setRealm(shiroRealm);

        return webSecurityManager;
    }

    //创建 realm 对象,需要自定义类继承 AuthorizingRealm抽象类,并实现其抽象方法
    @Bean
    public ShiroRealm getDhiroRealm(){
        return new ShiroRealm();
    }

}

三、自定义 realm 类

具体实现等后面再说

public class ShiroRealm extends AuthorizingRealm {

    /**
     * 访问授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        return null;
    }

    /**
     * 登录认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        return null;
    }
}

四、控制器中的操作

@GetMapping("/tologin")
public String toLogin(){
    //通过 SecurityUtils 工具类 获取当前的用户(Subject)
    Subject subject= SecurityUtils.getSubject();
    //封装用户的登录数据
    UsernamePasswordToken token=new UsernamePasswordToken(username,password);

    /* 
       认证用户身份,此操作将转移到 自定义 realm对象类中的认证方法中
       认证失败则会抛出如下异常
    */
    try{
        subject.login(token);
    }catch (UnknownAccountException e){
        System.out.println("用户不存在");
    }catch (IncorrectCredentialsException e){
        System.out.println("密码错误");
    }catch (LockedAccountException e){
        System.out.println("账户被锁定");
    }

    return "";
}

五、定义登录认证规则

现在我们回到 ShiroRealm 类中 制定认证规则

我们需要在 doGetAuthenticationInfo()方法中制定用户名校验规则

最终执行用户名比较的是 SimpleAccountRealm 类

而最终执行密码比较的是 SimpleAuthenticationInfo 类 

/**
     * 登录认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //数据库操作,获取用户信息,此处不演示
        String name="zs";
        String password="123456";

        //从token中获取登录方法传递过来的用户名
        String principal = (String) authenticationToken.getPrincipal();

        //判断用户是否存在
        if(!principal.equals(name)){
            //返回空则默认抛出(UnknownAccountException)用户不存在的异常
            return null;
        }
        //认证密码
        // 参数1:数据库中用户名  参数2:数据库中密码  参数3:realmName,系统运行时会自动生成,通过父类的方法获取realmName
        return new SimpleAuthenticationInfo(name,password,this.getName());
    }

六、授权

授权,即访问控制,控制谁能访问那些资源,主体(Subject)进行身份认证后需要分配权限(Permission)方可访问系统资源(Rsource),对于某些资源没有权限是无法访问的。

 授权方式:

  •     基于角色的访问控制 例:subject.hasRole("admin")
  •     基于资源的访问控制 例:subject.isPermission("user:*:create")

  权限字符串的命名规则 

        资源标识符:操作:资源实例标识符

例如:

  • 用户创建权限:user:create ,或 user:create:*
  • 用户修改实例001的权限 user:update:001
  • 用户操作实例001的所有权限 user:*:001

我们现在回到控制器中,在对用户进行认证之后,我们就可以对用户进行授权

1、使用编程式进行授权

@GetMapping("/tologin")
public String toLogin(){
    //通过 SecurityUtils 工具类 获取当前的用户(Subject)
    Subject subject= SecurityUtils.getSubject();
    //封装用户的登录数据
    UsernamePasswordToken token=new UsernamePasswordToken(username,password);

    /* 
       认证用户身份,此操作将转移到 自定义 realm对象类中的认证方法中
       认证失败则会抛出如下异常
    */
    try{
        subject.login(token);
    }catch (UnknownAccountException e){
        System.out.println("用户不存在");
    }catch (IncorrectCredentialsException e){
        System.out.println("密码错误");
    }catch (LockedAccountException e){
        System.out.println("账户被锁定");
    }

    //1、使用 基于角色的访问控制 的授权方式
    // 认证通过之后对用户进行授权
    //单角色
    if(subject.hasRole("admin")){ // 此处将进入自定义 realm对象中的doGetAuthorizationInfo方法中进行验证
    }

    //多角色
    if(subject.hasAllRoles(Arrays.asList("admin","user"))){ // 此处将进入自定义 realm对象中的doGetAuthorizationInfo方法中进行验证
    }

    //是否具有其中一个角色
    subject.hasRoles(Array.asList("admin","user")){
    }
    
    //使用 基于资源的访问控制 的授权方式
    boolean hasPermission=subject.isPermitted("user:*:*");

    return "";
}

在realm对象中定制授权操作

     /**
     * 授权(只有当需要检测用户权限的时候才会调用此方法)
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //获取权限对象
        SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();

        //获取用户的主身份信息,
        String userName=(String)principals.getPrimaryPrincipal();

        
        //基于角色的访问控制
        //此处查询数据库,获取当前用户的角色
        List<String> Roles=new ArrayList<>();
        //将数据库中查询出来的所有角色赋值给 simpleAuthorizationInfo 权限对象
        simpleAuthorizationInfo.addRoles(Roles);

        //基于权限的访问控制
        //此处查询数据库,获取当前用户的角色权限
        List<String> permissions=new ArrayList<>();
        //将数据库中查询出来的所有角色权限赋值给 simpleAuthorizationInfo 权限对象
        simpleAuthorizationInfo.addStringPermissions(permissions);

        
        return simpleAuthorizationInfo;
    }

2、使用注解式进行授权

注解需要加在控制器中的方法中,表示在进入该方法前判断用户是否有权限

@RequestMapping("/order")
@Controller
public class OrderController(){

    @RequiresRoles("admin")//判断角色是否有该角色
    @RequiresRoles({"admin","user"})//判断角色是否有多个角色
    @RequiresPermissions("order:save")//判断角色是否有该权限
    @GetMapping("/save")
    public String save(){
        //操作
    }
}

七、总结:

springboot中使用shiro的使用步骤简化如下:

  1. 添加依赖
  2. 配置类,需要配置三个bean
    1. ShiroFilterFactoryBean     关联 DefaultWebSecurityManager    配置拦截路径
    2. DefaultWebSecurityManager  关联 ShiroRealm 
    3. ShiroRealm  获取自定义ShiroRealm类
  3. 自定义 ShiroRealm 类 
    1. 实现 doGetAuthorizationInfo() 此方法实现授权操作规则
    2. 实现 doGetAuthenticationInfo() 此方法实现认证操作规则
  4. 控制器中操作 :
    1. 在登录方法中使用subject.login(token)方法进行用户认证
    2. 制定ShiroRealm类中的doGetAuthorizationInfo()方法
  5. 授权
    1. 基于角色的访问控制
      1. 使用subject.hasRole()方法判断是否有操作权限
      2. 在控制器中的方法中添加@RequiresRoles("")注解
    2. 基于权限的访问控制
      1. 使用subject.isPermitted()方法判断是否有操作权限
      2. 在控制器中的方法中添加@RequiresPermissions("")注解

下一章节将讲解如何实现密码加密加盐,以及整合Redis进行缓存

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,由于篇幅和涉及版权等问题,无法提供完整的代码实现。以下是基于springboot+shiro+layui实现qq聊天室功能的代码结构和主要实现思路供参考: 1. 后端代码结构 - controller:控制层,实现用户登录、注册等接口。 - service:服务层,实现用户管理、聊天消息管理等业务逻辑。 - dao:数据访问层,实现对数据库的增删改查操作。 - entity:实体类,包括用户信息、聊天消息等。 - config:配置类,实现Shiro安全框架的配置。 - websocket:WebSocket实现,接收消息并广播给在线用户。 2. 前端代码结构 - index.html:聊天室主页面。 - login.html:用户登录页面。 - register.html:用户注册页面。 - layui:Layui框架相关文件。 - js:前端JS代码,实现聊天室界面和逻辑。 3. 主要实现思路 - 用户登录:前端发送用户名和密码到后台,后台进行密码验证并返回登录结果。 - 用户注册:前端发送用户名和密码到后台,后台将用户信息保存到数据库。 - 聊天室界面:前端使用Layui实现聊天室界面,包括聊天消息显示和发送消息等功能。 - 实时通讯:使用WebSocket实现前后端实时通讯功能,后端接收消息并将消息广播给所有在线用户,前端接收消息并显示在聊天室界面。 - 私聊功能:在聊天室界面添加私聊功能,用户可以选择一个在线用户进行私聊,后端接收私聊消息并发送给对应的用户。 - 数据库存储:使用MySQL作为持久化存储,将用户信息、聊天记录等数据保存到数据库。 以上是springboot+shiro+layui实现qq聊天室功能的主要实现思路和代码结构,具体实现过程需要根据实际需求进行调整和改进。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值