栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring Boot整合Shiro

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring Boot整合Shiro

Spring Boot整合Shiro 1. Shiro简介

Apache Shiro是一个开源的轻量级的Java安全框架,它提供身份验证、授权、密码管理以及会话管理等功能。相对于SpringSecurity,Shiro框架更加直观、易用,同时也能提供健壮的安全性。在传统的SSM框架中,手动整合Shiro的配置步骤还是比较多的,针对Spring Boot, Shiro 官方提供了shiro-spring-boot-web-starter 用来简化Shiro 在Spring Boot 中的配置。下 面向读者介绍shiro-spring- boot-web- starter的使用步骤。

2. 整合Shiro 2.1 创建项目

首先创建一个普通的SpringBootWeb项目,添加Shiro依赖以及页面模板依赖,代码如下:


    org.springframework.boot
    spring-boot-starter


    org.apache.shiro
    shiro-spring-boot-web-starter


    org.apache.shiro
    shiro-spring-boot-web-starter
    1.9.0


org.springframework.boot
spring-boot-starter-thymeleaf


    com.github.theborakompanioni
    thymeleaf-extras-shiro
    2.1.0

注意这里不需要添加spring-boot-starter-web 依赖,shiro-spring boot-web-starter中已经依赖了
spring- boot-starter-web。同时,本案例使用Thymeleaf 模板,因此添加Thymeleaf依赖,另外,为
了在Thymeleaf中使用shiro标签,因此引入了thymeleaf-extras-shiro 依赖。

2.2 Shiro基本配置

首先在application.properties中配置Shiro的基本信息,代码如下:

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

spring.thymeleaf.cache=false

基本信息配置完成后,接下来在Java代码中配置Shiro,提供两个最基本的Bean即可,代码如下:

@Configuration
public class ShiroConfig {

    // 配置用户和角色,Realm 可以是自定义的 Realm,也可以是 Shiro 提供的 Realm
    @Bean
    public Realm realm() {
        // 为简单起见,本案例没有配置数据库连接,直接配置了两个用户,以及对应的角色
        TextConfigurationRealm realm = new TextConfigurationRealm();
        realm.setUserDefinitions("admin=123,adminn hangge=123,user");
        // 配置角色权限,admin 具有read、write 权限,user 只有 read 权限
        realm.setRoleDefinitions("admin=read,writen user=read");
        return realm;
    }

    // 配置基本的过滤规则
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition chainDefinition =
                new DefaultShiroFilterChainDefinition();
        // /login 和 /doLogin 可以匿名访问
        chainDefinition.addPathDefinition("/login", "anon");
        chainDefinition.addPathDefinition("/doLogin", "anon");
        // https://blog.csdn.net/logout 是一个注销登录请求
        chainDefinition.addPathDefinition("https://blog.csdn.net/logout", "logout");
        // 其余请求则都需要人周后才能访问
        chainDefinition.addPathDefinition("/**", "authc");
        return chainDefinition;
    }
    
    // 这个Bean是为了支持在Thymeleaf中使用Shiro标签
    // 如果不在Thymeleaf中使用Shiro标签,那么可以不提供 ShiroDialect
    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }
}

代码解释:

  • 这里提供两个 关键Bean,一个是Realm,另一个是ShiroFilterChainDefinition.至于ShiroDialect,则是为了支持在Thymeleaf中使用Shiro 标签,如果不在Thymeleaf中使用Shiro标签,那么可以不提供ShiroDialect.
  • Realm 可以是自定义Realm,也可以是Shiro 提供的Realm,简单起见,本案例没有配置数据库连接,这里直接配置了两个用户: sang/123 和admin/123,分别对应角色user和admin,user具有read权限,admin 则具有read、 write 权限。
  • ShiroFilterChainDefinition Bean 中配置了基本的过滤规则,“/login” 和“/doLogin” 可以匿名访问,“https://blog.csdn.net/logout” 是一个注销登录请求,其余请求则都需要认证后才能访问。

接下来配置登录接口以及页面访问接口,代码如下:

@Controller
public class UserController {

    // 登录接口
    @PostMapping("/doLogin")
    public String doLogin(String username, String password, Model model) {
        // 通过接收到的用户名和密码构造一个 UsernamePasswordToken 实例
        UsernamePasswordToken token =
                new UsernamePasswordToken(username, password);
        // 获取一个Subject对象
        Subject subject = SecurityUtils.getSubject();
        try {
            // 执行登录操作
            subject.login(token);
        } catch (AuthenticationException e) {
            // 登录操作执行过程中,当有异常抛出时,说明登录失败,携带错误信息返回登录视图
            model.addAttribute("error", "用户名或密码输入错误!");
            return "login";
        }
        // 当登录成功时,则重定向到"/index"
        return "redirect:/index";
    }

