spring boot整合Shiro实现单点登录的示例代码

下面是关于“spring boot整合Shiro实现单点登录的示例代码”的详细攻略。

环境准备

首先,我们需要准备以下环境:

  • JDK 8
  • Maven
  • IDE:Eclipse 或者 Intellij IDEA

在环境准备完成后,我们接下来需要进行以下的准备工作。

创建Spring Boot工程

我们可以通过Maven快速构建一个Spring Boot应用程序,然后加上Shiro依赖即可。

  1. 打开Eclipse或者Intellij IDEA,创建一个普通的Maven工程;
  2. 在pom.xml文件中添加以下的Spring Boot依赖:
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
   <groupId>org.apache.shiro</groupId>
   <artifactId>shiro-spring</artifactId>
   <version>1.4.0</version>
</dependency>
  1. 执行命令 mvn clean install 完成依赖的下载

Shiro基本配置

接下来,我们需要进行Shiro的基本配置

  1. 创建ShiroConfig类

在src/main/java下创建一个ShiroConfig类

@Configuration
public class ShiroConfig {
    /**
     * 配置Shiro到Spring容器
     * @param securityManager
     * @return
     */
    @Bean(name = "shiroFilter")
    protected ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //声明securityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //注册authcFilter过滤器
        Map<String, Filter> filters = new LinkedHashMap<>();
        filters.put("authc", authcFilter());
        shiroFilterFactoryBean.setFilters(filters);

        //为URL设置访问所需要的角色
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        filterChainDefinitionMap.put("/logout", "logout");
        filterChainDefinitionMap.put("/login", "authc");
        filterChainDefinitionMap.put("/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        shiroFilterFactoryBean.setLoginUrl("/login");

        return shiroFilterFactoryBean;
    }

    /**
     * 创建securityManager
     *
     * @return
     */
    @Bean(name = "securityManager")
    protected DefaultWebSecurityManager defaultWebSecurityManager(UserRealm bean) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //注入Realm
        securityManager.setRealm(bean);
        return securityManager;
    }

    /**
     * 创建Realm
     *
     * @return
     */
    @Bean(name = "realm")
    public UserRealm userRealm() {
        return new UserRealm();
    }

    /**
     * 注册authcFilter过滤器
     * @return
     */
    @Bean(name = "authc")
    public AuthenticationFilter authcFilter() {
        UsernamePasswordAuthenticationFilter authcFilter = new UsernamePasswordAuthenticationFilter();
        authcFilter.setLoginUrl("/login");
        return authcFilter;
    }
}
  1. 创建一个UserRealm类

在src/main/java下创建一个UserRealm类:

public class UserRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        User user = (User) principalCollection.getPrimaryPrincipal();

        //获取角色ResouceCode关联信息
        List<ResouceCode> resouceCodeList = userService.selectResourceCodeList(user.getUserName());
        //将role和url加入到授权对象中
        if (resouceCodeList != null && resouceCodeList.size() > 0) {
            for (ResouceCode resouceCode : resouceCodeList) {
                authorizationInfo.addRole(resouceCode.getRoleCode().toUpperCase());
                authorizationInfo.addStringPermission(resouceCode.getResCode().toLowerCase());
            }
        }

        return authorizationInfo;
    }

    /**
     * 验证 登录
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken;
        String username = usernamePasswordToken.getUsername();
        if (StringUtils.isBlank(username)) {
            return null;
        }

        User user = userService.selectUserByUserName(username);
        if (user == null) {
            return null;
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getCredentialsSalt()), getName());

        return authenticationInfo;
    }
}

编写Controller和View

接下来,我们需要编写Controller和View

  1. 添加登录页面

在src/main/resources下创建login.html页面:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登陆</title>
</head>
<body>
<div>
<form method="post" th:action="@{/login}">
<div>
<label>用户名: <input type="text" name="username" required></label>
</div>
<div>
<label>密码: <input type="password" name="password" required></label>
</div>
<div><input type="submit" value="登陆"></div>
</form>
</div>
</body>
</html>
  1. 创建HomeController类

在src/main/java下创建一个HomeController类,实现登录成功后的跳转:

@Controller
public class HomeController {

    /**
     * 登录成功后跳转到主页面
     *
     * @return
     */
    @RequestMapping("/home")
    public String home() {
        return "/views/home";
    }
}
  1. 创建IndexController类

在src/main/java下创建一个IndexController类,实现登录和退出:

@Controller
public class IndexController {

    /**
     * 登录
     *
     * @return
     */
    @RequestMapping("/login")
    public String login() {
        return "/views/login";
    }

    /**
     * 退出
     *
     * @return
     */
    @RequestMapping("/logout")
    public String logout() {
        SecurityUtils.getSubject().logout();
        return "redirect:/login";
    }
}
  1. 创建Home页面

在src/main/resources/views下创建一个home.html页面,实现登录验证后的统一页面:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>首页</title>
</head>
<body>
<h1>欢迎访问首页</h1>
</body>
</html>

两个示例说明

下面我们演示两个Shiro单点登录的应用:

