本文参考来源:
Spring Security提供了全面的OAuth 2支持。本节讨论了如何将OAuth 2集成到你的基于Servlet的应用程序中。 OAuth 2.0登录功能允许应用程序让用户通过使用他们在OAuth 2.0提供商(如GitHub)或OpenID Connect 1.0提供商(如Google)的现有账户登录到应用程序
想要实现通过 OAuth 2.0提供商的现有账户登录到应用程序需要引入 oauth2-client ,下面按照官网给的默认配置进行深入
<dependencies>
<!--引入oauth2-client:通过 OAuth 2.0提供商的现有账户登录到应用程序-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
以 Google 为例,想要通过 Google 的现有账户进行登录,需要进行下面的配置,spring security 团队为一些知名的供应商预先定义了一套默认的客户端属性。如:谷歌、GitHub、Facebook和Okta, 按照官网提供的配置进行配置即可
spring:
security:
oauth2:
client:
registration:
google:
client-id: google-client-id
client-secret: google-client-secret
这里只做一个示范,国内你也根本不可能访问到 google,因此上面的 client-id 和 client-secret 不需要换成真实的。启动程序,访问 http://localhost:8080/login 会发现页面给了一个 去 google 的链接,之后就是 google 基于 oauth2 的授权码模式流程,这里不做过多介绍。
当然,你的系统可以支持多个oauth2应用的供应商提供的登录方式,有些供应商不在 spring security 团队的计划内,需要自己适配,只需要将各个属性都配置即可
spring:
security:
oauth2:
client:
registration:
google:
client-id: google-client-id
client-secret: google-client-secret
github:
client-id: github-client-id
client-secret: github-client-secret
gitee:
provider: gitee
client-id: gitee-client-id
client-secret: gitee-client-secret
authorization-grant-type: authorization_code
redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
scope: user_info
client-name: Gitee
provider:
gitee:
authorization-uri: https://gitee.com/oauth/authorize
token-uri: https://gitee.com/oauth/token
user-name-attribute: id
user-info-uri: https://gitee.com/api/v5/user
比如:像配置文件中的 gitee 就需要按照上面的方式进行配置,再次启动程序 就可以看到,可以用 google , github , gitee 进行登录了
由于国内 github 、 facebook、 google 等龟速问题,我们以 gitee 为例进行 oauth2 登录的演示,其实就是对前面整个章节的一个示范,这里只是引入了 一个 oauth2-client 的依赖而已。
gitee 的有关 oauth2 授权的开发者文档: https://gitee.com/api/v5/oauth_doc#/
根据上面的链接,创建好gitee的应用即可,不做赘述,主要是获取 clientId 及 client Secret,将获取的信息配置到 application.yml 中即可
spring:
security:
oauth2:
client:
registration:
gitee:
provider: gitee
client-id: gitee-client-id
client-secret: gitee-client-secret
## 使用授权码模式
authorization-grant-type: authorization_code
## 配置在 gitee 上的回调地址 务必保持一致,如果是想对第三方应用的用户进行处理
## 请将回调地址配置成 '{baseUrl}/login/oauth2/code/{registrationId}' 模式
redirect-uri: https://www.baidu.com
## 授权范围
scope:
- user_info
client-name: Gitee
provider:
gitee:
authorization-uri: https://gitee.com/oauth/authorize
token-uri: https://gitee.com/oauth/token
user-name-attribute: id
user-info-uri: https://gitee.com/api/v5/user
启动程序,访问 http://localhost:8080/login ,点击 Gitee ,系统将引导你到 gitee 的授权页面
接下来的事情就不再赘述了
HttpSecurity.oauth2Login() 为定制OAuth 2.0登录提供了大量的配置选项。主要的配置选项被分组到它们的协议端点对应处。 例如,oauth2Login().authorizationEndpoint() 允许配置授权端点,而 oauth2Login().tokenEndpoint() 允许配置令牌端点。 在用户成功通过 OAuth 2.0 提供商的认证后,OAuth2User.getAuthorities()(或 OidcUser.getAuthorities())包含一个 由 OAuth2UserRequest.getAccessToken().getScopes() 填充的授予权限列表,其前缀为 SCOPE_。 这些授权可以被映射到一组新的 GrantedAuthority 实例中,在完成认证时提供给 OAuth2AuthenticationToken。
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.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
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.web.SecurityFilterChain;
import java.util.Map;
@Configuration
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.oauth2Login(oauth2 -> oauth2
.userInfoEndpoint(userInfo -> userInfo
.userService(this.oauth2UserService())));
return http.build();
}
private OAuth2UserService<OAuth2UserRequest, OAuth2User> oauth2UserService() {
DefaultOAuth2UserService userService = new DefaultOAuth2UserService(){
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
//假设这里要将用户存到数据库
OAuth2User oAuth2User = super.loadUser(userRequest);
//userRequest 和 oAuth2User 中有大量的有用信息可以拿来使用 具体断点到这里看就行了
//1 写个方法将 oAuth2User 和 userRequest 中有用的信息 转化成系统用户
//2 将系统用户存入数据库
Map<String, Object> attributes = oAuth2User.getAttributes();
//3 可以在这里自定义一些信息放入 attributes 中
return new DefaultOAuth2User(oAuth2User.getAuthorities(),attributes,userRequest
.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName());
}
};
return userService;
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。