springboot基础学习 之 集成OAuth2实现第三方登录或API访问授权
以上是一个简单的使用 Spring Security 实现 OAuth2 的示例。实际应用中,你可能需要根据实际需求配置更多的信息,如多个第三方登录提供商、授权范围的配置等。详细的配置可以参考 Spring Security 和各个 OAuth2 提供商的文档。OAuth2 是一个开放标准,允许用户授权第三方应用访问他们的资源,而无需共享用户的凭据。创建一个配置类,配置 OAuth2 相关的信息。
集成 OAuth2 可以实现第三方登录和 API 访问授权。OAuth2 是一个开放标准,允许用户授权第三方应用访问他们的资源,而无需共享用户的凭据。以下是使用 Spring Security 实现 OAuth2 的基本步骤:
-
添加依赖:
在项目的
pom.xml文件中添加 Spring Security OAuth2 相关的依赖:xmlCopy code
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency> -
配置 OAuth2:
创建一个配置类,配置 OAuth2 相关的信息。以下是一个简单的示例:
javaCopy code
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; @Configuration public class OAuth2Config { @Bean public UserDetailsService userDetailsService() { return (username) -> { UserDetails userDetails = User .withUsername(username) .password(passwordEncoder().encode("password")) // Replace with actual password .authorities(AuthorityUtils.createAuthorityList("ROLE_USER")) .build(); return userDetails; }; } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public ClientRegistrationRepository clientRegistrationRepository() { return (new InMemoryClientRegistrationRepository(githubClientRegistration())); } private ClientRegistration githubClientRegistration() { return ClientRegistration .withRegistrationId("github") .clientId("your-github-client-id") .clientSecret("your-github-client-secret") .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) .clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) .redirectUri("{baseUrl}/login/oauth2/code/{registrationId}") .scope("read:user") .authorizationUri("https://github.com/login/oauth/authorize") .tokenUri("https://github.com/login/oauth/access_token") .userInfoUri("https://api.github.com/user") .userNameAttributeName("id") .clientName("GitHub") .build(); } }请替换上述代码中的占位符(如
your-github-client-id和your-github-client-secret)为实际的 GitHub 应用程序信息。 -
配置 Spring Security:
在 Spring Security 的配置类中,启用 OAuth2 登录:
javaCopy code
import org.springframework.beans.factory.annotation.Autowired; 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.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private OAuth2AuthorizationRequestRedirectFilter oAuth2AuthorizationRequestRedirectFilter; @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/", "/login**", "/error**").permitAll() .anyRequest().authenticated() .and() .oauth2Login() .loginPage("/login") .defaultSuccessURL("/home") .failureUrl("/login?error=true") .and() .exceptionHandling() .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login")) .and() .addFilterBefore(oAuth2AuthorizationRequestRedirectFilter, CsrfFilter.class); } @Bean public OAuth2AuthorizationRequestRedirectFilter oAuth2AuthorizationRequestRedirectFilter() { return new OAuth2AuthorizationRequestRedirectFilter(clientRegistrationRepository(), "/login/oauth2/code/*"); } } -
创建登录和首页页面:
创建一个登录页面和一个首页页面,用于演示登录和登录成功后的页面。
-
src/main/resources/templates/login.html:htmlCopy code
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Login</title> </head> <body> <h2>Login</h2> <p><a href="/login/oauth2/authorization/github">Login with GitHub</a></p> </body> </html> -
src/main/resources/templates/home.html:htmlCopy code
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Home</title> </head> <body> <h2>Home</h2> <p>Welcome! You are now authenticated.</p> </body> </html>
-
-
启动应用程序:
启动你的 Spring Boot 应用程序,并访问
http://localhost:8080/login查看登录页面。点击 "Login with GitHub" 将跳转到 GitHub 登录页面,登录成功后将重定向到应用程序的首页。
以上是一个简单的使用 Spring Security 实现 OAuth2 的示例。实际应用中,你可能需要根据实际需求配置更多的信息,如多个第三方登录提供商、授权范围的配置等。详细的配置可以参考 Spring Security 和各个 OAuth2 提供商的文档
-
获取用户信息:
当用户通过 OAuth2 登录成功后,你可能需要获取用户的详细信息。你可以通过注入
OAuth2UserService来实现:javaCopy code
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.oauth2.core.user.OAuth2UserAuthority; @Configuration public class OAuth2Config { @Autowired private OAuth2AuthorizedClientService authorizedClientService; // existing methods... @Bean public OAuth2UserService<OAuth2UserRequest, OAuth2User> oAuth2UserService(ClientRegistrationRepository clientRegistrationRepository) { DefaultOAuth2UserService delegate = new DefaultOAuth2UserService(); return new CustomOAuth2UserService(delegate, authorizedClientService); } }创建一个自定义的
CustomOAuth2UserService类,继承自DefaultOAuth2UserService,用于获取用户信息:javaCopy code
import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; import org.springframework.security.oauth2.client.userinfo.OAuth2UserResponse; import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.oauth2.core.user.OAuth2UserAuthority; import org.springframework.security.oauth2.core.user.OAuth2UserRequest; import org.springframework.security.oauth2.core.user.OAuth2UserResponse; import org.springframework.security.oauth2.core.user.OAuth2UserResponseException; public class CustomOAuth2UserService extends DefaultOAuth2UserService { // existing methods... @Override public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { OAuth2User user = super.loadUser(userRequest); try { return new CustomOAuth2User(user, authorizedClientService.loadAuthorizedClient( userRequest.getClientRegistration().getRegistrationId(), userRequest.getPrincipalName())); } catch (OAuth2UserResponseException e) { throw new OAuth2AuthenticationException(e.getError(), e); } } }在
CustomOAuth2User类中,你可以获取并处理用户的详细信息,例如:javaCopy code
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.user.DefaultOAuth2User; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.oauth2.core.user.OAuth2UserAuthority; import java.util.Collection; import java.util.Map; public class CustomOAuth2User extends DefaultOAuth2User { private final OAuth2AuthorizedClient authorizedClient; public CustomOAuth2User(OAuth2User user, OAuth2AuthorizedClient authorizedClient) { super(user.getAuthorities(), user.getAttributes(), "id"); this.authorizedClient = authorizedClient; } // Additional methods to get and process user details... }在这里,你可以自定义
CustomOAuth2User类来获取和处理用户的详细信息,包括用户 ID、用户名、电子邮件等。 -
注销:
考虑用户注销时,你可能需要注销用户的 OAuth2 授权。可以配置注销端点来实现:
javaCopy code
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client; @Configuration @EnableOAuth2Client public class OAuth2Config { @Autowired private OAuth2AuthorizedClientService authorizedClientService; // existing methods... @Bean public OAuth2UserService<OAuth2UserRequest, OAuth2User> oAuth2UserService(ClientRegistrationRepository clientRegistrationRepository) { DefaultOAuth2UserService delegate = new DefaultOAuth2UserService(); return new CustomOAuth2UserService(delegate, authorizedClientService); } @Bean public ClientRegistrationRepository clientRegistrationRepository() { // existing method... } @Bean public OAuth2AuthorizationRequestRedirectFilter oAuth2AuthorizationRequestRedirectFilter() { // existing method... } }在上述配置中,
EnableOAuth2Client注解启用了 OAuth2 客户端支持。在用户注销时,可以使用以下代码来注销 OAuth2 授权:javaCopy code
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Authentication; 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; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; @Controller @RequestMapping("/logout") public class LogoutController { @Autowired private OAuth2AuthorizedClientService authorizedClientService; @GetMapping public String logout(HttpServletRequest request, Authentication authentication) { if (authentication != null) { OAuth2AuthorizedClient authorizedClient = authorizedClientService.loadAuthorizedClient( "github", authentication.getName()); if (authorizedClient != null) { authorizedClientService.removeAuthorizedClient( "github", authentication.getName()); } } return "redirect:/login?logout"; } }上述代码在用户注销时移除了 GitHub 的 OAuth2 授权。
-
API 访问授权:
如果你希望在应用程序中访问第三方 API,你可以使用
RestTemplate或WebClient来添加 OAuth2 授权头。以下是一个使用WebClient的简单示例:javaCopy code
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.client.WebClient; @Service public class GitHubApiService { private final WebClient webClient; private final OAuth2AuthorizedClientService authorizedClientService; @Autowired public GitHubApiService(WebClient.Builder webClientBuilder, OAuth2AuthorizedClientService authorizedClientService) { this.webClient = webClientBuilder.baseUrl("https://api.github.com").build(); this.authorizedClientService = authorizedClientService; } public String getUserInfo(Authentication authentication) { OAuth2AuthorizedClient authorizedClient = authorizedClientService.loadAuthorizedClient( "github", authentication.getName()); return webClient .get() .uri("/user") .headers(headers -> headers.setBearerAuth(authorizedClient.getAccessToken().getTokenValue())) .retrieve() .bodyToMono(String.class) .block(); } }上述代码使用
WebClient向 GitHub API 发送请求,并添加了 OAuth2 授权头。
这是一个简单的 OAuth2 集成示例,你可以根据实际需求和业务逻辑进一步定制和扩展。在开发过程中,请参考 Spring Security 和 OAuth2 文档,以确保正确实现所需的功能和安全性。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)