This commit is contained in:
parent
09bfe63b27
commit
a856062a90
|
|
@ -5,11 +5,15 @@ import com.nimbusds.jose.jwk.RSAKey;
|
|||
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
|
||||
import com.nimbusds.jose.jwk.source.JWKSource;
|
||||
import com.nimbusds.jose.proc.SecurityContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
|
|
@ -49,6 +53,9 @@ import java.util.UUID;
|
|||
@Configuration
|
||||
public class SecurityConfig {
|
||||
|
||||
@Autowired
|
||||
@Lazy
|
||||
AuthenticationProvider tenantAwareAuthenticationProvider;
|
||||
// 自定义认证入口点,保留client_id参数
|
||||
public static class CustomLoginUrlAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {
|
||||
public CustomLoginUrlAuthenticationEntryPoint(String loginFormUrl) {
|
||||
|
|
@ -89,6 +96,7 @@ public class SecurityConfig {
|
|||
@Bean
|
||||
@Order(2)
|
||||
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
|
||||
http
|
||||
.authorizeHttpRequests(authorize ->
|
||||
authorize
|
||||
|
|
@ -115,22 +123,28 @@ public class SecurityConfig {
|
|||
.invalidateHttpSession(true)
|
||||
.deleteCookies("JSESSIONID")
|
||||
.permitAll()
|
||||
);
|
||||
|
||||
)
|
||||
// 添加会话管理配置
|
||||
// .sessionManagement(session -> session
|
||||
// .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
|
||||
// .maximumSessions(1) // 限制每个用户只能有一个会话
|
||||
// )
|
||||
// 添加自定义认证提供者
|
||||
.authenticationProvider(tenantAwareAuthenticationProvider);
|
||||
return http.build();
|
||||
}
|
||||
|
||||
// 用户信息服务(内存存储)
|
||||
@Bean
|
||||
public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
|
||||
UserDetails user = User.builder()
|
||||
.username("user")
|
||||
.password(passwordEncoder.encode("password"))
|
||||
.roles("USER")
|
||||
.build();
|
||||
|
||||
return new InMemoryUserDetailsManager(user);
|
||||
}
|
||||
//
|
||||
// // 用户信息服务(内存存储)
|
||||
// @Bean
|
||||
// public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
|
||||
// UserDetails user = User.builder()
|
||||
// .username("user")
|
||||
// .password(passwordEncoder.encode("password"))
|
||||
// .roles("USER")
|
||||
// .build();
|
||||
//
|
||||
// return new InMemoryUserDetailsManager(user);
|
||||
// }
|
||||
|
||||
// 注册客户端(内存存储)
|
||||
@Bean
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
package com.tuoheng.oauth.oidc.provider;
|
||||
|
||||
import com.tuoheng.oauth.oidc.service.CustomUserDetailsService;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
@Component
|
||||
public class TenantAwareAuthenticationProvider implements AuthenticationProvider {
|
||||
|
||||
@Autowired
|
||||
private CustomUserDetailsService userDetailsService;
|
||||
|
||||
@Autowired
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
@Override
|
||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||
|
||||
String username = authentication.getName();
|
||||
String password = authentication.getCredentials().toString();
|
||||
|
||||
// 获取请求中的额外参数
|
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
|
||||
.currentRequestAttributes()).getRequest();
|
||||
|
||||
String clientId = request.getParameter("client_id");
|
||||
String tenantCode = request.getParameter("tenant-code");
|
||||
|
||||
System.out.println("=== 认证信息 ===");
|
||||
System.out.println("用户名: " + username);
|
||||
System.out.println("客户端ID: " + clientId);
|
||||
System.out.println("租户代码: " + tenantCode);
|
||||
|
||||
// 执行标准的用户认证
|
||||
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
|
||||
|
||||
if (userDetails != null && passwordEncoder.matches(password, userDetails.getPassword())) {
|
||||
System.out.println("用户认证成功");
|
||||
return new UsernamePasswordAuthenticationToken(
|
||||
userDetails, password, userDetails.getAuthorities());
|
||||
}
|
||||
|
||||
System.out.println("用户认证失败");
|
||||
throw new BadCredentialsException("Invalid username or password");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<?> authentication) {
|
||||
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package com.tuoheng.oauth.oidc.service;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
@Service
|
||||
public class CustomUserDetailsService implements UserDetailsService {
|
||||
|
||||
@Autowired
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
|
||||
// 创建UserDetails对象
|
||||
return org.springframework.security.core.userdetails.User.builder()
|
||||
.username("user")
|
||||
.password(passwordEncoder.encode("password"))
|
||||
.authorities(new HashSet<>())
|
||||
.accountExpired(false)
|
||||
.accountLocked(false)
|
||||
.credentialsExpired(false)
|
||||
.disabled(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue