Springboot整合Shiro之认证
Shiro
是我们常用的一个权限管理框架,我们之前已经详细的给大家介绍过了Shiro的基础知识,不太清楚的可以参考下 https://blog.csdn.net/qq_38526573/category_9284714.html 此文,本文的重点是来介绍下在SpringBoot环境下我们怎么来使用Shiro。
一、添加相关依赖
本案例中我们使用SpringDataJPA
和Thymeleaf
来配合讲解,所以相关的依赖如下
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!-- springBoot的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
二、添加相关的配置信息
在application.properties中添加如下的配置信息
# jdbc 的相关信息
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/srm?characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456
# 配置连接池信息
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
# 配置jpa的相关参数
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
三、业务准备
我们提前将登录认证的后台业务先完成。我们提前将登录认证的后台业务先完成。
1.对应的表结构
CREATE TABLE `t_user` (
`id` int(20) NOT NULL AUTO_INCREMENT,
`username` varchar(20) DEFAULT NULL,
`password` varchar(100) DEFAULT NULL,
`salt` varchar(100) DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
`state` int(1) DEFAULT NULL,
`last_login_time` datetime DEFAULT NULL,
`nickname` varchar(30) DEFAULT NULL,
`realname` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
2.pojo对象
package com.dpb.springboot41shiro.pojo;
import javax.persistence.*;
/**
* @program: springboot-41-shiro
* @description:
* @author: 波波烤鸭
* @create: 2019-11-29 20:06
*/
@Entity
@Table(name = "t_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "username")
private String username;
@Column(name = "password")
private String password;
@Column(name = "salt")
private String salt;
@Column(name = "realname")
private String realname;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
public String getRealname() {
return realname;
}
public void setRealname(String realname) {
this.realname = realname;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
3.dao接口
接口我们通过 JpaRepository接口来实现,然后根据名称规则来定义方法
public interface UserDao extends JpaRepository<User,Integer> {
/**
* 根据账号查询
* @param username
* @return
*/
List<User> findByUsername(String username);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
4.业务层代码
业务层就实现简单的调用即可
四、Shiro整合
接下来我们就可以来整合Shiro框架了
1.自定义Realm文件
首先我们定义一个realm实现类来实现我们认证和授权的逻辑
package com.dpb.springboot41shiro.realm;
import com.dpb.springboot41shiro.pojo.User;
import com.dpb.springboot41shiro.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.SimpleByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/**
* @program: springboot-41-shiro
* @description: 自定义Realm
* @author: 波波烤鸭
* @create: 2019-11-29 19:37
*/
public class AuthcRealm extends AuthorizingRealm {
/**
* 认证的方法
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
return null;
}
/**
* 授权的方法
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
逻辑可以稍后实现
2.Shiro的配置类
我们先来看下之前在spring整合shiro的时候,我们的整合配置文件:
那么我们在SpringBoot中只需将此配置转换为对应的java配置即可,如下
package com.dpb.springboot41shiro.config;
import com.dpb.springboot41shiro.realm.AuthcRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* @program: springboot-41-shiro
* @description: Shiro的配置类
* @author: 波波烤鸭
* @create: 2019-11-29 19:31
*/
@Configuration
public class ShiroConfig {
@Value("${shiro.hashAlgorithmName}")
private String hashAlgorithmName;
@Value("${shiro.hashIterations}")
private Integer hashIterations;
/**
* 获取凭证匹配器
* @return
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher(){
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
matcher.setHashAlgorithmName(hashAlgorithmName);
matcher.setHashIterations(hashIterations);
return matcher;
}
/**
* 获取自定义的Realm
* @return
*/
@Bean
public AuthcRealm authcRealm(){
AuthcRealm realm = new AuthcRealm();
realm.setCredentialsMatcher(hashedCredentialsMatcher());
return realm;
}
/**
* 获取SecurityManager对象
* @return
*/
@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(authcRealm());
return manager;
}
/**
* 注册ShiroFilterFactoryBean
* @return
*/
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager manager){
ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
filter.setSecurityManager(manager);
filter.setLoginUrl("/login.do");
filter.setSuccessUrl("/success.html");
filter.setUnauthorizedUrl("/refuse.html");
// 设置过滤器
Map<String,String> map = new HashMap<>();
map.put("/css/**","anon");
map.put("/img/**","anon");
map.put("/js/**","anon");
map.put("/login","anon");
map.put("/login.do","authc");
map.put("/**","authc");
filter.setFilterChainDefinitionMap(map);
return filter;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
3.访问测试
到此shiro已经被集成到了我们项目中,我们可以根据我们配置的过滤链路来启动访问下,首先创建如下的相关文件,便于测试
同时添加对应的跳转控制器
/**
* @program: springboot-41-shiro
* @description: 基础控制器
* @author: 波波烤鸭
* @create: 2019-11-29 19:52
*/
@Controller
public class BaseController {
@RequestMapping("/{path}")
public String page(@PathVariable String path){
return path;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
访问需要认证的success.html ,会给错误提示
访问img/a2.jpg可以直接访问
五、登录认证测试
接下来我们实现下认证的过程。
1.自定义realm实现登录
自定义realm认证的流程如下
@Autowired
private UserService service;
/**
* 认证的方法
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
String userName = token.getUsername();
System.out.println("开始登录认证:"+userName);
List<User> list = service.login(userName);
if (list == null || list.size() != 1) {
return null;
}
User user = list.get(0);
return new SimpleAuthenticationInfo(user,user.getPassword(),new SimpleByteSource(user.getSalt()),"authcRealme");
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
2.创建登录表单
前端我们用Thymeleaf来作为模块框架,创建登录表单
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>登录管理</h1>
<form th:action="@{/login.do}" method="post">
账号:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
<input type="submit" value="登录">
</form>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
3.创建认证的控制器
同时我们创建认证的控制器,来处理认证失败的情况
package com.dpb.springboot41shiro.controller;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
/**
* @program: springboot-41-shiro
* @description: 认证的控制器
* @author: 波波烤鸭
* @create: 2019-11-29 20:12
*/
@Controller
public class AuthcController {
@RequestMapping("/login.do")
public String login(HttpServletRequest request){
Object obj = request.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
System.out.println("认证的错误信息:" + obj);
return "/login";
}
/**
* 注销的方法
* @return
*/
@RequestMapping("/logout.do")
public String logout(){
SecurityUtils.getSubject().logout();
return "redirect:/login";
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
4.准备数据
我们可以自己通过Md5加密一个密码然后保存到数据库中
5.测试
到此启动项目,登录测试即可
最后项目的目录结构如下:
文章来源: dpb-bobokaoya-sm.blog.csdn.net,作者:波波烤鸭,版权归原作者所有,如需转载,请联系作者。
原文链接:dpb-bobokaoya-sm.blog.csdn.net/article/details/103322744
- 点赞
- 收藏
- 关注作者
评论(0)