在spring-boot 3上有一个java应用程序。0.5,它被配置为资源服务器,如下所示:
Maven依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
安全配置:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
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.http.SessionCreationPolicy;
import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator;
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
import org.springframework.security.oauth2.jwt.*;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
private String issuerUri;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors().disable()
.csrf().disable()
.authorizeHttpRequests()
.requestMatchers("/actuator/**").permitAll()
.anyRequest().authenticated()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.oauth2ResourceServer()
.jwt();
return http.build();
}
@Bean
public JwtDecoder jwtDecoder() {
NimbusJwtDecoder jwtDecoder = JwtDecoders.fromIssuerLocation(issuerUri);
OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuerUri);
OAuth2TokenValidator<Jwt> withOperation = new OperationClaimValidator();
jwtDecoder.setJwtValidator(
new DelegatingOAuth2TokenValidator<>(withIssuer, withOperation)
);
return jwtDecoder;
}
}
正如你所看到的,我定义了JwtDecoder
bean来为JWT添加一个自定义验证器OperationClaimValidator
,因为我想验证我的自定义jwt声明operation
:
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult;
import org.springframework.security.oauth2.jwt.Jwt;
public class OperationClaimValidator implements OAuth2TokenValidator<Jwt> {
private static final String CLAIM_OPERATION = "operation";
@Override
public OAuth2TokenValidatorResult validate(Jwt jwt) {
if (jwt.getClaimAsString(CLAIM_OPERATION).equals("Value-from-HttpServletRequest")) { // problem here
return OAuth2TokenValidatorResult.success();
} else {
return OAuth2TokenValidatorResult.failure(
new OAuth2Error("invalid_token", "The required operation is GET", null)
);
}
}
}
问题是我想比较operation
声明中的值和HttpServletRequest#getMethod
中的值,但我不知道如何从OAuth2TokenValidator
实现中访问HttpServletRequest
。
我可以使用OncePerRequestFilter
以另一种方式验证这一说法:
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private static final String CLAIM_OPERATION = "operation";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String requestMethod = request.getMethod();
String operationClaimValue = getOperationClaimValue(request);
if (!requestMethod.equals(operationClaimValue)) {
response.sendError(HttpStatus.UNAUTHORIZED.value(),
"Operation claim in token does not match with http method used in request");
} else {
filterChain.doFilter(request, response);
}
}
private String getOperationClaimValue(HttpServletRequest request) {
Principal principal = request.getUserPrincipal();
Jwt token = ((JwtAuthenticationToken) principal).getToken();
return token.getClaimAsString(CLAIM_OPERATION);
}
}
,但我想实现它实现OAuth2TokenValidator
.有什么想法吗?先谢谢你。
1条答案
按热度按时间3bygqnnd1#
您可以静态访问
ServletRequest
,如下所示: