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

yizhihongxing

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日

相关文章

  • springboot实现返回视图而不是string的方法

    SpringBoot实现返回视图而不是String的方法 在SpringBoot中,我们可以使用Thymeleaf、Freemarker等模板引擎来实现返回视图而不是String。下面是实现返回视图的几种方法。 1. 使用Thymeleaf Thymeleaf是一种现代化的服务器端Java模板引擎,可以用于Web和独立环境。下面是一个简单的示例: 在pom.…

    Java 2023年5月18日
    00
  • Java如果通过jdbc操作连接oracle数据库

    以下是Java通过JDBC连接Oracle数据库的完整攻略,包括代码示例和详细步骤: 一、准备工作 1. 下载Oracle JDBC驱动 首先,我们需要下载Oracle官方的JDBC驱动。我们可以在Oracle官网上下载,或者通过与Oracle数据库的连接成功时给出的链接下载安装。在这里我们以”ojdbc8.jar”为例。 2. 配置Java环境变量 将”o…

    Java 2023年5月19日
    00
  • Java截取字符串的方法

    当处理字符串时,Java提供了多种截取字符串的方式,本文针对这些方法进行详细的讲解,方便读者学习并掌握该技能。 序号方式截取字符串 通过char数组序号的方式截取字符串是Java中最常见的一种方法。该方式是基于Java中String类中的toCharArray()方法,可以将字符串按指定长度分解为多个字符的序列,然后通过循环遍历序列获取需要的部分。 Stri…

    Java 2023年5月26日
    00
  • 基于maven使用IDEA创建多模块项目

    下面是基于maven使用IDEA创建多模块项目的完整攻略。 1. 创建父项目 打开IDEA,选择File -> New -> Project。 在左侧栏选择Maven,并且在右侧方框中勾选Create from archetype选项。 在弹出的对话框中选择maven-archetype-quickstart,并点击Next。 填写GroupId…

    Java 2023年5月19日
    00
  • java实现省市区转换成树形结构

    下面是详细的Java实现省市区转换成树形结构的攻略,包括过程和示例说明。 1. 收集省市区数据 首先需要收集省市区的原始数据,可以从各种数据源中获取,如官方提供的数据文件、API接口等。为方便操作,最好将数据保存到数据库中,并设计好相应的数据表结构,以便后续处理和查询。 下面是一个示例的省市区表结构: CREATE TABLE `area` ( `id` i…

    Java 2023年5月26日
    00
  • SpringBoot的三大开发工具小结

    接下来我为您详细讲解“SpringBoot的三大开发工具小结”的完整攻略。 前言 SpringBoot是一个高效、快速构建基于Spring框架的应用程序的工具。它支持简单的配置,使得开发者可以快速上手,专注于业务代码的编写。在SpringBoot的开发过程中,借助于一些开发工具可以大大提高开发效率和代码质量。本文将重点介绍SpringBoot的三种开发工具:…

    Java 2023年5月15日
    00
  • Springmvc处理ajax请求并返回json数据

    下面我将介绍SpringMVC处理ajax请求并返回JSON数据的完整攻略。 什么是SpringMVC SpringMVC是一个基于Spring框架之上的Web框架,它可以帮助我们简化Web应用程序的开发,并且具有良好的可扩展性和灵活性。SpringMVC中最常见的请求方式是通过URL来映射到处理器(Controller)中的某个具体的方法,并由该方法来处理…

    Java 2023年6月15日
    00
  • 详解spring与jdbc整合操作

    详解spring与jdbc整合操作 1. Spring JDBC介绍 Spring JDBC是spring框架中最重要的部分之一,提供了一组用于执行SQL操作和访问关系型数据库的类和接口。 Spring JDBC提供的主要API为JdbcTemplate和NamedParameterJdbcTemplate,以及支持Transaction(事务)和DAO(数…

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