SpringBoot与Shiro整合

修改pom.xml:


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<!-- 继承Spring Boot的默认父工程 -->

<!-- Spring Boot 父工程 -->

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>1.5.4.RELEASE</version>

</parent>

<groupId>com.mxj</groupId>

<artifactId>springboot-shiro</artifactId>

<version>0.0.1-SNAPSHOT</version>

</project>

1.1. 导入web支持

修改pom.xml


<!-- 导入依赖 -->

<dependencies>

<!-- 导入web支持:SpringMVC开发支持,Servlet相关的程序 -->

<!-- web支持,SpringMVC, Servlet支持等 -->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

</dependencies>

1.2. 编写测试Controller类


package com.mxj.controller;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

@Controller

public class UserController {

/**

* 测试方法

*/

@RequestMapping("/hello")

@ResponseBody

public String hello(){

System.out.println("UserController.hello()");

return "ok";

}

}

1.3. 编写SpringBoot启动类


package com.mxj;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

/**

* SpringBoot启动类

* @author MA

*

*/

@SpringBootApplication

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}

1.4. 导入thymeleaf页面模块

l 引入thymeleaf依赖


<!-- 导入thymeleaf依赖 -->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-thymeleaf</artifactId>

</dependency>

l 在Controller添加测试方法


/**

* 测试thymeleaf

*/

@RequestMapping("/testThymeleaf")

public String testThymeleaf(Model model){

//把数据存入model

model.addAttribute("name", "mxj");

//返回test.html

return "test";

}

l 建立test.html页面

在src/main/resource目录下创建templates目录,然后创建test.html页面


<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>测试Thymeleaf的使用</title>

</head>

<body>

<h3 th:text="${name}"></h3>

</body>

</html>

在thymeleaf3.0以前对页面标签语法要求比较严格,开始标签必须有对应的结束标签。

如果希望页面语法不严谨,但是也能够运行成功,可以把thymeleaf升级为3.0或以上版本。

升级thymeleaf3.0.2版本:


<!-- 修改参数 -->

<properties>

<!-- 修改JDK的编译版本为1.8 -->

<java.version>1.8</java.version>

<!-- 修改thymeleaf的版本 -->

<thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>

<thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.version>

</properties>

2. Spring Boot与Shiro整合实现用户认证

2.1. 分析Shiro的核心API

Subject: 用户主体(把操作交给SecurityManager)

SecurityManager:安全管理器(关联Realm)

Realm:Shiro连接数据的桥梁

2.2. Spring Boot整合Shiro

2.2.1. 导入shiro与spring整合依赖

修改pom.xml


<!-- shiro与spring整合依赖 -->

<dependency>

<groupId>org.apache.shiro</groupId>

<artifactId>shiro-spring</artifactId>

<version>1.4.0</version>

</dependency>

2.2.2. 自定义Realm类


package com.mxj.shiro;

import org.apache.shiro.authc.AuthenticationException;

import org.apache.shiro.authc.AuthenticationInfo;

import org.apache.shiro.authc.AuthenticationToken;

import org.apache.shiro.authz.AuthorizationInfo;

import org.apache.shiro.realm.AuthorizingRealm;

import org.apache.shiro.subject.PrincipalCollection;

/**

* 自定义Realm

* @author MA

*

*/

public class UserRealm extends AuthorizingRealm{

/**

* 执行授权逻辑

*/

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {

System.out.println("执行授权逻辑");

return null;

}

/**

* 执行认证逻辑

*/

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {

System.out.println("执行认证逻辑");

return null;

}

}

2.2.3. 编写Shiro配置类(*)


package com.mxj.shiro;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;

import org.apache.shiro.web.mgt.DefaultWebSecurityManager;

import org.springframework.beans.factory.annotation.Qualifier;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

/**

* Shiro的配置类

* @author MA

*

*/

@Configuration

public class ShiroConfig {

/**

* 创建ShiroFilterFactoryBean

*/

@Bean

public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){

ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

//设置安全管理器

shiroFilterFactoryBean.setSecurityManager(securityManager);

return shiroFilterFactoryBean;

}