    // 暴露"https://blog.csdn.net/admin"接口,并且该接口需要具有admin角色才能访问
    @RequiresRoles("admin")
    @GetMapping("https://blog.csdn.net/admin")
    public String admin() {
        return "admin";
    }

    // 暴露"https://blog.csdn.net/user"接口,并且该接口只要有admin或者user角色就能访问
    @RequiresRoles(value = {"admin","user"},logical = Logical.OR)
    @GetMapping("https://blog.csdn.net/user")
    public String user() {
        return "user";
    }
}

代码解释:

  • 在doLogin方法中,首先构造一个UsermamePasswordToken实例,然后获取一个Subject对象并调用该对象中的login 方法执行登录操作,在登录操作执行过程中,当有异常抛出时, 说明登录失败,携带错误信息返回登录视图;当登录成功时,则重定向到“/index" 。
  • 接下来暴露两个接口“https://blog.csdn.net/admin” 和“https://blog.csdn.net/user”, 对于“https://blog.csdn.net/admin” 接口,需要具有admin角色才可以访问;对于“https://blog.csdn.net/user” 接口,具备admin角色和user角色其中任意一个即可访问。

对于其他不需要角色就能访问的接口,直接在WebMvc中配置即可,代码如下:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");
        registry.addViewController("/index").setViewName("index");
        registry.addViewController("/unauthorized").setViewName("unauthorized");
    }
}

接下来创建全局异常处理器进行全局异常处理,本案例主要是处理授权异常,代码如下:

@ControllerAdvice
public class ExceptionController {
    // 当用户访问未授权的资源时,跳转到 unauthorized 视图,并携带出错信息
    @ExceptionHandler(AuthorizationException.class)
    public ModelAndView error(AuthorizationException e) {
        ModelAndView mv = new ModelAndView("unauthorized");
        mv.addObject("error", e.getMessage());
        return mv;
    }
}

当用户访问未授权的资源时,跳转到unauthorized视图中,并携带出错信息。

配置完成后,最后在resources/templates目录下创建5个HTML页面进行测试。

(1) index.html, 代码如下:




    
    Title


Hello,

注销登录

管理员页面

普通用户页面

index.html是登录成功后的首页,首先展示当前登录用户的用户名,然后展示一个“注销登录”链接,若当前登录用户具备“admin”角色,则展示一个“管理员页面”的超链接;若用户具备“admin”或者“user”角色,则展示一个“普通用户页面”的超链接。注意这里导入的名称空间是
xmlns:shiro=“http://www.pollix.at/thymeleaf/shiro”,和JSP中导入的Shiro名称空间不一致。

(2) login.html, 代码如下:




    
    Title




login.html是一个普通的登录页面,在登录失败时通过一个 div显示登录失败信息。

(3) user.html,代码如下:




    
    Title


普通用户页面

user.html是一个普通的用户信息展示页面。

(4)admin.html,代码如下:




    
    Title


管理员页面

admin.html是一个普通的管理员信息展示页面。

(5) unauthorized.html, 代码如下:




    
    Title


未获授权,非法访问

unauthorized.html是一个授权失败的展示页面,该页面还会展示授权出错的信息。

2.3 测试

配置完成后,启动Spring Boot项目,访问登录页面,分别使用sang/123和admin/123登录,结果如图所示。注意,因为hangge用户不具备admin角色,因此登录成功后的页面上没有前往管理员页面的超链接。

登录成功后,无论是hangge还是admin用户,单击“注销登录”都会注销成功,然后回到登录页面,hangge 用户因为不具备admin 角色,因此没有“管理员页面”的超链接,无法进入管理员页面中,此时,若用户使用sang用户登录,然后手动在地址栏输入http://localhost:8080https://blog.csdn.net/admin ,则会跳转到未授权页面,如图所示。

以上通过一个简单的案例向读者展示了如何在SpringBoot中整合Shiro以及如何在Thymeleaf中使用Shiro标签,一旦整合成功,接下来Shiro的用法就和原来的一模一样。本小节主要介绍SpringBoot整合Shiro,对于Shiro的其他用法,读者可以参考Shiro官方文档,这里不再赘述。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/886039.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号