SpringBoot整合Shiro

Shiro简介

Apache Shiro是一个开源的轻量级的Java安全框架,它提供了身份认证、授权、密码管理、会话管理等操作。我们知道在Spring中也有一个跟它功能差不多的框架Spring Security,Shiro框架可以更加直观的提供安全性操作,在SSM框架中整合Shrio的配置步骤比较多。但是争对SpringBoot,在SpringBoot官方也提供了对应的启动器。这样的话化简了Shiro在Spring Boot中的配置,提高了开发效率。

Spring Boot 整合Shiro

1、创建项目

在POM文件中添加对应的依赖,以及页面模板的依赖。

    <!--增加Shiro的配置-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring-boot-web-starter</artifactId>
            <version>1.4.0</version>
        </dependency>
        <!--Thymeleaf模板引擎-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--在Thymeleaf中使用shiro标签-->
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>

注意:
在对于这个而配置的时候不需要添加关于spring-boot-starter-web的依赖,因为在shiro-spring-boot-web-starter中已经添加了对应的依赖,可以通过查看依赖关系来发现

   <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>${spring-boot.version}</version>
  </dependency>

可以看到对应的web启动器。另外为了使用thymeleaf引入了对应的thymeleaf对于shiro的标签。

2、Shiro基本配置

在application.properties中添加对应的Shiro的配置。

#开启Shiro配置,默认为true
shiro.enabled=true
#开启ShiroWeb配置,默认为true
shiro.web.enabled=true
#登录地址
shiro.loginUrl=/login
#登录成功地址
shiro.successUrl=/index
#未获授权默认跳转地址
shiro.unauthorizedUrl=/unauthorized
#允许通过URL参数实现会话跟踪,如果网站支持Cookie,可以关闭这个选项。默认为true
shiro.sessionManager.sessionIdUrlRewritingEnabled=true
#是否允许通过Cookie实现会话跟踪,默认为true
shiro.sessionManager.sessionIdCookieEnabled=true

完成配置类的编写之后,通过配置类的方式提供Shiro的配置。

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.realm.text.TextConfigurationRealm;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ShiroConfig {

    /**
     * 自定义Realm
     * 直接配置了两个用户
     * nihiu=123
     * admin=123
     * 角色分别对应user和admin两个角色
     * @return
     */
    @Bean
    public Realm realm(){
        TextConfigurationRealm realm = new TextConfigurationRealm();
        realm.setUserDefinitions("nihui=123,user
 admin=123,admin");
        realm.setRoleDefinitions("admin=read,write
 user=read");
        return realm;
    }

    /**
     * ShiroFilterChainDefinition
     * @return
     */
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition(){
        DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
        chainDefinition.addPathDefinition("/login","anon");
        chainDefinition.addPathDefinition("/doLogin","anon");
        chainDefinition.addPathDefinition("logout","logout");
        chainDefinition.addPathDefinition("/**","authc");
        return chainDefinition;
    }

    /**
     * 定义一个在Thymeleaf中支持Shiro标签。
     * @return
     */
    @Bean
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }
}

编写登录接口的控制类

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class UserController {
    @PostMapping("/doLogin")
    public String doLogin(String username, String password, Model model){
        //构造一个UsernamePasswordToken实例获取
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
        //获取Subject对象访问login方法当有异常的时候抛出异常
        Subject subject = SecurityUtils.getSubject();
        try{
            subject.login(token);
        }catch (AuthenticationException e){
            model.addAttribute("error","用户名密码输入错误");
            return "login";
        }
        return "redirect:/index";
    }
    @RequiresRoles("admin")
    @GetMapping("/admin")
    public String admin(){
        return "admin";
    }

    @RequiresRoles(value = {"admin","user"},logical = Logical.OR)
    @GetMapping("/user")
    public String user(){
        return "user";
    }
}

这里使用@ControllerAdvice注解创建全局异常处理器进行异常的处理。

import org.apache.shiro.authz.AuthorizationException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

@ControllerAdvice
public class ExceptionController {
    @ExceptionHandler(AuthorizationException.class)
    public ModelAndView error(AuthorizationException e){
        ModelAndView mv = new ModelAndView("unauthorized");
        mv.addObject("error",e.getMessage());
        return mv;
    }
}
3、编写页面代码

在这里插入图片描述
在对应的目录下面建立五个页面分别表示用户登录页面、首页、用户页面、管理员页面、认证错误页面。

登录页面
在这里插入图片描述
用户页面
在这里插入图片描述
管理员页面
在这里插入图片描述
认证错误页面
在这里插入图片描述

用户名密码错误提示
在这里插入图片描述
用户首页

<!DOCTYPE html>
<html lang="en" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h3>Hello,<shiro:principal/></h3>
    <h3><a href="/logout">注销登录</a></h3>
    <h3><a shiro:hasRole="admin" href="/admin">管理员页面</a></h3>
    <h3><a shiro:hasAnyRoles="admin,user" href="/user">普通用户页面</a></h3>
</body>
</html>

管理员页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>管理员页面</h1>
</body>
</html>

用户登录页

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/doLogin" method="post">
        <input type="text" name="username"/><br/>
        <input type="password" name="password"/><br/>
        <div th:text="${error}"></div>
        <input type="submit" value="登录">
    </form>

</body>
</html>

授权全局异常页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://ww.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>
        <h3>未获授权,非法访问</h3>
        <h3 th:text="${error}"></h3>
    </div>
</body>
</html>

用户页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>用户页面</h1>
</body>
</html>
总结

通过上这个小例子,让我对权限控制有了更进一步的了解,对于之前学过的Shrio在这里终于结合到一起使用到了SpringBoot中。在开发期间也根据之前的内容熟悉了SpringBoot的自动配置的加载原理,也看到了日志中很多的加载内容。通过这个小项目为我们展现了一种整合Shrio安全框架的方式,当然还有很多的整合方式等待着我去学习。在以后的博客中可能会分享出来。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值