/**

* 创建DefaultWebSecurityManager

*/

@Bean(name="securityManager")

public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){

DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();

//关联realm

securityManager.setRealm(userRealm);

return securityManager;

}

/**

* 创建Realm

*/

@Bean(name="userRealm")

public UserRealm getRealm(){

return new UserRealm();

}

}

2.3. 使用Shiro内置过滤器实现页面拦截


package com.mxj.shiro;

import java.util.LinkedHashMap;

import java.util.Map;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;

import org.apache.shiro.web.mgt.DefaultWebSecurityManager;

import org.springframework.beans.factory.annotation.Qualifier;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

/**

* Shiro的配置类

* @author MA

*

*/

@Configuration

public class ShiroConfig {

/**

* 创建ShiroFilterFactoryBean

*/

@Bean

public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){

ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

//设置安全管理器

shiroFilterFactoryBean.setSecurityManager(securityManager);

//添加Shiro内置过滤器

/**

* Shiro内置过滤器,可以实现权限相关的拦截器

*    常用的过滤器:

*       anon: 无需认证(登录)可以访问

*       authc: 必须认证才可以访问

*       user: 如果使用rememberMe的功能可以直接访问

*       perms: 该资源必须得到资源权限才可以访问

*       role: 该资源必须得到角色权限才可以访问

*/

Map<String,String> filterMap = new LinkedHashMap<String,String>();

/*filterMap.put("/add", "authc");

filterMap.put("/update", "authc");*/

filterMap.put("/testThymeleaf", "anon");

filterMap.put("/*", "authc");

//修改调整的登录页面

shiroFilterFactoryBean.setLoginUrl("/toLogin");

shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);

return shiroFilterFactoryBean;

}

/**

* 创建DefaultWebSecurityManager

*/

@Bean(name="securityManager")

public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){

DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();

//关联realm

securityManager.setRealm(userRealm);

return securityManager;

}

/**

* 创建Realm

*/

@Bean(name="userRealm")

public UserRealm getRealm(){

return new UserRealm();

}

}

2.4. 实现用户认证(登录)操作

2.4.1. 设计登录页面


<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>登录页面</title>

</head>

<body>

<h3>登录</h3>

<form method="post" action="login">

用户名:<input type="text" name="name"/><br/>

密码:<input type="password" name="password"/><br/>

<input type="submit" value="登录"/>

</form>

</body>

</html>

2.4.2. 编写Controller的登录逻辑


/**

* 登录逻辑处理

*/

@RequestMapping("/login")

public String login(String name,String password,Model model){

/**

* 使用Shiro编写认证操作

*/

//1.获取Subject

Subject subject = SecurityUtils.getSubject();

//2.封装用户数据

UsernamePasswordToken token = new UsernamePasswordToken(name,password);

//3.执行登录方法

try {

subject.login(token);

//登录成功

//跳转到test.html

return "redirect:/testThymeleaf";

} catch (UnknownAccountException e) {

//e.printStackTrace();

//登录失败:用户名不存在

model.addAttribute("msg", "用户名不存在");

return "login";

}catch (IncorrectCredentialsException e) {

//e.printStackTrace();

//登录失败:密码错误

model.addAttribute("msg", "密码错误");

return "login";

}

}

2.4.3. 编写Realm的判断逻辑


package com.mxj.shiro;

import org.apache.shiro.authc.AuthenticationException;

import org.apache.shiro.authc.AuthenticationInfo;

import org.apache.shiro.authc.AuthenticationToken;

import org.apache.shiro.authc.SimpleAuthenticationInfo;

import org.apache.shiro.authc.UsernamePasswordToken;

import org.apache.shiro.authz.AuthorizationInfo;

import org.apache.shiro.realm.AuthorizingRealm;

import org.apache.shiro.subject.PrincipalCollection;

/**

* 自定义Realm

* @author MA

*

*/

