首先,我们需要在GitHub上注册OAuth2应用程序,并获取client-id和client-secret。在GitHub上注册应用程序时,我们需要提供回调URL,该URL将在用户授权后重定向回我们的应用程序。我们可以使用http://localhost:8080/login/oauth2/code/github作为回调URL,这是Spring Security默认的OAuth2回调URL。
我们可以使用以下application.yml配置来配置OAuth2客户端:
代码语言:javascript复制spring:
security:
oauth2:
client:
registration:
github:
client-id: github-client-id
client-secret: github-client-secret
scope:
- user:email
- read:user
provider:
github:
authorization-uri: https://github.com/login/oauth/authorize
token-uri: https://github.com/login/oauth/access_token
user-info-uri: https://api.github.com/user
user-name-attribute: login
在上面的示例中,我们配置了一个名为“github”的OAuth2客户端。该客户端需要一个client-id和client-secret,可以从GitHub开发者设置中获取。客户端还指定了要获取的权限范围,包括“user:email”和“read:user”。
我们还需要配置GitHub的OAuth2提供程序的详细信息。该提供程序的授权地址为https://github.com/login/oauth/authorize,令牌地址为https://github.com/login/oauth/access_token,用户信息地址为https://api.github.com/user。我们还指定了用户的名称属性为登录名称。
接下来,我们需要定义一个WebSecurityConfigurerAdapter类,以保护我们的应用程序并配置OAuth2客户端。以下是示例代码:
代码语言:javascript复制@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login/**").permitAll()
.anyRequest().authenticated()
.and()
.oauth2Login();
}
@Override
protected void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("github")
.secret("{noop}github-client-secret")
.authorizedGrantTypes("authorization_code")
.scopes("user:email", "read:user")
.redirectUris("http://localhost:8080/login/oauth2/code/github");
}
}
在上面的示例代码中,我们覆盖了configure(HttpSecurity)方法来配置安全性。我们允许所有用户访问/login/**,并对其他所有请求进行身份验证。我们还使用.oauth2Login()配置了OAuth2登录流程。
我们还覆盖了configure(ClientDetailsServiceConfigurer)方法来配置OAuth2客户端的详细信息。在这个示例中,我们将客户端详细信息存储在内存中,但在实际应用程序中,我们可能会使用数据库或其他持久化机制来存储这些信息。我们指定客户端ID为“github”,授权类型为“authorization_code”,并指定要获取的权限范围和重定向URI。
最后,我们需要定义一个Controller来访问受保护的资源。以下是示例代码:
代码语言:javascript复制@RestController
public class GitHubApiController {
@GetMapping("/api/github/user")
public ResponseEntity<String> getUserInfo(OAuth2AuthenticationToken token) {
OAuth2AuthorizedClient client = new OAuth2AuthorizedClient(
token.getAuthorizedClientRegistrationId(),
token.getPrincipal(),
token.getAccessToken()
);
String userInfoEndpointUri = client.getClientRegistration()
.getProviderDetails().getUserInfoEndpoint().getUri();
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.AUTHORIZATION, "Bearer " client.getAccessToken().getTokenValue());
HttpEntity<String> entity = new HttpEntity<>("", headers);
ResponseEntity<String> response = new RestTemplate().exchange(userInfoEndpointUri, HttpMethod.GET, entity, String.class);
return response;
}
}
在上面的示例代码中,我们定义了一个名为“getUserInfo”的端点来访问GitHub API。我们使用OAuth2AuthenticationToken获取OAuth2AuthorizedClient,并使用它来获取访问令牌和用户信息终端点URI。我们还创建了一个HTTP实体,并使用RestTemplate发送HTTP GET请求来访问用户信息终端点。
现在,我们可以使用http://localhost:8080/api/github/user来访问受保护的GitHub API。如果用户已经通过OAuth2登录,并且已经授权了我们的应用程序,则可以成功访问该资源。如果用户没有登录或未授权,则将重定向到OAuth2提供程序的登录页面。