我有一个简单的用例。
从我现有的 Spring Boot 应用程序中,我想调用受 OAuth2 保护的 REST API(授权类型 -
client_credentials
)
我以前从未使用过 OAuth。
我尝试检查 spring-docs 和其他地方的示例(我自己的错误 chatgpt 给出了错误的建议)。
现在我只是很困惑什么是正确的解决方案。
有人可以给我举个例子或者推动我朝正确的方向迈进吗?
到目前为止我的代码:
应用程序属性
spring.application.name=oauth-test
spring.security.oauth2.client.registration.myuser.client-id=userId
spring.security.oauth2.client.registration.myuser.client-secret=userPassword
spring.security.oauth2.client.registration.myuser.authorization-grant-type=client_credentials
spring.security.oauth2.client.registration.myuser.scope=read
spring.security.oauth2.client.provider.myuser.token-uri=https://auth-server-app/v1/oauth/token
控制器:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
@RequestMapping("/v2/")
public class ApiController {
@Autowired
private OAuth2AuthorizedClientService authorizedClientService;
@GetMapping("/protected-data")
public ResponseEntity<String> getProtectedData() {
OAuth2AuthorizedClient client = authorizedClientService.loadAuthorizedClient("myuser", "userId");
String accessToken = client.getAccessToken().getTokenValue();
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + accessToken);
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<String> response = restTemplate.exchange("https://my-resource-server/v1/resource/1", HttpMethod.GET, entity, String.class);
return ResponseEntity.ok("Protected data retrieved successfully!");
}
}
这是我的存在WebSecurityConfigurerAdapter.java
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final BasicAuthConfig basicAuthConfig; // Basic @Configuration class fetching values from application properties.
public WebSecurityConfig(final BasicAuthConfig basicAuthConfig) {
this.basicAuthConfig = basicAuthConfig;
}
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
String userName = basicAuthConfig.getUsername();
String password = basicAuthConfig.getPassword();
String encodedPassword = encoder().encode(password);
auth.inMemoryAuthentication()
.withUser(userName)
.password(encodedPassword)
.roles("USER");
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http
.authorizeRequests()
.antMatchers("/v1/**").authenticated()
.anyRequest().permitAll()
.and()
.httpBasic();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
Spring Security OAuth2 显示了我认为您正在实现的场景的一部分“我想为用户获取访问令牌,以便访问第三方 API”。
Spring security也提供了一些示例,这里你可以找到一个使用webclient + Oauth2.0访问Github资源的示例吗?
根据我自己的经验,我的建议是您熟悉 Oauth2 工作原理的基础知识,以便您能够理解您正在实现的流程(client_credentials)。我留下了一些简单的资源来帮助我了解如何开始: