若依框架(RuoYi)是一个基于Spring Boot的快速开发平台,其内置了模块化设计和权限管理功能。为了进一步增强系统的安全性,可以将Spring Security集成到若依框架中,实现更强大的认证与授权功能。本文将详细介绍如何在若依框架中集成Spring Security,并实现用户认证和权限控制。
Spring Security 是一个功能强大的安全框架,提供了认证(Authentication)和授权(Authorization)的核心功能。它通过过滤器链机制拦截请求,并根据配置的安全策略对请求进行处理。
首先,在pom.xml
文件中引入Spring Security相关的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
若依框架本身已经集成了部分安全功能,因此需要确保Spring Security的版本与若依框架兼容。
创建一个自定义的WebSecurityConfigurerAdapter
类,用于配置Spring Security的行为:
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// 关闭csrf防护
http.csrf().disable()
.authorizeRequests()
.antMatchers("/login", "/logout", "/css/**", "/js/**", "/images/**").permitAll() // 允许访问公共资源
.anyRequest().authenticated() // 其他所有请求都需要认证
.and()
.formLogin()
.loginPage("/login") // 自定义登录页面
.defaultSuccessUrl("/") // 登录成功后的默认跳转页面
.and()
.logout()
.logoutUrl("/logout") // 登出URL
.invalidateHttpSession(true); // 注销时清除session
}
}
Spring Security通过UserDetailsService
接口获取用户信息。我们需要实现该接口,并结合若依框架的数据库结构返回用户数据。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.service.ISysUserService;
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private ISysUserService userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
SysUser user = userService.selectUserByUserName(username);
if (user == null) {
throw new UsernameNotFoundException("用户不存在");
}
return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassword(), AuthorityUtils.createAuthorityList("ROLE_USER"));
}
}
若依框架中的权限控制通常是基于角色或菜单的。我们可以通过Spring Security的@PreAuthorize
注解来实现细粒度的权限控制。
例如,限制某个方法只能由管理员访问:
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@GetMapping("/admin")
@PreAuthorize("hasRole('ADMIN')")
public String adminAccess() {
return "只有管理员可以访问";
}
@GetMapping("/user")
@PreAuthorize("hasRole('USER')")
public String userAccess() {
return "普通用户可以访问";
}
}
以下是Spring Security在若依框架中的认证与授权流程图:
sequenceDiagram participant User as 用户 participant FilterChain as Spring Security过滤器链 participant UserService as 自定义UserDetailsService participant Controller as 控制器 User->>FilterChain: 发起请求 FilterChain->>FilterChain: 检查是否已认证 alt 未认证 FilterChain->>UserService: 调用loadUserByUsername加载用户信息 UserService-->>FilterChain: 返回用户信息 FilterChain->>User: 跳转至登录页面 else 已认证 FilterChain->>Controller: 放行请求 Controller-->>User: 返回响应 end