public class UserRealm extends AuthorizingRealm{

/**

* 执行授权逻辑

*/

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {

System.out.println("执行授权逻辑");

return null;

}

/**

* 执行认证逻辑

*/

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {

System.out.println("执行认证逻辑");

//假设数据库的用户名和密码

String name = "eric";

String password = "123456";

//编写shiro判断逻辑,判断用户名和密码

//1.判断用户名

UsernamePasswordToken token = (UsernamePasswordToken)arg0;

if(!token.getUsername().equals(name)){

//用户名不存在

return null;//shiro底层会抛出UnKnowAccountException

}

//2.判断密码

return new SimpleAuthenticationInfo("",password,"");

}

}

2.5. 整合MyBatis实现登录

2.5.1. 导入mybatis相关的依赖


<!-- 导入mybatis相关的依赖 -->

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>druid</artifactId>

<version>1.0.9</version>

</dependency>

<!-- mysql -->

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

</dependency>

<!-- SpringBoot的Mybatis启动器 -->

<dependency>

<groupId>org.mybatis.spring.boot</groupId>

<artifactId>mybatis-spring-boot-starter</artifactId>

<version>1.1.1</version>

</dependency>

2.5.2. 配置application.properties

位置:src/main/resources目录下


spring.datasource.driverClassName=com.mysql.jdbc.Driver

spring.datasource.url=jdbc:mysql://localhost:3306/ssm

spring.datasource.username=root

spring.datasource.password=123456

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

mybatis.type-aliases-package=com.mxj.dao

2.5.3. 编写User实体


package com.mxj.dao;

public class User {

private Integer id;

private String name;

private String password;

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

}

2.5.4. 编写UserMapper接口


package com.mxj.mapper;

import com.itheima.domain.User;

public interface UserMapper {

public User findByName(String name);

}

2.5.5. 编写UserMapper.xml映射文件


<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!-- 该文件存放CRUD的sql语句 -->

<mapper namespace="com.itheima.mapper.UserMapper">

<select id="findByName" parameterType="string" resultType="user">

SELECT id,

NAME,

PASSWORD

FROM

user where name = #{value}

</select>

</mapper>

2.5.6. 编写业务接口和实现

接口:


package com.mxj.service;

import com.itheima.domain.User;

public interface UserService {

public User findByName(String name);

}

实现;


package com.mxj.service.impl;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import com.itheima.domain.User;

import com.itheima.mapper.UserMapper;

import com.itheima.service.UserService;

@Service

public class UserServiceImpl implements UserService{

//注入Mapper接口

@Autowired

private UserMapper userMapper;

@Override

public User findByName(String name) {

return userMapper.findByName(name);

}

}

2.5.7. 添加@MapperScan注解


package com.mxj;

import org.mybatis.spring.annotation.MapperScan;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

/**

* SpringBoot启动类

* @author MA

*

*/

@SpringBootApplication

@MapperScan("com.mxj.mapper")

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}

2.5.8. 修改UserRealm


package com.mxj.shiro;

import org.apache.shiro.authc.AuthenticationException;

import org.apache.shiro.authc.AuthenticationInfo;

import org.apache.shiro.authc.AuthenticationToken;

import org.apache.shiro.authc.SimpleAuthenticationInfo;

import org.apache.shiro.authc.UsernamePasswordToken;

import org.apache.shiro.authz.AuthorizationInfo;

import org.apache.shiro.realm.AuthorizingRealm;

import org.apache.shiro.subject.PrincipalCollection;

import org.springframework.beans.factory.annotation.Autowired;

import com.mxj.dao.User;

import com.mxj.service.UserService;

/**

* 自定义Realm

* @author MA

*

*/

public class UserRealm extends AuthorizingRealm{

/**

* 执行授权逻辑

*/

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {

System.out.println("执行授权逻辑");

return null;

}

@Autowired

private UserService userSerivce;

/**

* 执行认证逻辑

*/

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {

System.out.println("执行认证逻辑");

//编写shiro判断逻辑,判断用户名和密码

//1.判断用户名

UsernamePasswordToken token = (UsernamePasswordToken)arg0;

User user = userSerivce.findByName(token.getUsername());

if(user==null){

//用户名不存在

return null;//shiro底层会抛出UnKnowAccountException

}

//2.判断密码

return new SimpleAuthenticationInfo("user.getName()",user.getPassword(),"");

}

}

