spring boot+spring security实现多租户的java代码
时间: 2023-07-11 18:37:03 浏览: 257
以下是使用 Spring Boot + Spring Security 实现多租户的 Java 代码示例:
1. 自定义 UserDetails 类,实现 UserDetails 接口。
```java
public class CustomUserDetails implements UserDetails {
private String username;
private String password;
private List<GrantedAuthority> authorities;
private String tenantId;
// 省略构造函数和 getter/setter 方法
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
public String getTenantId() {
return tenantId;
}
public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}
}
```
2. 自定义 UserDetailsService,从不同的数据源中加载用户信息。
```java
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User not found");
}
CustomUserDetails userDetails = new CustomUserDetails();
userDetails.setUsername(user.getUsername());
userDetails.setPassword(user.getPassword());
userDetails.setTenantId(user.getTenantId());
List<GrantedAuthority> authorities = new ArrayList<>();
for (Role role : user.getRoles()) {
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
userDetails.setAuthorities(authorities);
return userDetails;
}
}
```
3. 自定义 Filter,在请求进入应用程序之前,从请求中获取租户信息,并将其存储在 ThreadLocal 中。
```java
public class TenantFilter extends OncePerRequestFilter {
private static final String TENANT_HEADER = "X-TenantID";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String tenantId = request.getHeader(TENANT_HEADER);
if (StringUtils.isEmpty(tenantId)) {
throw new ServletException("Missing X-TenantID header");
}
TenantContext.setCurrentTenant(tenantId);
filterChain.doFilter(request, response);
}
}
```
4. 自定义 TenantContext,将当前租户信息存储在 ThreadLocal 中。
```java
public class TenantContext {
private static final ThreadLocal<String> currentTenant = new ThreadLocal<>();
public static void setCurrentTenant(String tenantId) {
currentTenant.set(tenantId);
}
public static String getCurrentTenant() {
return currentTenant.get();
}
public static void clear() {
currentTenant.remove();
}
}
```
5. 自定义 AuthenticationProvider,从当前租户的数据源中加载用户信息。
```java
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
private UserDetailsService userDetailsService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
CustomUserDetails userDetails = (CustomUserDetails) userDetailsService.loadUserByUsername(username);
if (!password.equals(userDetails.getPassword())) {
throw new BadCredentialsException("Bad credentials");
}
TenantContext.setCurrentTenant(userDetails.getTenantId());
return new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities());
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
```
6. 在 WebSecurityConfigurerAdapter 中配置多租户的认证和授权。
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomAuthenticationProvider authenticationProvider;
@Autowired
private CustomUserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
auth.userDetailsService(userDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/public/**").permitAll()
.antMatchers("/private/**").authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/private/dashboard")
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
.and()
.addFilterBefore(new TenantFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
```
以上是使用 Spring Boot + Spring Security 实现多租户的 Java 代码示例,其中 CustomUserDetails、CustomUserDetailsService、CustomAuthenticationProvider 和 TenantContext 都需要根据具体业务场景进行定制。
阅读全文