示例一:普通登录

  1. 在浏览器中输入网址 http://localhost:8080/login,会跳转到登录页面;
  2. 在登录页面中输入用户名和密码,点击“登陆”,会跳转到应用的首页:http://localhost:8080/home,同时在请求头中设置了Cookie;
  3. 访问 http://localhost:8080/home,会发现并没有被拦截,说明登录成功;

示例二:多个应用的单点登录

假设有两个应用APP1和APP2,在浏览器中访问APP1,然后跳转到APP2,由于已经实现了Shiro单点登录,所以在访问APP2时,就无需再次输入用户名和密码。

  1. 访问APP1,执行登录操作,成功登录;
  2. 在APP1的页面上添加访问APP2页面的链接,并设置URL为APP2的登录页面URL;
  3. 点击APP2的链接,跳转到APP2的登录页面,此时我们并不需要再次输入用户名和密码;
  4. 点击APP2的首页链接,会发现并没有被拦截,说明登录成功。

总结

至此,我们已经完成了Spring Boot整合Shiro实现单点登录的示例代码。需要注意的是,这里的示例是最基本的示例,如果想要在实际应用中使用,还需要根据实际情况进行具体的配置和开发。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:spring boot整合Shiro实现单点登录的示例代码 - Python技术站

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

相关文章

  • SpringBoot 的 web 类型推断详解

    Spring Boot是一个快速开发框架,可以帮助开发人员快速构建Web应用程序。在开发过程中,经常需要处理HTTP请求和响应。为了简化开发,Spring Boot提供了Web类型推断功能,可以自动推断HTTP请求和响应的类型。本文将介绍Spring Boot的Web类型推断功能,并提供两个示例。 什么是Web类型推断? Web类型推断是Spring Boo…

    Java 2023年5月15日
    00
  • SpringBoot整合mybatis的方法详解

    下面我来为你详细讲解“SpringBoot整合mybatis的方法详解”的完整攻略。 准备工作 在maven中引入spring-boot-starter-jdbc、mybatis-spring-boot-starter、mysql-connector-java等依赖。 在application.properties中配置数据库信息和mybatis配置。 sp…

    Java 2023年5月19日
    00
  • Spring Boot整合Bootstrap的超详细步骤

    下面是“Spring Boot整合Bootstrap的超详细步骤”完整攻略: 1. 引入Bootstrap资源 首先,在你的Web项目中引入Bootstrap资源,具体来说,就是将Bootstrap的CSS、JS等文件引入到项目中。你可以通过下载Bootstrap的官方资源文件并手工进行配置,也可以直接使用CDN引入。 下面示例展示了通过CDN直接引入Boo…

    Java 2023年5月15日
    00
  • Spring MVC官方文档学习笔记(一)之Web入门

    注: 该章节主要为原创内容,为后续的Spring MVC内容做一个先行铺垫 1.Servlet的构建使用 (1) 选择Maven -> webapp来构建一个web应用 (2) 构建好后,打开pom.xml文件,一要注意打包方式为war包,二导入servlet依赖,如下 <!– 打war包 –> <packaging>war…

    Java 2023年5月11日
    00
  • Java由浅入深细数数组的操作上

    Java数组操作完整攻略 一、数组概述 Java数组是一种包含固定数量元素的数据结构,这些元素属于同一种数据类型。 Java数组由以下几个基本点组成: 数组声明 数组的创建 数组的初始化 数组的访问 数组的遍历 二、数组的声明 Java中数组的声明包含两个重要的部分,第一部分是数组的类型,第二部分是数组的名字。如下所示: int[] arr; //第一种声明…

    Java 2023年5月26日
    00
  • 面向对象程序设计

    OOP 【面向对象程序设计】(OOP)与【面向过程程序设计】在思维方式上存在着很大的差别。【面向过程程序设计】中,算法是第一位的,数据结构是第二位的,这就明确地表述了程序员的工作方式。首先要确定如何操作数据,然后再决定如何组织数据,以便于数据操作。而【面向对象程序设计】却调换了这个次序,【面向对象程序设计】将数据放在第一位,然后再考虑操作数据的算法。 对于一…

    Java 2023年4月18日
    00
  • Jsp敏感词过滤的示例代码

    下面是关于 “JSP敏感词过滤的示例代码” 的完整攻略: 1. 什么是敏感词过滤? 在网站开发中,为了防止用户输入敏感词汇或者不良言论,常常需要对用户输入的内容进行敏感词过滤。敏感词过滤主要是通过程序对用户输入内容进行检查,然后对其中的敏感词进行替换或者屏蔽处理,从而保证网站的安全性和健康性。 2. 如何在JSP中实现敏感词过滤? JSP虽然不是一个专门用来…

    Java 2023年6月15日
    00
  • java compare compareTo方法区别详解

    Java CompareTo方法区别详解 什么是Java CompareTo方法? CompareTo()是Java中一个比较方法,用于对两个对象进行比较。在Java中,对象可以比较大小。如果Object A比Object B大,则compareTo()会返回一个正值。如果Object A比Object B小,则compareTo()会返回一个负的值。如果两…

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