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.ImmutableJWKSet;
|
||||||
import com.nimbusds.jose.jwk.source.JWKSource;
|
import com.nimbusds.jose.jwk.source.JWKSource;
|
||||||
import com.nimbusds.jose.proc.SecurityContext;
|
import com.nimbusds.jose.proc.SecurityContext;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.security.authentication.AuthenticationProvider;
|
||||||
import org.springframework.security.config.Customizer;
|
import org.springframework.security.config.Customizer;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
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.User;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
|
@ -49,6 +53,9 @@ import java.util.UUID;
|
||||||
@Configuration
|
@Configuration
|
||||||
public class SecurityConfig {
|
public class SecurityConfig {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
AuthenticationProvider tenantAwareAuthenticationProvider;
|
||||||
// 自定义认证入口点,保留client_id参数
|
// 自定义认证入口点,保留client_id参数
|
||||||
public static class CustomLoginUrlAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {
|
public static class CustomLoginUrlAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {
|
||||||
public CustomLoginUrlAuthenticationEntryPoint(String loginFormUrl) {
|
public CustomLoginUrlAuthenticationEntryPoint(String loginFormUrl) {
|
||||||
|
|
@ -89,6 +96,7 @@ public class SecurityConfig {
|
||||||
@Bean
|
@Bean
|
||||||
@Order(2)
|
@Order(2)
|
||||||
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
|
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||||
|
|
||||||
http
|
http
|
||||||
.authorizeHttpRequests(authorize ->
|
.authorizeHttpRequests(authorize ->
|
||||||
authorize
|
authorize
|
||||||
|
|
@ -115,22 +123,28 @@ public class SecurityConfig {
|
||||||
.invalidateHttpSession(true)
|
.invalidateHttpSession(true)
|
||||||
.deleteCookies("JSESSIONID")
|
.deleteCookies("JSESSIONID")
|
||||||
.permitAll()
|
.permitAll()
|
||||||
);
|
)
|
||||||
|
// 添加会话管理配置
|
||||||
|
// .sessionManagement(session -> session
|
||||||
|
// .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
|
||||||
|
// .maximumSessions(1) // 限制每个用户只能有一个会话
|
||||||
|
// )
|
||||||
|
// 添加自定义认证提供者
|
||||||
|
.authenticationProvider(tenantAwareAuthenticationProvider);
|
||||||
return http.build();
|
return http.build();
|
||||||
}
|
}
|
||||||
|
//
|
||||||
// 用户信息服务(内存存储)
|
// // 用户信息服务(内存存储)
|
||||||
@Bean
|
// @Bean
|
||||||
public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
|
// public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
|
||||||
UserDetails user = User.builder()
|
// UserDetails user = User.builder()
|
||||||
.username("user")
|
// .username("user")
|
||||||
.password(passwordEncoder.encode("password"))
|
// .password(passwordEncoder.encode("password"))
|
||||||
.roles("USER")
|
// .roles("USER")
|
||||||
.build();
|
// .build();
|
||||||
|
//
|
||||||
return new InMemoryUserDetailsManager(user);
|
// return new InMemoryUserDetailsManager(user);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// 注册客户端(内存存储)
|
// 注册客户端(内存存储)
|
||||||
@Bean
|
@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