application.yaml
security:
oauth2:
resourceserver:
jwt:
issuer-uri: <okta issuer uri>
client:
registration:
internal-client: okta
client-id: <My- client id>
client-secret: <My client secret>
authorization-grant-type: client_credentails
scope: internal
provider:
okta:
issuer-uri: <okta issuer uri>
okta:
oauth2:
issuer: <okta issuer uri>
audience: api://default
上面的代码是我的Spring Boot应用程序的application.yaml文件。
package DemoService.ConfigClasses;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
import org.springframework.web.client.RestTemplate;
import DemoService.ConfigClasses.Interceptors.RestTemplateInterceptor;
@Configuration
public class DemoConf {
@Autowired
private ClientRegistrationRepository clientRegistrationRepository;
@Autowired
private OAuth2AuthorizedClientRepository oAuth2AuthorizedClientRepository;
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate= new RestTemplate();
List<ClientHttpRequestInterceptor> interceptor=new ArrayList<>();
interceptor.add(new RestTemplateInterceptor(manager(clientRegistrationRepository,oAuth2AuthorizedClientRepository)));
return restTemplate;
}
@Bean
public OAuth2AuthorizedClientManager manager(ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository auth2AuthorizedClientRepository) {
OAuth2AuthorizedClientProvider provider=OAuth2AuthorizedClientProviderBuilder.builder().clientCredentials().build();
DefaultOAuth2AuthorizedClientManager defaultOAuth2AuthorizedClientManager=new DefaultOAuth2AuthorizedClientManager(clientRegistrationRepository, auth2AuthorizedClientRepository);
defaultOAuth2AuthorizedClientManager.setAuthorizedClientProvider(provider);
return defaultOAuth2AuthorizedClientManager;
}
}
这是我的配置类
package DemoService.ConfigClasses;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.server.SecurityWebFilterChain;
@Configuration
@EnableWebFluxSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig {
@Bean
public SecurityWebFilterChain securityFilterChain(ServerHttpSecurity httpSecurity) {
httpSecurity.authorizeExchange()
.anyExchange()
.authenticated()
.and()
.oauth2ResourceServer()
.jwt();
return httpSecurity.build();
}
}
网络安全配置类
package DemoService.ConfigClasses.Interceptors;
import java.io.IOException;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
public class RestTemplateInterceptor implements ClientHttpRequestInterceptor{
private OAuth2AuthorizedClientManager manager;
public RestTemplateInterceptor(OAuth2AuthorizedClientManager manager) {
super();
this.manager = manager;
}
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
throws IOException {
String token=manager.authorize(OAuth2AuthorizeRequest.withClientRegistrationId("internal-client").principal("internal").build()).getAccessToken().getTokenValue();
request.getHeaders().add("Authorization", "Bearer "+token);
return execution.execute(request, body);
}
}
Rest 模板拦截器类
我正在尝试创建一个内部服务,并使用 okta oauth2 添加 spring security 来保护该服务。我正在为此服务实施基于令牌的授权。启动服务时显示以下错误:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.1.9)
2024-03-24T12:26:08.837+05:30 INFO 11772 --- [ main] DemoService.DemoServApplication : Starting DemoServApplication using Java 17.0.3 with PID 11772 (C:\Users\lenovo\Downloads\DemoServ\DemoServ\target\classes started by lenovo in C:\Users\lenovo\Downloads\DemoServ\DemoServ)
2024-03-24T12:26:08.843+05:30 INFO 11772 --- [ main] DemoService.DemoServApplication : No active profile set, falling back to 1 default profile: "default"
2024-03-24T12:26:10.280+05:30 WARN 11772 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration]: Error processing condition on org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientRegistrationRepositoryConfiguration
2024-03-24T12:26:10.314+05:30 INFO 11772 --- [ main] .s.b.a.l.ConditionEvaluationReportLogger :
Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2024-03-24T12:26:10.413+05:30 ERROR 11772 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to bind properties under 'spring.security.oauth2.client.registration.internal-client' to org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties$Registration:
Reason: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties$Registration]
Action:
Update your application's configuration
您的属性至少有两个错误:
registration
属性下缺少一个级别(您稍后引用为 internal-client
的注册 ID)(这是当前异常的原因)registration
中,您使用 internal-client
(而不是 provider
)引用提供商尝试:
okta-issuer: change-me
internal-client-id: change-me
internal-client-secret: change-me
security:
oauth2:
resourceserver:
jwt:
issuer-uri: ${okta-issuer}
client:
registration:
internal-client:
provider: okta
client-id: ${internal-client-id}
client-secret: ${internal-client-secret}
authorization-grant-type: client_credentails
scope: internal
provider:
okta:
issuer-uri: ${okta-issuer}