3. Spring Boot与Shiro整合实现用户授权

3.1. 使用Shiro内置过滤器拦截资源


/**

* 创建ShiroFilterFactoryBean

*/

@Bean

public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){

ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

//设置安全管理器

shiroFilterFactoryBean.setSecurityManager(securityManager);

//添加Shiro内置过滤器

/**

* Shiro内置过滤器,可以实现权限相关的拦截器

*    常用的过滤器:

*       anon: 无需认证(登录)可以访问

*       authc: 必须认证才可以访问

*       user: 如果使用rememberMe的功能可以直接访问

*       perms: 该资源必须得到资源权限才可以访问

*       role: 该资源必须得到角色权限才可以访问

*/

Map<String,String> filterMap = new LinkedHashMap<String,String>();

/*filterMap.put("/add", "authc");

filterMap.put("/update", "authc");*/

filterMap.put("/testThymeleaf", "anon");

//放行login.html页面

filterMap.put("/login", "anon");

//授权过滤器

//注意:当前授权拦截后,shiro会自动跳转到未授权页面

filterMap.put("/add", "perms[user:add]");

filterMap.put("/*", "authc");

//修改调整的登录页面

shiroFilterFactoryBean.setLoginUrl("/toLogin");

//设置未授权提示页面

shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");

shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);

return shiroFilterFactoryBean;

}

3.2. 完成Shiro的资源授权

UserRealm:


/**
* 执行授权逻辑
* @param principals
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

System.out.println("执行授权逻辑");
//给资源进行授权
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

//添加资源的授权字符串
//info.addStringPermission("user:add");

//到数据库查询当前用户的授权字符串
//获取当前登陆用户
Subject subject = SecurityUtils.getSubject();
String name= (String) subject.getPrincipal();
User user = userService.findByName(name);

info.addStringPermission(user.getPerms());
return info;
}

4.  thymeleaf和shiro标签整合使用

4.1. 导入thymeleaf扩展坐标


<!-- thymel对shiro的扩展坐标 -->

<dependency>

<groupId>com.github.theborakompanioni</groupId>

<artifactId>thymeleaf-extras-shiro</artifactId>

<version>2.0.0</version>

</dependency>

4.2. 配置ShiroDialect

在ShiroConfig类里面添加getShiroDialect方法


/**

* 配置ShiroDialect,用于thymeleaf和shiro标签配合使用

*/

@Bean

public ShiroDialect getShiroDialect(){

return new ShiroDialect();

}

4.3. 在页面上使用shiro标签


<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>测试Thymeleaf的使用</title>

</head>

<body>

<h3 th:text="${name}"></h3>

<hr/>

<div shiro:hasPermission="user:add">

进入用户添加功能: <a href="add">用户添加</a><br/>

</div>

<div shiro:hasPermission="user:update">

进入用户更新功能: <a href="update">用户更新</a><br/>

</div>

<a href="toLogin">登录</a>

</body>

</html>

原文地址:https://www.cnblogs.com/mxj961116/p/11337391.html

时间: 2024-10-24 22:47:27

SpringBoot与Shiro整合的相关文章

springboot,vue,shiro整合 关于登录认证功能

首先是session问题 传统session认证 http协议是一种无状态协议,即浏览器发送请求到服务器,服务器是不知道这个请求是哪个用户发来的.为了让服务器知道请求是哪个用户发来的,需要让用户提供用户名和密码来进行认证.当浏览器第一次访问服务器(假设是登录接口),服务器验证用户名和密码之后,服务器会生成一个sessionid(只有第一次会生成,其它会使用同一个sessionid),并将该session和用户信息关联起来,然后将sessionid返回给浏览器,浏览器收到sessionid保存到C

(四) Session管理 --《springboot与shiro整合》

