springboot整合Shiro实现登录认证和授权
时间: 2024-12-19 12:21:57 浏览: 25
### SpringBoot 整合 Shiro 实现登录认证和授权
#### 项目概述
本项目使用 Spring Boot 3.2.11 和 Apache Shiro 2.0.1 实现用户的登录认证和授权功能。项目包括数据库连接、用户实体类、MyBatis 映射、Shiro 配置以及前端页面等部分。
#### 项目步骤
1. **数据库准备**
- 使用 `mybatis07.sql` 文件创建数据库和数据表。如果之前已完成,无需重复操作。
2. **项目搭建**
- 创建 Maven 工程 `unit7my02shiro`,版本为 3.2.11。
- 编辑 `pom.xml` 文件,添加必要的依赖项,包括 Shiro、MyBatis、MySQL 驱动、Druid、Thymeleaf 等。
3. **配置文件**
- `application.yml` 配置数据库连接和 Druid 数据源。
- `application.properties` 配置 MyBatis。
4. **实体类和映射**
- 创建 `User` 实体类。
- 创建 `UserMapper` 接口和对应的 XML 映射文件 `UserMapper.xml`。
5. **业务逻辑**
- 创建 `UserService` 接口和 `UserServiceImpl` 实现类,提供查询用户的方法。
6. **Shiro 配置**
- 创建 `UserRealm` 类,实现用户登录认证和授权逻辑。
- 创建 `ShiroConfig` 类,配置 Shiro 的 Filter 和 SecurityManager。
7. **前端页面**
- 在 `resources/templates` 目录下创建 `index.html` 和 `login.html` 页面,使用 Thymeleaf 模板引擎。
- 添加 Thymeleaf-Shiro 依赖,并配置 `ShiroDialect`。
8. **Controller**
- 创建 `MyController` 类,处理主页、登录、登出及授权相关请求。
- 添加 `doLogin` 方法处理登录逻辑,捕获异常并返回相应的提示信息。
- 添加 `toAdd` 和 `toDelete` 方法,分别跳转到添加和删除页面。
9. **授权配置**
- 修改 `ShiroConfig` 类中的 `getShiroFilterFactoryBean` 方法,添加权限过滤规则。
- 在 `UserRealm` 类的 `doGetAuthorizationInfo` 方法中添加授权逻辑。
- 在 `index.html` 中添加带有权限控制的超链接。
#### 示例代码片段
**pom.xml**
```xml
<dependencies>
<!-- Shiro 和 Spring 整合的依赖 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<classifier>jakarta</classifier>
<version>2.0.1</version>
</dependency>
<!-- 其他依赖省略 -->
</dependencies>
```
**application.yml**
```yaml
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/mybatis07?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
```
**User.java**
```java
package com.my.yanli.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@Data
public class User {
private int id;
private String name;
private String pwd;
private String perms;
}
```
**UserMapper.java**
```java
package com.my.yanli.mapper;
import com.my.yanli.pojo.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper {
User findUserByName(String uname);
}
```
**UserMapper.xml**
```xml
<mapper namespace="com.my.yanli.mapper.UserMapper">
<select id="findUserByName" resultType="User">
select * from t_user where name like #{uname}
</select>
</mapper>
```
**UserRealm.java**
```java
package com.my.yanli.config;
import com.my.yanli.pojo.User;
import com.my.yanli.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.subject.Subject;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了 ==== 》用户授权");
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行了 === 》登录认证");
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
User user = userService.findUserByName(token.getUsername());
if (user == null) {
return null;
}
Subject subject = SecurityUtils.getSubject();
subject.getSession().setAttribute("loginUser", user);
return new SimpleAuthenticationInfo(user, user.getPwd(), "");
}
}
```
**ShiroConfig.java**
```java
package com.my.yanli.config;
import com.my.yanli.config.UserRealm;
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;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(defaultWebSecurityManager);
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/user/add", "perms[user:add]");
filterMap.put("/user/delete", "perms[user:delete]");
bean.setFilterChainDefinitionMap(filterMap);
bean.setLoginUrl("/login");
bean.setUnauthorizedUrl("/noauth");
return bean;
}
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm);
return securityManager;
}
@Bean
public UserRealm userRealm() {
return new UserRealm();
}
@Bean
public ShiroDialect getShiroDialect() {
return new ShiroDialect();
}
}
```
通过以上步骤,您可以实现一个基本的 Spring Boot + Shiro 的登录认证和授权系统。
阅读全文