Spring Boot Shiro在Web应用中的作用详解

Spring Boot Shiro在Web应用中的作用详解

简介

Spring Boot Shiro是基于Spring Boot和Shiro的安全管理框架,可以方便地集成到Web应用中。它提供了一种简单、灵活且强大的身份验证和授权机制,可以在应用中实现多种安全需求,并且易于扩展和定制。

快速开始

依赖

在您的pom.xml文件中添加Spring Boot Shiro的依赖:

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring-boot-web-starter</artifactId>
    <version>1.7.1</version>
</dependency>

配置

在application.yml中添加shiro相关的配置:

# shiro
shiro:
  # 登录url
  loginUrl: /login
  # 成功后跳转的url
  successUrl: /index
  # 未授权url
  unauthorizedUrl: /403
  # 登出url
  logoutUrl: /logout
  # shiro加密方式
  hashAlgorithmName: md5
  # hash次数
  hashIterations: 1024
  # 是否开启记住我
  rememberMe: true
  cookie:
    # cookie名称
    name: rememberMe
    # cookie过期时间
    maxAge: 604800
    # cookie加密密钥
    cipherKey: 8AvVhmFLUs0KTA3Kprsdag==

# Shiro 配置
shiro:
  # ShiroFilter 配置
  filter:
    # 设置默认过滤器,顺序有讲究,细节请看文档,登陆成功主要看user这个拦截器
    loginUrl: /login
    unauthorizedUrl: /403
    anon: anon
    user: user
    logout: logout

  # ShiroRealm 配置
  realm:
    # 自定义的Realm类
    class-name: com.test.realm.UserRealm
    # 加密方式
    credentialsMatcher:
      hashAlgorithmName: MD5
      hashIterations: 1024

实现UserRealm

自定义UserRealm需要继承Shiro的AuthorizingRealm类,并实现doGetAuthorizationInfo()和doGetAuthenticationInfo()方法。其中,doGetAuthorizationInfo()用于获取授权信息,doGetAuthenticationInfo()用于获取身份验证信息。

以下是一个示例:

public class UserRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    // 获取授权信息
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); 
        //获取登录用户名
        String username= (String) principalCollection.getPrimaryPrincipal();
        // 根据用户名查询该用户的角色和权限
        User user = userService.findByUserName(username);
        Set<String> roles = new HashSet<>();
        roles.add(user.getRole());
        authorizationInfo.setRoles(roles);
        Set<String> permissions = new HashSet<>();
        permissions.add(user.getPermissions());
        authorizationInfo.setStringPermissions(permissions);
        return authorizationInfo;
    }

    // 获取身份验证信息
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
        String username = token.getUsername();
        User user = userService.findByUserName(username);
        if(user == null){
            throw new UnknownAccountException("用户名或密码错误!");
        }
        return new SimpleAuthenticationInfo(username,user.getPassword(),getName());
    }
}

实现登录、登出、授权

在controller中添加对应的方法来实现登录、授权、登出等功能。以下是一个示例:

@RestController
public class UserController {

    // 用户登录
    @PostMapping("/login")
    public Result login(@RequestParam String username,
                           @RequestParam String password,
                           @RequestParam(defaultValue = "false") Boolean rememberMe){
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username,password,rememberMe);
        try{
            subject.login(token);
            User user = (User)subject.getPrincipal();
            return Result.success("登录成功!", user);
        }catch (UnknownAccountException e){
            throw new UnknownAccountException("用户名或密码错误!");
        }catch (IncorrectCredentialsException e){
            return Result.error("用户名或密码错误!");
        }
    }

    // 用户登出
    @RequestMapping("/logout")
    public String logout(){
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return "redirect:/login";
    }

    // 用户授权
    @GetMapping("/index")
    @RequiresPermissions("user:index")
    public String index(){
        return "index";
    }
}

示例

示例一:基于注解的权限控制

@RestController
public class UserController {

    // 用户首页
    @GetMapping("/index")
    @RequiresPermissions("user:index")
    public String index(){
        return "This is index page.";
    }

    // 用户列表
    @GetMapping("/user/list")
    @RequiresPermissions("user:list")
    public String list(){
        return "This is user list page.";
    }

    // 用户编辑
    @GetMapping("/user/edit")
    @RequiresPermissions("user:edit")
    public String edit(){
        return "This is user edit page.";
    }

    // 用户删除
    @GetMapping("/user/delete")
    @RequiresPermissions("user:delete")
    public String delete(){
        return "This is user delete page.";
    }
}

该示例中,使用@RequiresPermissions注解定义访问该方法需要的权限。当用户没有该权限时,访问该方法会返回403错误页面。

示例二:记住我功能和退出登录

@RestController
public class UserController {

    // 用户列表
    @GetMapping("/user/list")
    @RequiresPermissions("user:list")
    public String list(){
        return "This is user list page.";
    }

