背景
由于项目的关系,系统需要集成oAuth2.0功能。关于OAuth2.0的概念参考文章 理解OAuth 2.0 ,或者 OAuth 2.0最简向导
实现自定义功能
依赖jar
我们系统使用的Spring cloud G版本,引入依赖jar包
<!-- oAuth2 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
复制代码
OAuth2.0 代码概述
OAuth 2.0 定义了四种授权方式
- ○ 授权码模式(authorization code)
- ○ 简化模式(implicit)
- ○ 密码模式(resource owner password credentials)
- ○ 客户端模式(client credentials)
在Spring OAuth2.0中除了定义以上四种授权模式外,还定义一个特殊的授权模式:刷新 四种模式和refresh模式对应的处理类是:
- ○ AuthorizationCodeTokenGranter: 对应 authorization_code 模式
- ○ ImplicitTokenGranter :对应 implicit模式
- ○ ClientCredentialsTokenGranter:对应 client_credentials模式
- ○ ResourceOwnerPasswordTokenGranter:对应 password 模式
- ○ RefreshTokenGranter: 对应 refresh_token模式
其他一些重要的类:
-
○ AuthorizationCodeServices:用于“授权码模式( authorization code )”如何保存"授权码",默认有两种实现:
- § InMemoryAuthorizationCodeServices:授权码保存在内存中
- § JdbcAuthorizationCodeServices:授权码保存在数据库中
-
○ TokenStore:存储token的方式,常用有以下几种实现
- § InMemoryTokenStore:内存存储
- § JdbcTokenStore:数据库存储
- § RedisTokenStore:redis存储
- § JwkTokenStore和JwtTokenStore
-
○ ClientDetailsService:客户端账号管理
- § InMemoryClientDetailsService:使用内存管理客户端账号
- § JdbcClientDetailsService:使用数据库管理客户端账号
-
○ UserDetailsService:如何加载用户账号
- § InMemoryUserDetailsManager:从内存中加载用户账号
- § JdbcUserDetailsManager:从数据库中加载用户账号
-
○ 其他
- § DefaultTokenServices:token服务类,token的处理逻辑很大部分在这里
实现自定义客户端账户(不是用户的账户)
-
○ ClientDetailsService:客户端账号管理
- § InMemoryClientDetailsService:使用内存管理客户端账号
- § JdbcClientDetailsService:使用数据库管理客户端账号
网上的案列基本是使用JdbcClientDetailsService 和 InMemoryClientDetailsService 实现客户端账号。这些都不符合我们的要求。JdbcClientDetailsService 必须按照的标准建立相关的数据库表,我们的已经有自己的账户表,不能使用这些创建的表。
我们首先研究InMemoryClientDetailsService里返回的ClientDetails实例值如下:
@Service
public class MyClientDetailsService implements ClientDetailsService {
@Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
System.out.println("clientId = " + clientId);
// 实际使用时,这里增加读数据库的操作,根据clientId获取账户信息,并根据下面代码的方式生成BaseClientDetails对象即可
BaseClientDetails baseClientDetails = new BaseClientDetails();
baseClientDetails.setClientId("clientapp");
// secret密码配置从 Spring Security 5.0开始必须以 {加密方式}+加密后的密码 这种格式填写
/*
* 当前版本5新增支持加密方式:
* bcrypt - BCryptPasswordEncoder (Also used for encoding)
* ldap - LdapShaPasswordEncoder
* MD4 - Md4PasswordEncoder
* MD5 - new MessageDigestPasswordEncoder("MD5")
* noop - NoOpPasswordEncoder
* pbkdf2 - Pbkdf2PasswordEncoder
* scrypt - SCryptPasswordEncoder
* SHA-1 - new MessageDigestPasswordEncoder("SHA-1")
* SHA-256 - new MessageDigestPasswordEncoder("SHA-256")
* sha256 - StandardPasswordEncoder
*/
baseClientDetails.setClientSecret("{noop}112233");
// 不可以设置为null
// baseClientDetails.setAutoApproveScopes(null);
List<String> scopeList = new ArrayList<>();
scopeList.add("read_userinfo"