登录成功后使用Subject.getSession()即可获取会话:其等价于Subject.getSession(true),即如果当前没有创建Session对象会创建一个: 另外Subject.getSession(false),如果当前没有创建Session则返回null(不过默认情况下如果启用会话存储功能的话在创建Subject时会主动创建一个Session). JAVA代码 session.getId(); 获取session唯一id session.getHost(); 获取当前Sub

教你 Shiro 整合 SpringBoot,避开各种坑

最近搞了下 Shiro 安全框架,找了一些网上的博客文章,但是一到自己实现的时候就遇到了各种坑,需要各种查资料看源码以及各种测试. 那么这篇文章就教大家如何将 Shiro 整合到 SpringBoot 中,并避开一些小坑,这次实现了基本的登陆以及角色权限,往后的文章也讲解了其他的功能,如 <教你 Shiro + SpringBoot 整合 JWT> 附上源码:https://github.com/HowieYuan/shiro 依赖包 <dependency> <groupI

Springboot集成Shiro和Cas实现单点登录(服务端篇CAS5)

什么是单点登录? 先说一个需求场景,比如:一个企业的内部有N多个子系统,每个子系统都有一套自己的用户名和密码,那么企业的员工要登录N个子系统,这样一个员工 就要记住N个用户名和密码,就算各个子系统的用户名和密码都是统一的,登录每个子系统都要输入用户名和密码进行登录也是一个繁琐的操作过程,那么单点登录功能由此便应运而生了.单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应

springboot同mybatis整合

springboot和mybatis整合有两种开发模式,首先要做的是配置好开发环境, 实现步骤: 在maven文件pom中配置: 1)SpringBoot同Mybatis整合的依赖. <dependency> <groupId>com.ruijc</groupId> <artifactId>spring-boot-starter-mybatis</artifactId> <version>3.2.2</version> &

shiro整合spring配置

shiro应用到项目中,一般都是通过spring来管理.下面就如何把shiro整理到spring中进行了讲解,及给出了配置的步骤: 一.pom.xml文件配置 本例子主要是介绍maven管理的web项目进行配置介绍,因此,首先需建立好一个maven管理的web项目(可参考本博客创建maven管理的web项目). pom.xml文件配置,主要是添加相关依赖的jar支持.因为整合到spring中需添加spring支持.具体配置参考配置代码: 1 <project xmlns="http://m

Spring+SpringMVC+Hibernate 与 shiro 整合步骤

通过这篇文章你可以了解到: SSH 三大框架(spring + springMVC + Hiberante) 与 shiro 安全验证框架如何整合: 通过一个示例,快速理解 shiro 框架. [TOC] 1. 业务需求分析 用户 N - 角色 N - 权限 N 我们可以想象一下,在平时工作中的职务,比如:业务经理,部门主管等,他们拥有很多的权力,而一个公司中不会只有一个业务经理,也不会只有一个部门主管,如果我们要给不同的人分配职务权力时,每次都是具体的条条框框去分配,人累心也累.而如果我们事先

springboot+mybatis+springmvc整合实例

以往的ssm框架整合通常有两种形式,一种是xml形式,一种是注解形式,不管是xml还是注解,基本都会有一大堆xml标签配置,其中有很多重复性的.springboot带给我们的恰恰是"零配置","零配置"不等于什么也不配置,只是说相对于传统的ssm框架的xml配置或是注解配置,要少的多.作为常规的来说,一个ssm框架整合,拿maven来说,首先在src/main/resource下加入jdbc.properties,spring-mvc.xml,spring-myba

业务逻辑:五、完成认证用户的动态授权功能 六、完成Shiro整合Ehcache缓存权限数据

一. 完成认证用户的动态授权功能 提示:根据当前认证用户查询数据库,获取其对应的权限,为其授权 操作步骤: 在realm的授权方法中通过使用principals对象获取到当前登录用户 创建一个授权信息对象 根据用户查询角色列表,并遍历角色列表 在循环体中将角色关键字添加到授权信息对象的角色属性中 根据用户查询权限列表,并遍历权限列表 在循环体中将权限关键字添加到授权信息对象的权限属性中 在角色与权限service类的根据用户查询角色与权限方法中判断用户是否为系统管理员 如果是系统管理员就查询出所