    // 用户首页
    @GetMapping("/index")
    @RequiresPermissions("user:index")
    public String index(){
        return "This is index page.";
    }

    // 用户登录
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login(@RequestParam String username,
                           @RequestParam String password,
                           @RequestParam(defaultValue = "false") Boolean rememberMe,
                           HttpServletRequest request){
        Subject currentUser = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        token.setRememberMe(rememberMe);
        try{
            currentUser.login(token);
            User user = (User) currentUser.getPrincipal();
            request.getSession().setAttribute("user", user);
            return "redirect:/index";
        } catch (UnknownAccountException uae) {
            return "用户名不存在";
        } catch (IncorrectCredentialsException ice) {
            return "密码不正确";
        }
    }

    // 退出登录
    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public String logout(HttpServletRequest request){
        SecurityUtils.getSubject().logout(); //完成退出
        request.getSession().invalidate();
        return "redirect:/login";
    }

}

该示例中,使用HttpServletRequest来获取Session,并将登录用户信息保存到Session中,以便实现记住我功能。同时,当用户点击退出登录时,使用SecurityUtils.getSubject().logout()方法来完成退出操作,并清除Session。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Boot Shiro在Web应用中的作用详解 - Python技术站

(0)
上一篇 2023年6月2日
下一篇 2023年6月2日

相关文章

  • java 中Spring task定时任务的深入理解

    对于Java中Spring task定时任务的深入理解,我们可以通过以下步骤来进行实现: 1. 添加依赖 首先,我们需要在项目中添加Spring task的相关依赖,该依赖包括: <dependency> <groupId>org.springframework</groupId> <artifactId>sp…

    Java 2023年6月15日
    00
  • Java IO及BufferedReader.readline()出现的Bug

    关于“Java IO及BufferedReader.readline()出现的Bug”,我们需要注意以下两点: 1. Java IO 中的缓存问题 Java的IO操作是基于缓存进行的,而很多读取函数如BufferedReader. readline()是以换行符作为结束标记的,但是我们在编写代码时常常忽略了特殊情况的处理,导致出现了缓存问题,例如一次读取操作…

    Java 2023年5月27日
    00
  • 零基础学Java:Java开发工具 Eclipse 安装过程创建第一个Java项目及Eclipse的一些基础使用技巧

    下面详细讲解“零基础学Java:Java开发工具 Eclipse 安装过程创建第一个Java项目及Eclipse的一些基础使用技巧”的完整攻略。 一、Eclipse的安装 首先,进入Eclipse官网https://www.eclipse.org/downloads/packages/installer,选择下载适合自己电脑操作系统的Eclipse版本。 下…

    Java 2023年5月24日
    00
  • JAVA module-info.java文件详解

    JAVA Module 是 JDK 9 之后推出的新特性,可以用来管理和组织 Java 应用程序的代码。在使用 Java module 的时候,需要用到 module-info.java 文件来声明模块的依赖和公共 API 等信息。本文将详细讲解 JAVA module-info.java 文件的相关知识,帮助读者了解如何使用该功能。 1. module-i…

    Java 2023年5月19日
    00
  • 浅谈JSONObject的使用及示例代码(JSON解析)

    一、什么是JSONObject? 在 JSON 格式中,包含了两种数据结构,分别是键值对和数组,JSONObject 就是用来处理键值对的一种数据结构。 在Java中,可以通过JSONObject对象来解析JSON字符串。 JSONObject继承自HashMap类,因此可以像在Map中一样使用put/get方法来操作其中的键值对。 二、JSONObject…

    Java 2023年5月26日
    00
  • Mybatis中SqlSession下的四大对象之执行器(executor)

    Mybatis是一款流行的ORM框架,SqlSession是其核心组件之一。在SqlSession中,有四大对象分别是:Configuration、Executor、StatementHandler和ResultSetHandler。其中,Executor是Mybatis中最重要的对象之一,本文将详细讲解Mybatis中SqlSession下的四大对象之执行…

    Java 2023年5月20日
    00
  • Java使用MyBatis框架分页的5种方式

    下面就来详细讲解“Java使用MyBatis框架分页的5种方式”的完整攻略。 1、MyBatis的分页插件 MyBatis作为一款优秀的ORM框架,提供了一个非常方便的分页插件——PageHelper,只需在查询前进行设置即可。以下是使用PageHelper的示例: int pageNum = 1; //当前页码 int pageSize = 10; //每…

    Java 2023年5月20日
    00
  • js函数获取html中className所在的内容并去除标签

    获取 HTML 中指定 className 所在的内容并去除标签,可以通过 JavaScript 函数来实现。下面是具体步骤: 选取需要获取 className 的元素 首先,需要通过 JavaScript 找到需要获取 className 的元素,可以使用 document.querySelector 或 document.querySelectorAll…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部