springboot-demo/src/main/java/com/example/demo/config/SecurityConfig.java

190 lines
7.7 KiB
Java
Raw Normal View History

2024-11-16 22:16:16 +00:00
package com.example.demo.config;
import com.example.demo.exception.CustomAuthenticationEntryPoint;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationServiceException;
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.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.web.SecurityFilterChain;
import java.util.*;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Getter
@Setter
private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
@Autowired
public SecurityConfig(CustomAuthenticationEntryPoint customAuthenticationEntryPoint) {
this.customAuthenticationEntryPoint = customAuthenticationEntryPoint;
}
private static final String[] WHITE_LIST = {"/swagger-ui/**", "/v3/api-docs/**", "/swagger/**"};
// @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
// String issuerUri;
@Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}")
private String jwkSetUri;
String jwtTokenType = "id_token";
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.exceptionHandling(
exception -> exception.authenticationEntryPoint(customAuthenticationEntryPoint))
.authorizeHttpRequests(authorizeRequests ->
authorizeRequests.requestMatchers(WHITE_LIST).permitAll().anyRequest().authenticated()
)
.sessionManagement(sessionManagement ->
sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.csrf(AbstractHttpConfigurer::disable)
.cors(AbstractHttpConfigurer::disable)
.oauth2ResourceServer(oauth2ResourceServerConfigurer ->
oauth2ResourceServerConfigurer.jwt(jwtConfigurer -> {
jwtConfigurer.decoder(customJwtDecoder());
jwtConfigurer.jwtAuthenticationConverter(jwtAuthenticationConverter());
})
);
;
return http.build();
}
@Bean
public JwtDecoder customJwtDecoder() {
// 使用NimbusJwtDecoder从JWKS URL读取密钥
return NimbusJwtDecoder.withJwkSetUri(jwkSetUri).jwtProcessorCustomizer(jwtProcessor -> {
jwtProcessor.setJWETypeVerifier((header, context) -> {
if (!header.getType().equals(jwtTokenType)) {
throw new AuthenticationServiceException("Invalid token type: " + header.getType());
}
});
jwtProcessor.setJWSTypeVerifier((joseObjectType, securityContext) -> {
if (!joseObjectType.getType().equals(jwtTokenType)) {
throw new AuthenticationServiceException("Invalid token type: " + joseObjectType);
}
});
}).build();
}
@Bean
public JwtAuthenticationConverter jwtAuthenticationConverter() {
JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
// 提取权限
converter.setJwtGrantedAuthoritiesConverter(this::extractAuthoritiesFromJwt);
return converter;
}
private Collection<GrantedAuthority> extractAuthoritiesFromJwt(Jwt jwt) {
// 从JWT的claims中提取角色和权限信息
Map<String, Object> claims = jwt.getClaims();
List<GrantedAuthority> authorities = new ArrayList<>();
// 提取角色
if (claims.containsKey("roles") && claims.get("roles") instanceof List) {
List<String> roles = (List<String>) claims.get("roles");
authorities.addAll(roles.stream()
.map(role -> new SimpleGrantedAuthority("ROLE_" + role))
.toList());
}
// 提取权限
if (claims.containsKey("permissions") && claims.get("permissions") instanceof List) {
List<String> permissions = (List<String>) claims.get("permissions");
authorities.addAll(permissions.stream()
.map(SimpleGrantedAuthority::new)
.toList());
}
return authorities;
}
//
// @Bean
// public JwtDecoder customJwtDecoder() {
// return token -> {
// try {
// // 使用Nimbus库解析JWT
// JWT jwt = JWTParser.parse(token);
// String typ = jwt.getHeader().getType().toString();
// // 检查JWT的typ是否为id_token
// if (!typ.equals(jwtTokenType)) {
// throw new AuthenticationServiceException("Invalid token type: " + typ);
// }
//
// JWTClaimsSet claims = jwt.getJWTClaimsSet();
//
//// Date exp = claims.getExpirationTime();
//// Date now = new Date();
// // 检测是否过期
// if (claims.getExpirationTime().before(new Date())) {
// throw new AuthenticationServiceException("Token has expired");
// }
//
// // 将JWT转换为Spring Security的Jwt对象
// return new Jwt(token, jwt.getJWTClaimsSet().getIssueTime().toInstant(), jwt.getJWTClaimsSet().getExpirationTime().toInstant(), jwt.getHeader().toJSONObject(), jwt.getJWTClaimsSet().toJSONObject());
// } catch (AuthenticationServiceException | ParseException e) {
// // 401 了
// throw new AuthenticationServiceException(e.getMessage());
// }
// };
//
//
// }
//
// @Bean
// public JwtAuthenticationConverter jwtAuthenticationConverter() {
// JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
// // 提取权限
// converter.setJwtGrantedAuthoritiesConverter(this::extractAuthoritiesFromJwt);
//
// return converter;
// }
//
//
// private Collection<GrantedAuthority> extractAuthoritiesFromJwt(Jwt jwt) {
// // 从JWT的claims中提取角色和权限信息
// Map<String, Object> claims = jwt.getClaims();
// List<GrantedAuthority> authorities = new ArrayList<>();
//
// // 提取角色
// if (claims.containsKey("roles") && claims.get("roles") instanceof List) {
// List<String> roles = (List<String>) claims.get("roles");
// authorities.addAll(roles.stream()
// .map(role -> new SimpleGrantedAuthority("ROLE_" + role))
// .toList());
// }
//
// // 提取权限
// if (claims.containsKey("permissions") && claims.get("permissions") instanceof List) {
// List<String> permissions = (List<String>) claims.get("permissions");
// authorities.addAll(permissions.stream()
// .map(SimpleGrantedAuthority::new)
// .toList());
// }
//
// return authorities;
// }
}