主要是3个配置文件,其他跟普通使用方法没啥区别
1.开发环境
springboot 2.7.4
java 17
认证服务:spring-security-oauth2-authorization-server 0.3.1
openfeign(客户端)用的springcloud 2021.0.4
2.maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
3.application.properties配置参数
#根据实际认证服务器地址和端口号填写
spring.security.oauth2.client.provider.spring.issuer-uri=http://auth-server:9000
#auth-server是自己起的名字,待会儿配置文件里会用到
spring.security.oauth2.client.registration.auth-server.provider=spring
spring.security.oauth2.client.registration.auth-server.authorizationGrantType=client_credentials
spring.security.oauth2.client.registration.auth-server.clientId=theClientId
spring.security.oauth2.client.registration.auth-server.clientSecret=123
spring.security.oauth2.client.registration.auth-server.scope=openid
4.添加入口类注解
@SpringBootApplication
@EnableFeignClients
public class SpringcloudOpenfeignApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudOpenfeignApplication.class, args);
}
}
5.配置文件(共3个:2个针对openfeign的,1个针对springsecurity的)
import feign.RequestInterceptor;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.*;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
@Configuration
@RequiredArgsConstructor
public class OpenfeignConfiguration {
private static final String CLIENT_REGISTRATION_ID="auth-server"; //auth-server对应application.properties里面的名字
private final OAuth2AuthorizedClientService oAuth2AuthorizedClientService;
private final ClientRegistrationRepository clientRegistrationRepository;
//拦截器,每次访问在header里添加token
@Bean
public RequestInterceptor requestInterceptor(){
ClientRegistration clientRegistration = clientRegistrationRepository.findByRegistrationId(CLIENT_REGISTRATION_ID);
OAuthClientCredentialsFeignManager manager = new OAuthClientCredentialsFeignManager(authorizedClientManager(), clientRegistration);
return requestTemplate -> {
requestTemplate.header("Authorization","Bearer "+ manager.getAccessToken());
};
}
@Bean
OAuth2AuthorizedClientManager authorizedClientManager() {
OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials()
.build();
AuthorizedClientServiceOAuth2AuthorizedClientManager authorizedClientManager =
new AuthorizedClientServiceOAuth2AuthorizedClientManager(clientRegistrationRepository, oAuth2AuthorizedClientService);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
return authorizedClientManager;
}
}
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import java.util.Collection;
import java.util.Collections;
import static java.util.Objects.isNull;
public class OAuthClientCredentialsFeignManager {
private final OAuth2AuthorizedClientManager manager;
private final Authentication principal;
private final ClientRegistration clientRegistration;
public OAuthClientCredentialsFeignManager(OAuth2AuthorizedClientManager manager, ClientRegistration clientRegistration){
this.manager = manager;
this.clientRegistration = clientRegistration;
this.principal = createPrincipal();
}
private Authentication createPrincipal(){
return new Authentication() {
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.emptyList();
}
@Override
public Object getCredentials() {
return null;
}
@Override
public Object getDetails() {
return null;
}
@Override
public Object getPrincipal() {
return this;
}
@Override
public boolean isAuthenticated() {
return false;
}
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
}
@Override
public String getName() {
return clientRegistration.getClientId();
}
};
}
public String getAccessToken() {
try {
OAuth2AuthorizeRequest oAuth2AuthorizeRequest = OAuth2AuthorizeRequest
.withClientRegistrationId(clientRegistration.getRegistrationId())
.principal(principal)
.build();
OAuth2AuthorizedClient client = manager.authorize(oAuth2AuthorizeRequest);
if (isNull(client)) {
throw new IllegalStateException("client credentials flow on " + clientRegistration.getRegistrationId() + " failed, client is null");
}
return client.getAccessToken().getTokenValue();
} catch (Exception exp) {
System.out.println("client credentials error " + exp.getMessage());
}
return null;
}
}
springsecurity的相关配置
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
@EnableWebSecurity
public class OAuth2WebSecurityConfigurerAdapter{
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
/*.authorizeRequests(authorizeRequests ->
authorizeRequests.anyRequest().authenticated()
)*/
.csrf().disable().oauth2Client();
return http.build();
}
}
6.client接口类
@FeignClient(value = "MeClient",
url = "http://127.0.0.1:9000/"
)
public interface MeClient {
@RequestMapping(method = RequestMethod.GET, value = "/user/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<SimpleResponse<Me>> getMe(@PathVariable("id") Integer id);
}
参考文章:
https://www.baeldung.com/spring-cloud-feign-oauth-token
https://amithkumarg.medium.com/spring-cloud-openfeign-oauth-2-0-68f75f06836f
tutorials/spring-cloud-modules/spring-cloud-openfeign at master · eugenp/tutorials · GitHub