justauth-spring-boot-security-starter
justauth-spring-boot-security-starter copied to clipboard
spring security 集成 JustAuth 实现第三方授权登录: 此项目从 UMS(用户管理脚手架:https://github.com/ZeroOrInfinity/UMS | https://gitee.com/pcore/UMS) 项目中分离. 1. 支持所有 justAuth 支持的第三方...
Spring security éæ JustAuth å®ç°ç¬¬ä¸æ¹ææç»å½èææ¶:
ä¸ãç¹æ§
Spring security éæ JustAuth å®ç°ç¬¬ä¸æ¹ææç»å½: æ¤é¡¹ç®ä» ç¨æ·ç®¡çèææ¶(UMS):https://github.com/ZeroOrInfinity/UMS | https://gitee.com/pcore/UMS) 项ç®ä¸å离.
- æ¯æææ justAuth æ¯æç第ä¸æ¹ç»å½ï¼ç»å½åèªå¨æ³¨å æ ç»å® æ å建临æ¶ç¨æ·(TemporaryUser).
- æ¯æå®æ¶å·æ° accessToken åå¸å¼å®æ¶ä»»å¡,
- æ¯æ第ä¸æ¹ææç»å½çç¨æ·ä¿¡æ¯è¡¨ä¸ token ä¿¡æ¯è¡¨ç redis ç¼ååè½.
- æ¯æ第ä¸æ¹ç»å®ä¸è§£ç»åæ¥è¯¢æ¥å£.
- æ¯æä¸é®ç»å½.
ç»å½æµç¨å¾
微信群ï¼UMS æ·»å 微信(z56133)å¤æ³¨(UMS)
äºãmaven
ï¼
<dependency>
<groupId>top.dcenter</groupId>
<artifactId>justAuth-spring-security-starter</artifactId>
<version>latest</version>
</dependency>
ä¸ã使ç¨è¯´æ:
1. å¼å
¥ä¾èµ
<dependency>
<groupId>top.dcenter</groupId>
<artifactId>justAuth-spring-security-starter</artifactId>
<version>latest</version>
</dependency>
2. å¿
é¡»å®ç°çæ¥å£
- æ¬å°ç¨æ·æå¡: UmsUserDetailsService
- å¼å¯ä¸é®ç»å½åè½æ¶: OneClickLoginService
3. å¿
须添å Auth2AutoConfigurer å° HttpSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private Auth2AutoConfigurer auth2AutoConfigurer;
@Autowired
private Auth2Properties auth2Properties;
@Override
protected void configure(HttpSecurity http) throws Exception {
// ========= start: ä½¿ç¨ justAuth-spring-security-starter å¿
é¡»æ¥éª¤ =========
// æ·»å Auth2AutoConfigurer 使 OAuth2(justAuth) login çæ.
http.apply(this.auth2AutoConfigurer);
http.csrf().disable();
// æ¾è¡ç¬¬ä¸æ¹ç»å½å
¥å£å°åä¸ç¬¬ä¸æ¹ç»å½åè°å°å
// @formatter:off
http.authorizeRequests()
.antMatchers(HttpMethod.GET,
auth2Properties.getRedirectUrlPrefix() + "/*",
auth2Properties.getAuthLoginUrlPrefix() + "/*")
.permitAll();
// @formatter:on
// ========= end: ä½¿ç¨ justAuth-spring-security-starter å¿
é¡»æ¥éª¤ =========
}
}
4. æ¥å£ä»ç»
- justAuth-spring-security-starter 大é¨ååè½å®ç°é½æ¯éè¿é
ç½®æ件设置å±æ§æ¥å®æç, 详ç»å±æ§é
置请æ¥ç
äºãå±æ§é ç½®å表
.
åãæ¥å£è¯´æ:
-
UmsUserDetailsService:
å¿ é¡»å®ç°
-
Auth2StateCoder:
ç¨æ·éè¦æ¶å®ç°
, 对第ä¸æ¹ææç»å½æµç¨ä¸ç state è¿è¡èªå®ä¹ç¼è§£ç . å¯ä»¥ä¼ éå¿ è¦çä¿¡æ¯, å¦: 第ä¸æ¹ç»å½æåç跳转å°åç 注ææ¤æ¥å£ç两个æ¹æ³å¿ é¡»åæ¶å®ç°å¯¹åºçç¼è§£ç é»è¾, å®ç°æ¤æ¥å£åæ³¨å ¥ IOC 容å¨å³å¯, å¦æå端åå端è·å authorizeUrl æ¶ååç«¯ä¼ éé¢å¤åæ° ä¸ç¨ä½æ³¨åæ¶çä¿¡æ¯, éé å UmsUserDetailsService.registerUser(AuthUser, String, String, String) æ¹æ³å®ç°. -
Auth2UserService: è·å第ä¸æ¹ç¨æ·ä¿¡æ¯çæ¥å£, ä¸è¬ä¸éè¦ç¨æ·å®ç°, é¤éæ³èªå®ä¹è·å第ä¸æ¹ç¨æ·ä¿¡æ¯çé»è¾, å®ç°æ¤æ¥å£æ³¨å ¥ IOC 容å¨å³å¯æ¿ä»£.
-
ConnectionService: 第ä¸æ¹ææç»å½ç¨æ·ç注å, ç»å®, æ´æ°ç¬¬ä¸æ¹ç¨æ·ä¿¡æ¯ä¸ accessToken ä¿¡æ¯çæ¥å£, ä¸è¬ä¸éè¦ç¨æ·å®ç°. é¤éæ³èªå®ä¹è·å第ä¸æ¹ç¨æ·ä¿¡æ¯çé»è¾, å®ç°æ¤æ¥å£æ³¨å ¥ IOC 容å¨å³å¯æ¿ä»£.
-
UsersConnectionRepository: 第ä¸æ¹ææç»å½ç第ä¸æ¹ç¨æ·ä¿¡æ¯å¢å æ¹æ¥, ç»å®ä¸è§£ç»åæ¥è¯¢æ¯å¦ç»å®ä¸è§£ç»æ¥å£, ä¸è¬ä¸éè¦ç¨æ·å®ç°. é¤éæ³èªå®ä¹è·å第ä¸æ¹ç¨æ·ä¿¡æ¯çé»è¾, å®ç°æ¤æ¥å£æ³¨å ¥ IOC 容å¨å³å¯æ¿ä»£.
-
UsersConnectionTokenRepository: 第ä¸æ¹ææç»å½ç¨æ· accessToken ä¿¡æ¯è¡¨å¢å æ¹æ¥æ¥å£, ä¸è¬ä¸éè¦ç¨æ·å®ç°. é¤éæ³èªå®ä¹è·å第ä¸æ¹ç¨æ·ä¿¡æ¯çé»è¾, å®ç°æ¤æ¥å£æ³¨å ¥ IOC 容å¨å³å¯æ¿ä»£.
åæ¶ OAuth2 çå ç½®æ°æ®åºè¯´æ
ä¸. åæ¶åæ¶ç¬¬ä¸æ¹ç»å½ç user_connection ä¸ auth_token 表
1. å±æ§é ç½®
ums: oauth: # æ¯å¦æ¯æå ç½®ç第ä¸æ¹ç»å½ç¨æ·è¡¨(user_connection) å auth_token 表. é»è®¤: true. # 注æ: å¦æ为 false, åå¿ é¡»éæ°å®ç° ConnectionService æ¥å£. enable-user-connection-and-auth-token-table: false
2. å¿ é¡»éæ°å®ç°
top.dcenter.ums.security.core.oauth.signup.ConnectionService
æ¥å£äº. åæ¶ç¬¬ä¸æ¹ç»å½ auth_token 表
1. å±æ§é ç½®
ums: oauth: # æ¯å¦æ¯æå ç½®ç第ä¸æ¹ç»å½ token 表(auth_token). é»è®¤: true. enable-auth-token-table: false
-
-
èªå®ä¹ OAuth2 Login æ©å±æ¥å£: å 置两个èªå®ä¹ providerId(ums.oauth.customize ä¸ ums.oauth.gitlabPrivate)
-
AuthGitlabPrivateSource: æ½è±¡ç±», å®ç°æ¤èªå®ä¹ç AuthGitlabPrivateSource ä¸æ³¨å ¥ ioc 容å¨çåæ¶, å¿ é¡»å®ç° AuthCustomizeRequest , ä¼èªå¨éæè¿ OAuth2 Login é»è¾æµç¨ä¸, åªéè¦å JustAuth é»è®¤å®ç°ç第ä¸æ¹ç»å½ä¸æ ·, é ç½®ç¸åºçå±æ§(ums.oauth.gitlabPrivate.[clientId|clientSecret]çå±æ§)å³å¯.
-
AuthCustomizeSource: æ½è±¡ç±», å®ç°æ¤èªå®ä¹ç AuthCustomizeSource ä¸æ³¨å ¥ ioc 容å¨çåæ¶, å¿ é¡»å®ç° AuthCustomizeRequest , ä¼èªå¨éæè¿ OAuth2 Login é»è¾æµç¨ä¸, åªéè¦å JustAuth é»è®¤å®ç°ç第ä¸æ¹ç»å½ä¸æ ·, é ç½®ç¸åºçå±æ§(ums.oauth.customize.[clientId|clientSecret]çå±æ§)å³å¯.
-
AuthCustomizeRequest: æ½è±¡ç±», å®ç°æ¤èªå®ä¹ç AuthCustomizeRequest åæ¶, å¿ é¡»å®ç° AuthCustomizeSource æ AuthGitlabPrivateSource ä¸æ³¨å ¥ ioc 容å¨, ä¼èªå¨éæè¿ OAuth2 Login é»è¾æµç¨ä¸, åªéè¦å JustAuth é»è®¤å®ç°ç第ä¸æ¹ç»å½ä¸æ ·, é ç½®ç¸åºçå±æ§(ums.oauth.customize.[clientId|clientSecret]çå±æ§)å³å¯.
-
-
OneClickLoginService: ä¸é®ç»å½åè½å¼å¯æ¶,
å¿ é¡»å®ç°
æ¤æ¥å£, æ ¹æ® accessToken ä»æå¡åè·åç¨æ·ææºå·.
äºãJackson åºååä¸ååºåå
- æ·»å ä¸äº Authentication ä¸ UserDetails åç±»çååºååå¨, ä»¥è§£å³ redis ç¼åä¸è½ååºååæ¤ç±»åçé®é¢, å ·ä½é ç½® redis ååºåå¨çé 置请ç RedisCacheAutoConfiguration.getJackson2JsonRedisSerializer() æ¹æ³.
// 示ä¾
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
// Auth2Jackson2Module 为æ¤é¡¹ç®å®ç°çååºååé
ç½®
objectMapper.registerModules(new CoreJackson2Module(), new WebJackson2Module(), new Auth2Jackson2Module());
jackson2JsonRedisSerializer.setObjectMapper(om);
- 注æ: UmsUserDetailsService
ç注åç¨æ·æ¹æ³è¿åç
UserDetails
çé»è®¤å®ç°User
å·²å®ç°ååºååå¨, å¦ææ¯å¼åè èªå®ä¹çåç±», éå¼åè èªå·±å®ç°ååºååå¨.
å
ãå¿«éå¼å§(Quick Start)
ï¼
1. æ·»å ä¾èµ(Add Dependency):
<dependency>
<groupId>top.dcenter</groupId>
<artifactId>justAuth-spring-security-starter</artifactId>
<version>latest</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<!-- 第ä¸æ¹ææç»å½é»è®¤ä¼æç
§ä¸é¢çä¼å
级èªè¡å¯»æ¾ä¸ç§ HTTP å·¥å
·ä¾èµï¼java 11 HttpClient -> OkHttp3 -> apache HttpClient -> hutool-http
示ä¾ä½¿ç¨ apache HttpClient .
注æ: å¦ææ¯ JDK11 åä¸éè¦æ¤ä¾èµ-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.12</version>
</dependency>
ä¾èµè¯´æ: å¦ææ¯ JDK-1.8 ç¯å¢, ä»»éä¸ç§ HTTP å·¥å ·ä¾èµï¼é¡¹ç®å å¦æå·²æï¼è¯·å¿½ç¥ãå¦å¤éè¦ç¹å«æ³¨æï¼å¦æ项ç®ä¸å·²ç»å¼å ¥äºä½çæ¬çä¾èµï¼è¯·å æé¤ä½çæ¬ä»¥åæ¥ï¼å¼å ¥é«çæ¬æè ææ°çæ¬çä¾èµ
-
hutool-http
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId>
<version>5.2.5</version>
</dependency>
-
httpclient
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.12</version>
</dependency>
-
okhttp
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.4.1</version>
</dependency>
2. config:
server:
port: 9090
spring:
profiles:
active: dev
# mysql
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/ums?useSSL=false&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai
username: root
password: 123456
# session ç®åé
ç½®
session:
# session åå¨æ¨¡å¼è®¾ç½®, è¦å¯¼å
¥ç¸åºç spring-session ç±»çä¾èµ, é»è®¤ä¸º none, åå¸å¼åºç¨æ session æ¾å
¥ redis çä¸é´ä»¶
store-type: none
# session è¿ææ¶é´
timeout: PT300s
# ums core
ums:
# ================ 第ä¸æ¹ææç»å½ç¸å
³é
ç½® ================
oauth:
# æ¯å¦æ¯æ第ä¸æ¹ææç»å½åè½, é»è®¤: true
enabled: true
# æå¶åå°è¦å, æ¯æ JDK11, é»è®¤: false , å¨ç¡®è®¤ WARNING: An illegal reflective access operation has occurred å®å
¨å, å¯ä»¥æå¼æ¤è®¾ç½®, å¯ä»¥æå¶åå°è¦å.
suppress-reflect-warning: true
# 第ä¸æ¹æå¡å: providerId, æ¯æææ JustAuth æ¯æç第ä¸æ¹ææç»å½, ç®åæ 32 家第ä¸æ¹ææç»å½
github:
# æ ¹æ®æ¯å¦æ设置 clientId æ¥å¨æå è½½ç¸åº JustAuth ç AuthXxxRequest
client-id: 4d4ee00e82f669f2ea8d
client-secret: 953ddbe871a08d6924053531e89ecc01d87195a8
gitee:
client-id: dcc38c801ee88f43cfc1d5c52ec579751c12610c37b87428331bd6694056648e
client-secret: e60a110a2f6e7c930c2d416f802bec6061e19bfa0ceb0df9f6b182b05d8f5a58
# 第ä¸æ¹ç»å½ææç»å½ url åç¼, ä¸å
å« ServletContextPathï¼é»è®¤ä¸º /auth2/authorization.
auth-login-url-prefix: /auth2/authorization
# 第ä¸æ¹ç»å½åè°å¤ç url åç¼ ï¼ä¹å°±æ¯ RedirectUrl çåç¼, ä¸å
å« ServletContextPathï¼é»è®¤ä¸º /auth2/login.
redirect-url-prefix: /auth2/login
# 第ä¸æ¹ç»å½åè°çåå, ä¾å¦ï¼http://localhost:9090 é»è®¤ä¸º "http://127.0.0.1"ï¼
# redirectUrl ç´æ¥ç± {domain}/{servletContextPath}/{redirectUrlPrefix}/{providerId}(ums.oauth.[qq/gitee/weibo])ç»æ
domain: http://localhost:9090
# 第ä¸æ¹ææç»å½æååçé»è®¤æé, å¤ä¸ªæéç¨éå·åå¼, é»è®¤ä¸º: "ROLE_USER"
default-authorities: ROLE_USER
# ç¨äº JustAuth ç代ç(HttpClient)设置
proxy:
# ç¨äºå½å
代ç(HttpClient)è¶
æ¶, é»è®¤ PT3S
timeout: PT3S
# ç¨äºå½å¤ç½ç«ä»£ç(HttpClient)è¶
æ¶, é»è®¤ PT15S
foreign-timeout: PT150S
---
spring:
profiles: dev
mvc:
throw-exception-if-no-handler-found: true
#debug: true
server:
port: 9090
servlet:
context-path: /demo
3. å¿ é¡»å®ç° UmsUserDetailsService æ¥å£:
UserDetailsServiceImpl.java
import me.zhyd.oauth.model.AuthUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserCache;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import top.dcenter.ums.security.core.oauth.enums.ErrorCodeEnum;
import top.dcenter.ums.security.core.oauth.exception.RegisterUserFailureException;
import top.dcenter.ums.security.core.oauth.exception.UserNotExistException;
import top.dcenter.ums.security.core.oauth.service.UmsUserDetailsService;
import java.util.List;
/**
* ç¨æ·å¯ç ä¸ææºçä¿¡ç»å½ä¸æ³¨åæå¡ï¼<br><br>
* 1. ç¨äºç¬¬ä¸æ¹ç»å½ä¸ææºçä¿¡ç»å½é»è¾ã<br><br>
* 2. ç¨äºç¨æ·å¯ç ç»å½é»è¾ã<br><br>
* 3. ç¨æ·æ³¨åé»è¾ã<br><br>
* @author YongWu zheng
* @version V1.0 Created by 2020/9/20 11:06
*/
@Service
public class UserDetailsServiceImpl implements UmsUserDetailsService {
private final Logger log = LoggerFactory.getLogger(this.getClass());
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@Autowired(required = false)
private UserCache userCache;
/**
* ç¨äºå¯ç å 解å¯
*/
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@Autowired
private PasswordEncoder passwordEncoder;
@SuppressWarnings("AlibabaUndefineMagicConstant")
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
try
{
// ä»ç¼åä¸æ¥è¯¢ç¨æ·ä¿¡æ¯:
// ä»ç¼åä¸æ¥è¯¢ç¨æ·ä¿¡æ¯
if (this.userCache != null)
{
UserDetails userDetails = this.userCache.getUserFromCache(username);
if (userDetails != null)
{
return userDetails;
}
}
// æ ¹æ®ç¨æ·åè·åç¨æ·ä¿¡æ¯
// è·åç¨æ·ä¿¡æ¯é»è¾ããã
// ...
// 示ä¾ï¼åªæ¯ä»ç¨æ·ç»å½æ¥å¿è¡¨ä¸æåçä¿¡æ¯ï¼
log.info("Demo ======>: ç»å½ç¨æ·åï¼{}, ç»å½æå", username);
return new User(username,
passwordEncoder.encode("admin"),
true,
true,
true,
true,
AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_VISIT, ROLE_USER"));
}
catch (Exception e)
{
String msg = String.format("Demo ======>: ç»å½ç¨æ·åï¼%s, ç»å½å¤±è´¥: %s", username, e.getMessage());
log.error(msg);
throw new UserNotExistException(ErrorCodeEnum.QUERY_USER_INFO_ERROR, e, username);
}
}
@Override
public UserDetails registerUser(AuthUser authUser, String username, String defaultAuthority, String decodeState) throws RegisterUserFailureException {
// 第ä¸æ¹ææç»å½ä¸éè¦å¯ç , è¿éé便设置ç, çæç¯å¢æèªå·±çé»è¾
String encodedPassword = passwordEncoder.encode(authUser.getUuid());
// è¿éç decodeState å¯ä»¥æ ¹æ®èªå·±å®ç°ç top.dcenter.ums.security.core.oauth.service.Auth2StateCoder æ¥å£çé»è¾æ¥ä¼ éå¿
è¦çåæ°.
// æ¯å¦: 第ä¸æ¹ç»å½æååç跳转å°å
final RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
// å设 decodeState å°±æ¯ redirectUrl, æ们ç´æ¥æ redirectUrl è®¾ç½®å° request ä¸
// åç»ç»è¿æåå¤çå¨æ¶ç´æ¥ä» requestAttributes.getAttribute("redirectUrl", RequestAttributes.SCOPE_REQUEST) è·å并跳转
requestAttributes.setAttribute("redirectUrl", decodeState, RequestAttributes.SCOPE_REQUEST);
// å½ç¶ decodeState ä¹å¯ä»¥ä¼ éä»åç«¯ä¼ å°å端çç¨æ·ä¿¡æ¯, 注åå°æ¬å°ç¨æ·
List<GrantedAuthority> grantedAuthorities = AuthorityUtils.commaSeparatedStringToAuthorityList(defaultAuthority);
// ... ç¨æ·æ³¨åé»è¾
log.info("Demo ======>: ç¨æ·åï¼{}, 注åæå", username);
// @formatter:off
UserDetails user = User.builder()
.username(username)
.password(encodedPassword)
.disabled(false)
.accountExpired(false)
.accountLocked(false)
.credentialsExpired(false)
.authorities(grantedAuthorities)
.build();
// @formatter:off
// æç¨æ·ä¿¡æ¯åå
¥ç¼å
if (userCache != null)
{
userCache.putUserInCache(user);
}
return user;
}
@Override
public UserDetails loadUserByUserId(String userId) throws UsernameNotFoundException {
UserDetails userDetails = loadUserByUsername(userId);
User.withUserDetails(userDetails);
return User.withUserDetails(userDetails).build();
}
/**
* {@link #existedByUsernames(String...)} usernames çæè§å.
* å¦éèªå®ä¹éæ°å®ç°æ¤é»è¾
* @param authUser 第ä¸æ¹ç¨æ·ä¿¡æ¯
* @return è¿åä¸ä¸ª username æ°ç»
*/
@Override
public String[] generateUsernames(AuthUser authUser) {
return new String[]{
authUser.getUsername(),
// providerId = authUser.getSource()
authUser.getUsername() + "_" + authUser.getSource(),
// providerUserId = authUser.getUuid()
authUser.getUsername() + "_" + authUser.getSource() + "_" + authUser.getUuid()
};
}
@Override
public List<Boolean> existedByUsernames(String... usernames) throws UsernameNotFoundException {
// ... å¨æ¬å°è´¦æ·ä¸æ¥è¯¢ userIds æ¯å¦å·²è¢«ä½¿ç¨
List<Boolean> list = new ArrayList<>();
list.add(true);
list.add(false);
list.add(false);
return list;
}
}
4. å¿ é¡»æ·»å top.dcenter.ums.security.core.oauth.config.Auth2AutoConfigurer å° HttpSecurity
WebSecurityConfig.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import top.dcenter.ums.security.core.oauth.config.Auth2AutoConfigurer;
import top.dcenter.ums.security.core.oauth.properties.Auth2Properties;
/**
* web security config
* @author YongWu zheng
* @version V2.0 Created by 2020/10/18 22:39
*/
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private Auth2AutoConfigurer auth2AutoConfigurer;
@Autowired
private Auth2Properties auth2Properties;
@Bean
public PasswordEncoder passwordEncoder() {
/*
é»è®¤ä¸º BCryptPasswordEncoder çå®ç°äºæ·»å éæº salt ç®æ³ï¼å¹¶ä¸è½ä»hashåçå符串ä¸è·å salt è¿è¡åå§å¯ç ä¸hashåçå¯ç ç对æ¯
æ¯ææ ¼å¼:
{bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
{noop}password
{pbkdf2}5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc
{scrypt}$e0801$8bWJaSu2IKSn9Z9kM+TPXfOc/9bdYSrN1oD9qfVThWEwdRTnO7re7Ei+fUZRJ68k9lTyuTeUp4of4g24hHnazw==$OAOec05+bXxvuu/1qZ6NUR+xQYvYv7BeL1QxwRpY5Pc=
{sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0
*/
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
.loginPage("/login.html")
.defaultSuccessUrl("/index.html");
http.logout().logoutSuccessUrl("/login.html");
http.csrf().disable();
// ========= start: ä½¿ç¨ justAuth-spring-security-starter å¿
é¡»æ¥éª¤ =========
// æ·»å Auth2AutoConfigurer 使 OAuth2(justAuth) login çæ.
http.apply(this.auth2AutoConfigurer);
// æ¾è¡ç¬¬ä¸æ¹ç»å½å
¥å£å°åä¸ç¬¬ä¸æ¹ç»å½åè°å°å
// @formatter:off
http.authorizeRequests()
.antMatchers(HttpMethod.GET,
auth2Properties.getRedirectUrlPrefix() + "/*",
auth2Properties.getAuthLoginUrlPrefix() + "/*")
.permitAll();
// @formatter:on
// ========= end: ä½¿ç¨ justAuth-spring-security-starter å¿
é¡»æ¥éª¤ =========
http.authorizeRequests().anyRequest().permitAll();
}
}
4. åç«¯é¡µé¢ :
login.html: æ¾å¨ classpath:/static
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ç»å½</title>
</head>
<body>
<h2>ç»å½é¡µé¢</h2>
<h3>社交ç»å½</h3>
<a href="/demo/auth2/authorization/gitee">giteeç»å½</a>
<a href="/demo/auth2/authorization/github">githubç»å½</a>
<a href="/demo/auth2/authorization/qq">qqç»å½</a>
</body>
</html>
index.html: æ¾å¨ classpath:/static
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
hello world!<br>
<form action="/demo/logout?logout" method="post">
<input type="submit" value="éåºç»å½post"/>
</form>
<br>
<br>
<a href="/demo/auth2/authorization/gitee">giteeç»å½</a>
<a href="/demo/auth2/authorization/github">githubç»å½</a>
<a href="/demo/auth2/authorization/qq">qqç»å½</a>
</body>
</html>
5. 访é®å端页é¢
- æµè§å¨è®¿é®
http://localhost:9090/demo/login.html
, è³æ¤éæäºï¼ç¬¬ä¸æ¹ç»å½(justAuth-spring-security-starter); å®ç°å¿«éå¼åã - 详ç»é ç½®é ç½®å¨: justAuth-security-oauth2-example
ä¸ãæ¶åºå¾(Sequence Diagram)
: éççæ¬è¿ä»£ä¼æåºå
¥
å
«ãå±æ§é
ç½®å表
OAuth2 / refreshToken å®æ¶ä»»å¡ / JustAuth é ç½®å±æ§
å±æ§ | ç±»å | é»è®¤å¼ | æè¿° | å¯é项 |
---|---|---|---|---|
ums.oauth.autoSignUp | Boolean | true | 第ä¸æ¹ææç»å½åå¦æªæ³¨åç¨æ·æ¯å¦æ¯æèªå¨æ³¨ååè½, é»è®¤: true | true/false |
ums.oauth.signUpUrl | String | /signUp.html | 第ä¸æ¹ææç»å½åå¦æªæ³¨åç¨æ·ä¸æ¯æèªå¨æ³¨ååè½, å跳转å°æ¤ url è¿è¡æ³¨åé»è¾, æ¤ url å¿
é¡»å¼åè
èªå·±å®ç°; é»è®¤: /signUp.html ; ä¾å¦: 1. è®¾ç½®å¼ "/signUp" , å跳转æå®å° "/signUp" è¿è¡æ³¨å. 2. æ³è¿åèªå®ä¹ json æ°æ®å°å端, è¿éè¦è®¾ç½® null , å¨ Auth2LoginAuthenticationFilter 设置ç AuthenticationSuccessHandler ä¸å¤çè¿å json; å¤ææ¯å¦ä¸ºä¸´æ¶ç¨æ·çæ¡ä»¶æ¯: Authentication.getPrincipal() æ¯å¦ä¸º TemporaryUser ç±»å. |
|
ums.oauth.temporaryUserPassword | String | "" | ç¨äºç¬¬ä¸æ¹ææç»å½æ¶, æªå¼å¯èªå¨æ³¨åä¸ç¨æ·æ¯ç¬¬ä¸æ¬¡ææç»å½ç临æ¶ç¨æ·å¯ç , é»è®¤ä¸º: "". 注æ: ç产ç¯å¢æ´æ¢å¯ç | |
ums.oauth.temporaryUserAuthorities | String | "ROLE_TEMPORARY_USER" | ç¨äºç¬¬ä¸æ¹ææç»å½æ¶, æªå¼å¯èªå¨æ³¨åä¸ç¨æ·æ¯ç¬¬ä¸æ¬¡ææç»å½ç临æ¶ç¨æ·çé»è®¤æé, å¤ä¸ªæéç¨éå·åå¼, é»è®¤ä¸º: "ROLE_TEMPORARY_USER" | |
ums.oauth.domain | String | http://127.0.0.1 | 第ä¸æ¹ç»å½åè°çåå, ä¾å¦ï¼https://localhost é»è®¤ä¸º "http://127.0.0.1"ï¼ redirectUrl ç´æ¥ç± {domain}/{servletContextPath}/{redirectUrlPrefix}/{providerId}(ums.oauth.[qq/gitee/weibo]) ç»æ |
|
ums.oauth.redirectUrlPrefix | String | /oauth/login | 第ä¸æ¹ç»å½åè°å¤ç url åç¼ ï¼ä¹å°±æ¯ RedirectUrl çåç¼, ä¸å
å« ServletContextPath ï¼é»è®¤ä¸º /oauth/login |
|
ums.oauth.authLoginUrlPrefix | String | /oauth/authorization | 第ä¸æ¹ç»å½ææç»å½ url åç¼, ä¸å
å« ServletContextPath ï¼é»è®¤ä¸º /oauth/authorization |
|
ums.oauth.temporaryUserAuthorities | String | ROLE_USER | 第ä¸æ¹ææç»å½æååçé»è®¤æé, å¤ä¸ªæéç¨éå·åå¼, é»è®¤ä¸º: "ROLE_USER" | |
ums.oauth.suppressReflectWarning | Boolean | false | æå¶åå°è¦å, æ¯æ JDK11, é»è®¤: false , å¨ç¡®è®¤ WARNING: An illegal reflective access operation has occurred å®å ¨å, å¯ä»¥æå¼æ¤è®¾ç½®, å¯ä»¥æå¶åå°è¦å. | true/false |
ums.oauth.enableUserConnectionAndAuthTokenTable | Boolean | true | æ¯å¦æ¯æå
ç½®ç第ä¸æ¹ç»å½ç¨æ·è¡¨(user_connection ) å 第ä¸æ¹ç»å½ token 表(auth_token ). é»è®¤: true . 注æ: å¦æ为 false , åå¿
é¡»éæ°å®ç° ConnectionService æ¥å£. |
true/false |
ums.oauth.enableAuthTokenTable | Boolean | true | æ¯å¦æ¯æå
ç½®ç第ä¸æ¹ç»å½ token 表(auth_token ). é»è®¤: true . |
true/false |
refreshToken å®æ¶ä»»å¡ | ||||
ums.oauth.refreshTokenJobCron | String | 0 * 2 * * ? | A cron-like expression.0 * 2 * * ? åå«å¯¹åº: second/minute/hour/day of month/month/day of week é»è®¤ä¸º: "0 * 2 * * ?", åæ¨ 2 ç¹å¯å¨å®æ¶ä»»å¡, æ¯æåå¸å¼(åå¸å¼ IOC 容å¨ä¸å¿ é¡»æ RedisConnectionFactory , ä¹å°±æ¯è¯´, æ¯å¦åå¸å¼æ§è¡ä¾æ® IOC 容å¨ä¸æ¯å¦æ RedisConnectionFactory ) |
|
ums.oauth.enableRefreshTokenJob | Boolean | false | æ¯å¦æ¯æå®æ¶å·æ° AccessToken å®æ¶ä»»å¡, èèå°å¾å¤åºç¨é½æèªå·±çå®æ¶ä»»å¡åºç¨, é»è®¤: false . RefreshTokenJob æ¥å£çå®ç°å·²æ³¨å
¥ IOC 容å¨, æ¹ä¾¿èªå®ä¹å®æ¶ä»»å¡æ¥å£æ¶è°ç¨. æ¯æåå¸å¼(åå¸å¼ IOC 容å¨ä¸å¿
é¡»æ RedisConnectionFactory , ä¹å°±æ¯è¯´, æ¯å¦åå¸å¼æ§è¡ä¾æ® IOC 容å¨ä¸æ¯å¦æ RedisConnectionFactory ) |
true/false |
ums.oauth.batchCount | Integer | 1000 | å®æ¶å·æ° accessToken ä»»å¡æ¶, æ¹å¤çæ°æ®åºçè®°å½æ°. 注æ: åå¸å¼åºç¨æ¶, æ¤é
ç½®ä¸åæå¡å¨é
ç½®å¿
é¡»æ¯ä¸æ ·ç. batchCount 大å°éè¦æ ¹æ®å®é
ç产ç¯å¢è¿è¡ä¼å |
|
ums.oauth.remainingExpireIn | Integer | 24 | accessToken çå©ä½æææå
è¿è¡å·æ° accessToken , é»è®¤: 24, åä½: å°æ¶. 注æ: éè¦æ ¹æ®å®é
ç产ç¯å¢è¿è¡ä¼å |
|
justAuth | ||||
ums.oauth.justAuth.ignoreCheckState | Boolean | false | 忽ç¥æ ¡éª state åæ°ï¼é»è®¤ä¸å¼å¯ãå½ ignoreCheckState 为 true æ¶ï¼ me.zhyd.oauth.request.AuthDefaultRequest.login(AuthCallback) å°ä¸ä¼æ ¡éª state çåæ³æ§ã 使ç¨åºæ¯ï¼å½ä¸ä» å½ä½¿ç¨èªå®ç° state æ ¡éªé»è¾æ¶å¼å¯ 以ä¸åºæ¯ä½¿ç¨æ¹æ¡ä» ä½åèï¼ 1. ææãç»å½ä¸ºå端ï¼å¹¶ä¸å ¨é¨ä½¿ç¨ JustAuth å®ç°æ¶ï¼è¯¥å¼å»ºè®®è®¾ä¸º false; 2. ææåç»å½ä¸ºä¸å端å®ç°æ¶ï¼æ¯å¦å端页é¢æ¼è£ authorizeUrlï¼å¹¶ä¸å端èªè¡å¯¹stateè¿è¡æ ¡éªï¼ å端åªè´è´£ä½¿ç¨codeè·åç¨æ·ä¿¡æ¯æ¶ï¼è¯¥å¼å»ºè®®è®¾ä¸º true; å¦éç¹æ®éè¦ï¼ä¸å»ºè®®å¼å¯è¿ä¸ªé ç½® 该æ¹æ¡ä¸»è¦ä¸ºäºè§£å³ä»¥ä¸ç±»ä¼¼åºæ¯çé®é¢ï¼ |
true/false |
ums.oauth.justAuth.timeout | Duration | PT180S | é»è®¤ state ç¼åè¿ææ¶é´ï¼3åé(PT180S) é´äºææè¿ç¨ä¸ï¼æ ¹æ®ä¸ªäººçæä½ä¹ æ¯ï¼æè ææå¹³å°çä¸åï¼googleçï¼ï¼æ¯ä¸ªæææµç¨çèæ¶ä¹æå·®å¼ï¼ä¸è¿å个æææµç¨ä¸è¬ä¸ä¼å¤ªé¿ æ¬ç¼åå·¥å ·é»è®¤çè¿ææ¶é´è®¾ç½®ä¸º3åéï¼å³ç¨åºé»è®¤è®¤ä¸º3åéå çææææï¼è¶ è¿3åéåé»è®¤å¤±æï¼å¤±æåå é¤ | |
ums.oauth.justAuth.cacheType | StateCacheType | SESSION | JustAuth state ç¼åç±»å, é»è®¤ session | DEFAULT/SESSION/REDIS |
ums.oauth.justAuth.cacheKeyPrefix | String | JUST_AUTH: | JustAuth state ç¼å key åç¼ | |
proxy | ||||
ums.oauth.proxy.enable | Boolean | false | æ¯å¦æ¯æ代ç, é»è®¤ä¸º: false. å½ä¸º false æ¶, å ¶ä»å±æ§é½å¤±æ. | true/false |
ums.oauth.proxy.proxy | Proxy.Type | HTTP | é对å½å¤æå¡å¯ä»¥åç¬è®¾ç½®ä»£çç±»å, é»è®¤ Proxy.Type.HTTP | HTTP/DIRECT/SOCKS |
ums.oauth.proxy.hostname | String | 代ç host, enable = true æ¶çæ. | ||
ums.oauth.proxy.port | Integer | 代ç端å£, enable = true æ¶çæ. | ||
ums.oauth.proxy.timeout | Duration | PT3S | 代çè¶ æ¶, é»è®¤ PT3S | |
ums.oauth.proxy.foreignTimeout | Duration | PT15S | ç¨äºå½å¤ç½ç«ä»£çè¶ æ¶, é»è®¤ PT15S | |
github | ||||
ums.oauth.github.clientId | String | client Id |
||
ums.oauth.github.clientSecret | String | client Secret |
||
ums.oauth.github.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
ums.oauth.weibo.clientId | String | client Id |
||
ums.oauth.weibo.clientSecret | String | client Secret |
||
ums.oauth.weibo.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
gitee | ||||
ums.oauth.gitee.clientId | String | client Id |
||
ums.oauth.gitee.clientSecret | String | client Secret |
||
ums.oauth.gitee.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
dingtalk | ||||
ums.oauth.dingtalk.clientId | String | client Id |
||
ums.oauth.dingtalk.clientSecret | String | client Secret |
||
baidu | ||||
ums.oauth.baidu.clientId | String | client Id |
||
ums.oauth.baidu.clientSecret | String | client Secret |
||
ums.oauth.baidu.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
coding | ||||
ums.oauth.coding.clientId | String | client Id |
||
ums.oauth.coding.clientSecret | String | client Secret |
||
ums.oauth.coding.codingGroupName | String | ä½¿ç¨ Coding ç»å½æ¶ï¼éè¦ä¼ 该å¼ã å¢éåååç¼ï¼æ¯å¦ä»¥â https://justauth.coding.net/ â为ä¾ï¼``codingGroupName = justauth` |
||
ums.oauth.coding.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
oschina | ||||
ums.oauth.oschina.clientId | String | client Id |
||
ums.oauth.oschina.clientSecret | String | client Secret |
||
alipay | ||||
ums.oauth.alipay.clientId | String | client Id |
||
ums.oauth.alipay.clientSecret | String | client Secret |
||
ums.oauth.alipay.alipayPublicKey | String | æ¯ä»å®å ¬é¥ï¼å½éæ©æ¯ä»å®ç»å½æ¶ï¼è¯¥å¼å¯ç¨ 对åºâRSA2(SHA256)å¯é¥âä¸çâæ¯ä»å®å ¬é¥â | ||
ums.oauth.alipay.proxyHost | String | æ¯ä»å®: æ¯ä»å®æèªå·±ç代ç, é»è®¤ä»£ç对æ¯ä»å®ä¸çæ, 代ç主æº: | ||
ums.oauth.alipay.proxyPort | Integer | æ¯ä»å®: æ¯ä»å®æèªå·±ç代ç, é»è®¤ä»£ç对æ¯ä»å®ä¸çæ, 代ç端å£: | ||
ums.oauth.qq.clientId | String | client Id |
||
ums.oauth.qq.clientSecret | String | client Secret |
||
ums.oauth.qq.unionId | String | æ¯å¦éè¦ç³è¯· unionIdï¼é»è®¤: false. ç®ååªé对qqç»å½ 注ï¼qqææç»å½æ¶ï¼è·å unionId éè¦åç¬åéé®ä»¶ç³è¯·æéãå¦æ个人å¼åè è´¦å·ä¸ç³è¯·äºè¯¥æéï¼å¯ä»¥å°è¯¥å¼ç½®ä¸ºtrueï¼å¨è·åopenIdæ¶å°±ä¼åæ¥è·åunionId åèé¾æ¥ï¼http://wiki.connect.qq.com/unionid%E4%BB%8B%E7%BB%8D | ||
ums.oauth.qq.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
wechatOpen | ||||
ums.oauth.wechatOpen.clientId | String | client Id |
||
ums.oauth.wechatOpen.clientSecret | String | client Secret |
||
wechatMp | ||||
ums.oauth.wechatMp.clientId | String | client Id |
||
ums.oauth.wechatMp.clientSecret | String | client Secret |
||
ums.oauth.wechatMp.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
taobao | ||||
ums.oauth.taobao.clientId | String | client Id |
||
ums.oauth.taobao.clientSecret | String | client Secret |
||
ums.oauth.taobao.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
ums.oauth.google.clientId | String | client Id |
||
ums.oauth.google.clientSecret | String | client Secret |
||
ums.oauth.google.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
ums.oauth.facebook.clientId | String | client Id |
||
ums.oauth.facebook.clientSecret | String | client Secret |
||
ums.oauth.facebook.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
github | ||||
ums.oauth.github.clientId | String | client Id |
||
ums.oauth.github.clientSecret | String | client Secret |
||
ums.oauth.github.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
douyin | ||||
ums.oauth.douyin.clientId | String | client Id |
||
ums.oauth.douyin.clientSecret | String | client Secret |
||
ums.oauth.linkedin.clientId | String | client Id |
||
ums.oauth.linkedin.clientSecret | String | client Secret |
||
ums.oauth.linkedin.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
microsoft | ||||
ums.oauth.microsoft.clientId | String | client Id |
||
ums.oauth.microsoft.clientSecret | String | client Secret |
||
ums.oauth.microsoft.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
mi | ||||
ums.oauth.mi.clientId | String | client Id |
||
ums.oauth.mi.clientSecret | String | client Secret |
||
ums.oauth.mi.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
toutiao | ||||
ums.oauth.toutiao.clientId | String | client Id |
||
ums.oauth.toutiao.clientSecret | String | client Secret |
||
teambition | ||||
ums.oauth.teambition.clientId | String | client Id |
||
ums.oauth.teambition.clientSecret | String | client Secret |
||
renren | ||||
ums.oauth.renren.clientId | String | client Id |
||
ums.oauth.renren.clientSecret | String | client Secret |
||
ums.oauth.renren.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
ums.oauth.pinterest.clientId | String | client Id |
||
ums.oauth.pinterest.clientSecret | String | client Secret |
||
ums.oauth.pinterest.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
stackOverflow | ||||
ums.oauth.stackOverflow.clientId | String | client Id |
||
ums.oauth.stackOverflow.clientSecret | String | client Secret |
||
ums.oauth.stackOverflow.stackOverflowKey | String | Stack Overflow Key | ||
ums.oauth.stackOverflow.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
huawei | ||||
ums.oauth.huawei.clientId | String | client Id |
||
ums.oauth.huawei.clientSecret | String | client Secret |
||
ums.oauth.huawei.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
wechatEnterprise ä¼ä¸å¾®ä¿¡äºç»´ç ç | ||||
ums.oauth.wechatEnterprise.clientId | String | client Id |
||
ums.oauth.wechatEnterprise.clientSecret | String | client Secret |
||
ums.oauth.wechatEnterprise.agentId | String | ä¼ä¸å¾®ä¿¡ï¼æææ¹çç½é¡µåºç¨ID | ||
kujiale | ||||
ums.oauth.kujiale.clientId | String | client Id |
||
ums.oauth.kujiale.clientSecret | String | client Secret |
||
ums.oauth.kujiale.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
gitlab | ||||
ums.oauth.gitlab.clientId | String | client Id |
||
ums.oauth.gitlab.clientSecret | String | client Secret |
||
ums.oauth.gitlab.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
meituan | ||||
ums.oauth.meituan.clientId | String | client Id |
||
ums.oauth.meituan.clientSecret | String | client Secret |
||
eleme | ||||
ums.oauth.eleme.clientId | String | client Id |
||
ums.oauth.eleme.clientSecret | String | client Secret |
||
ums.oauth.twitter.clientId | String | client Id |
||
ums.oauth.twitter.clientSecret | String | client Secret |
||
jd | ||||
ums.oauth.jd.clientId | String | client Id |
||
ums.oauth.jd.clientSecret | String | client Secret |
||
ums.oauth.jd.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
aliyun | ||||
ums.oauth.aliyun.clientId | String | client Id |
||
ums.oauth.aliyun.clientSecret | String | client Secret |
||
feishu | ||||
ums.oauth.feishu.clientId | String | client Id |
||
ums.oauth.feishu.clientSecret | String | client Secret |
||
xmly å马æé | ||||
ums.oauth.xmly.clientId | String | client Id |
||
ums.oauth.xmly.clientSecret | String | client Secret |
||
ums.oauth.xmly.deviceId | String | å马æé
ï¼è®¾å¤ID, 设å¤å¯ä¸æ è¯ID |
||
ums.oauth.xmly.clientOsType | Integer | å马æé
ï¼å®¢æ·ç«¯æä½ç³»ç»ç±»åï¼1-iOSç³»ç»ï¼2-Androidç³»ç»ï¼3-Web |
||
ums.oauth.xmly.packId | String | å马æé
ï¼å®¢æ·ç«¯å
åï¼å¦æ AuthConfig#getClientOsType() 为1æ2æ¶å¿
å¡«ã对Android 客æ·ç«¯æ¯å
åï¼å¯¹IOS 客æ·ç«¯æ¯Bundle ID |
||
wechatEnterpriseWeb ä¼ä¸å¾®ä¿¡ç½é¡µç | ||||
ums.oauth.wechatEnterpriseWeb.clientId | String | client Id |
||
ums.oauth.wechatEnterpriseWeb.clientSecret | String | client Secret |
||
ums.oauth.wechatEnterpriseWeb.agentId | String | ä¼ä¸å¾®ä¿¡ï¼æææ¹çç½é¡µåºç¨ID | ||
ums.oauth.wechatEnterpriseWeb.scopes | List<String> | æ¯æèªå®ä¹ææå¹³å°ç scope å 容, æ ¼å¼åè对åºç AuthScope.getScope() çåç±». 注æ: ä¼èªå¨æ·»å é»è®¤ç scope 设置. | ||
customize | ||||
ums.oauth.customize.clientId | String | client Id |
||
ums.oauth.customize.clientSecret | String | client Secret |
||
ums.oauth.customize.customizeProviderId | String | èªå®ä¹ç¬¬ä¸æ¹ææç»å½, å½ Auth2Properties#customize æ¶ææ, æ¤å段å¿
须以驼峰æ¹å¼å½å. æ¯å¦æ¤å段çå¼ä¸º umsCustomize , é£ä¹ /auth2/authorization/customize ä¼æ¿æ¢ä¸º /auth2/authorization/umsCustomize |
||
ums.oauth.customize.customizeIsForeign | Boolean | false | èªå®ä¹ç¬¬ä¸æ¹ææç»å½, å½ Auth2Properties#customize æ¶ææ, 设置第ä¸æ¹æ¯å¦å¨å½å¤, é»è®¤: false . å¦æ为 false æ¶, 设置 HttpConfig çè¶
æ¶æ¶é´ä¸º ums.oauth.proxy.timeout çå¼. å¦æ为 true æ¶, 设置 HttpConfig çè¶
æ¶æ¶é´ä¸º ums.oauth.proxy.foreignTimeout çå¼. |
true/false |
gitlabPrivate | ||||
ums.oauth.gitlabPrivate.clientId | String | client Id |
||
ums.oauth.gitlabPrivate.clientSecret | String | client Secret |
线ç¨æ± å±æ§
å±æ§ | ç±»å | é»è®¤å¼ | æè¿° | å¯é项 |
---|---|---|---|---|
accessTokenRefreshJob | ||||
ums.executor.accessTokenRefreshJob.corePoolSize | Integer | 0 | 线ç¨æ± ä¸ç©ºé²æ¶ä¿çç线ç¨æ°, é»è®¤: 0 | |
ums.executor.accessTokenRefreshJob.keepAliveTime | Integer | 10 | keep alive time, é»è®¤: 10 | |
ums.executor.accessTokenRefreshJob.timeUnit | TimeUnit | TimeUnit.MILLISECONDS | keepAliveTime æ¶é´åä½, é»è®¤: æ¯«ç§ | MILLISECONDS/MICROSECONDS/MILLISECONDS/SECONDS/MINUTES/HOURS/DAYS |
ums.executor.accessTokenRefreshJob.poolName | String | accessTokenJob | 线ç¨æ± å称, é»è®¤: accessTokenJob | |
ums.executor.accessTokenRefreshJob.rejectedExecutionHandlerPolicy | RejectedExecutionHandlerPolicy | ABORT | æç»çç¥, é»è®¤: ABORT | ABORT/CALLER_RUNS/DISCARD_OLDEST/DISCARD |
ums.executor.accessTokenRefreshJob.executorShutdownTimeout | Duration | PT10S | 线ç¨æ± å ³éè¿ç¨çè¶ æ¶æ¶é´, é»è®¤: PT10S | |
refreshToken | ||||
ums.executor.refreshToken.corePoolSize | Integer | 0 | 线ç¨æ± ä¸ç©ºé²æ¶ä¿çç线ç¨æ°, é»è®¤: 0 | |
ums.executor.refreshToken.maximumPoolSize | Integer | Runtime.getRuntime().availableProcessors() | æ大线ç¨æ°, é»è®¤: æ¬æºæ ¸å¿æ° | |
ums.executor.refreshToken.keepAliveTime | Integer | 5 | keep alive time, é»è®¤: 5 | |
ums.executor.refreshToken.timeUnit | TimeUnit | TimeUnit.SECONDS | keepAliveTime æ¶é´åä½, é»è®¤: ç§ | MILLISECONDS/MICROSECONDS/MILLISECONDS/SECONDS/MINUTES/HOURS/DAYS |
ums.executor.refreshToken.blockingQueueCapacity | Integer | maximumPoolSize * 2 | blocking queue capacity, é»è®¤: maximumPoolSize * 2 | |
ums.executor.refreshToken.poolName | String | refreshToken | 线ç¨æ± å称, é»è®¤: refreshToken | |
ums.executor.refreshToken.rejectedExecutionHandlerPolicy | RejectedExecutionHandlerPolicy | CALLER_RUNS | æç»çç¥, é»è®¤: CALLER_RUNS 注æ: ä¸è¬æ åµä¸ä¸è¦æ´æ¹é»è®¤è®¾ç½®, 没æå®ç° RefreshToken é»è¾è¢«æç»æ§è¡åçå¤çé»è¾, é¤éèªå·±å®ç°RefreshTokenJob.refreshTokenJob() 对 RefreshToken é»è¾è¢«æç»æ§è¡åçå¤çé»è¾. | ABORT/CALLER_RUNS/DISCARD_OLDEST/DISCARD |
ums.executor.refreshToken.executorShutdownTimeout | Duration | PT10S | 线ç¨æ± å ³éè¿ç¨çè¶ æ¶æ¶é´, é»è®¤: PT10S | |
updateConnection | ||||
ums.executor.updateConnection.corePoolSize | Integer | 5 | 线ç¨æ± ä¸ç©ºé²æ¶ä¿çç线ç¨æ°, é»è®¤: 5 | |
ums.executor.updateConnection.maximumPoolSize | Integer | Runtime.getRuntime().availableProcessors() | æ大线ç¨æ°, é»è®¤: æ¬æºæ ¸å¿æ° | |
ums.executor.updateConnection.keepAliveTime | Integer | 10 | keep alive time, é»è®¤: 10 | |
ums.executor.updateConnection.timeUnit | TimeUnit | TimeUnit.SECONDS | keepAliveTime æ¶é´åä½, é»è®¤: ç§ | MILLISECONDS/MICROSECONDS/MILLISECONDS/SECONDS/MINUTES/HOURS/DAYS |
ums.executor.updateConnection.blockingQueueCapacity | Integer | maximumPoolSize * 2 | blocking queue capacity, é»è®¤: maximumPoolSize * 2 | |
ums.executor.updateConnection.poolName | String | updateConnection | 线ç¨æ± å称, é»è®¤: updateConnection | |
ums.executor.updateConnection.rejectedExecutionHandlerPolicy | RejectedExecutionHandlerPolicy | CALLER_RUNS | æç»çç¥, é»è®¤: CALLER_RUNS 注æ: ä¸è¬æ åµä¸ä¸è¦æ´æ¹é»è®¤è®¾ç½®, é¤éèªå·±å®ç°Auth2LoginAuthenticationProvideræ´æ°é»è¾; æ¹æ ABORT ä¹æ¯æ, é»è®¤å®ç° Auth2LoginAuthenticationProvider æ¯å¼æ¥æ´æ°è¢«æç»æ§è¡å, ä¼æ§è¡åæ¥æ´æ°. | ABORT/CALLER_RUNS/DISCARD_OLDEST/DISCARD |
ums.executor.updateConnection.executorShutdownTimeout | Duration | PT10S | 线ç¨æ± å ³éè¿ç¨çè¶ æ¶æ¶é´, é»è®¤: PT10S |
对第ä¸æ¹ææç»å½ç¨æ·ä¿¡æ¯ä¸ token çæä¹ åï¼jdbcï¼æ°æ®æ¯å¦ç¼åå° redis çé ç½®
å±æ§ | ç±»å | é»è®¤å¼ | æè¿° | å¯é项 |
---|---|---|---|---|
ums.cache.redis.open | Boolean | false | Redis cache is open, é»è®¤ false | true/false |
ums.cache.redis.useIocRedisConnectionFactory | Boolean | false | æ¯å¦ä½¿ç¨ spring IOC 容å¨ä¸ç RedisConnectionFactoryï¼ é»è®¤ï¼ false. å¦æä½¿ç¨ spring IOC 容å¨ä¸ç RedisConnectionFactoryï¼åè¦æ³¨æ cache.database-index è¦ä¸ spring.redis.database ä¸æ · | true/false |
cache | ||||
ums.cache.redis.cache.databaseIndex | Integer | 0 | redis cache åæ¾ç database index, é»è®¤: 0 | |
ums.cache.redis.cache.defaultExpireTime | Duration | PT200S | 设置ç¼å管çå¨ç®¡ççç¼åçé»è®¤è¿ææ¶é´, é»è®¤: 200, åä½: ç§ | |
ums.cache.redis.cache.entryTtl | Duration | PT180S | cache ttl ãä½¿ç¨ 0 声æä¸ä¸ªæ°¸ä¹ çç¼åã é»è®¤: 180, åä½: ç§ åç¼åæ¶é´ç 20% ä½ä¸ºå¨æçéæºåéä¸ä¸æµ®å¨, é²æ¢åæ¶ç¼å失æèç¼åå»ç©¿ | |
ums.cache.redis.cache.cacheNames | Set<String> | Names of the default caches to consider for caching operations defined in the annotated class. |
第ä¸æ¹ææç»å½ç¨æ·ä¿¡æ¯è¡¨ user_connection sql é ç½®
å±æ§ | ç±»å | é»è®¤å¼ | æè¿° | å¯é项 |
---|---|---|---|---|
æ°æ®åºåå§åç¸å ³è¯å¥ | ||||
ums.repository.enableStartUpInitializeTable | Boolean | true | æ¯å¦å¨å¯å¨æ¶æ£æ¥å¹¶èªå¨å建 userConnectionTableName ä¸ authTokenTableName , é»è®¤: TRUE |
true/false |
ums.repository.queryDatabaseNameSql | String | select database(); | æ¥è¯¢æ°æ®åºå称, é»è®¤ä¸º mysql æ¥è¯¢è¯å¥. |
|
ums.repository.authTokenTableName | String | auth_token | 第ä¸æ¹ç»å½ AuthTokenPo æ°æ®åºè¡¨å称. |
|
ums.repository.queryAuthTokenTableExistSql | String | SELECT COUNT(1) FROM information_schema.tables WHERE table_name = '%s' AND table_schema = '%s'; | æ¥è¯¢æ· authTokenTableName å¨æ°æ®åºä¸æ¯å¦åå¨çè¯å¥ã 注æï¼ sql è¯å¥ä¸ç %s å¿
é¡»åä¸ï¼ä¸ %s ç顺åºå¿
é¡»ä¸åé¢çå段å称æ对åºçå«ä¹å¯¹åº : authTokenTableName , database |
|
ums.repository.createAuthTokenTableSql | String | å建 authTokenTableName ç建表è¯å¥ | å建 authTokenTableName ç建表è¯å¥ã 注æï¼ sql è¯å¥ä¸ç %s å¿
é¡»åä¸ï¼ä¸ %s ç顺åºå¿
é¡»ä¸åé¢çå段å称æ对åºçå«ä¹å¯¹åº : authTokenTableName |
|
èªå®ä¹ç¬¬ä¸æ¹ç»å½ç¨æ·è¡¨åç¸å ³ CURD è¯å¥ | ||||
ums.repository.userConnectionTableName | String | user_connection | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºè¡¨åç§°ï¼ | |
ums.repository.userIdColumnName | String | userId | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨ç¨æ·å¯ä¸ ID å段åç§°ï¼ é»è®¤ä¸º userId | |
ums.repository.providerIdColumnName | String | providerId | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨æå¡å providerId å段åç§°ï¼ é»è®¤ä¸º providerId | |
ums.repository.providerUserIdColumnName | String | providerUserId | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨æå¡åç¨æ· providerUserId å段åç§°ï¼ é»è®¤ä¸º providerUserId | |
ums.repository.rankColumnName | String | rank | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨ rank å段åç§°ï¼ é»è®¤ä¸º rank ã 注æï¼å 为 MySQL 8.0 çæ¬ rank æ¯ä¸ªå
³é®åãä¸å®è¦ç¨ ` å
裹ã |
|
ums.repository.displayNameColumnName | String | displayName | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨ç¨æ·æ¾ç¤ºå称 displayName å段åç§°ï¼ é»è®¤ä¸º displayName | |
ums.repository.profileUrlColumnName | String | profileUrl | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨ç¨æ·ä¸»é¡µ profileUrl å段åç§°ï¼ é»è®¤ä¸º profileUrl | |
ums.repository.imageUrlColumnName | String | imageUrl | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨ç¨æ·å¤´å imageUrl å段åç§°ï¼ é»è®¤ä¸º imageUrl | |
ums.repository.accessTokenColumnName | String | accessToken | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨ç¨æ· accessToken å段åç§°ï¼ é»è®¤ä¸º accessToken | |
ums.repository.tokenIdColumnName | String | tokenId | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨ç¨æ· tokenId å段åç§°ï¼ é»è®¤ä¸º tokenId | |
ums.repository.refreshTokenColumnName | String | refreshToken | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨ç¨æ·æ¾ refreshToken å段åç§°ï¼ é»è®¤ä¸º refreshToken | |
ums.repository.expireTimeColumnName | String | expireTime | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨ç¨æ·è¿ææ¶é´ expireTime å段åç§°ï¼ é»è®¤ä¸º expireTime | |
ums.repository.creatUserConnectionTableSql | String | "CREATE TABLE %s (%s varchar(255) NOT NULL, %s varchar(255) NOT NULL, %s varchar(255) NOT NULL, %s int NOT NULL, %s varchar(255), %s varchar(512), %s varchar(512), %s varchar(512) NOT NULL, %s varchar(512), %s varchar(512), %s bigint, PRIMARY KEY (%s, %s, %s), unique KEY idx_userId_providerId_rank (%s, %s, %s), KEY idx_providerId_providerUserId_rank (%s, %s, %s)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;" |
第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨å建è¯å¥ã ä¿®æ¹ç¬¬ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨å建è¯å¥æ¶ï¼è¦æ³¨æï¼ä¿®æ¹å段å称å¯ä»¥ç´æ¥ä¿®æ¹ä¸é¢çå段å称å³å¯ï¼ä¸ç¨ä¿®æ¹å»ºè¡¨è¯å¥ï¼ä¸å¯ä»¥åå°å段ï¼ä½å¯ä»¥å¦å¤å¢å å段ã ç¨æ·éè¦å¯¹ç¬¬ä¸æ¹ç»å½çç¨æ·è¡¨ä¸ curd ç sql è¯å¥ç»æè¿è¡æ´æ¹æ¶, å¿ é¡»å®ç°å¯¹åºç UsersConnectionRepositoryFactoryï¼ å¦æéè¦ï¼è¯·å®ç° UsersConnectionRepositoryFactoryï¼å¯ä»¥åè Auth2JdbcUsersConnectionRepositoryFactoryã 注æï¼ sql è¯å¥ä¸ç %s å¿ é¡»åä¸ï¼ä¸ %s ç顺åºå¿ é¡»ä¸åé¢çå段å称æ对åºçå«ä¹å¯¹åº : tableNameã userIdColumnNameã providerIdColumnNameã providerUserIdColumnNameã rankColumnNameã displayNameColumnNameã profileUrlColumnNameã imageUrlColumnNameã accessTokenColumnNameã tokenIdColumnNameã refreshTokenColumnNameã expireTimeColumnNameã userIdColumnNameã providerIdColumnNameã providerUserIdColumnNameã userIdColumnNameã providerIdColumnNameã rankColumnNameã providerIdColumnNameã providerUserIdColumnNameã rankColumnNameã | |
ums.repository.queryUserConnectionTableExistSql | String | SELECT COUNT(1) FROM information_schema.tables WHERE table_schema='%s' AND table_name = '%s' | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨æ¥è¯¢ userIds çæ¥è¯¢è¯å¥ã 注æï¼ sql è¯å¥ä¸ç %s å¿ é¡»åä¸ï¼é®å·å¿ é¡»ä¸æå®ç %s ç¸å¯¹åº,%sæ顺åºä¼ç¨å¯¹åºç : databaseNameã tableName | |
ums.repository.findUserIdsWithConnectionSql | String | select %s from %s where %s = ? and %s = ? | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨æ¥è¯¢ userIds çæ¥è¯¢è¯å¥ã 注æï¼ sql è¯å¥ä¸ç %s å¿ é¡»åä¸ï¼é®å·å¿ é¡»ä¸æå®ç %s ç¸å¯¹åº,%sæ顺åºä¼ç¨å¯¹åºç : userIdColumnNameã tableNameã providerIdColumnNameã providerUserIdColumnName | |
ums.repository.findUserIdsConnectedToSql | String | select %s from %S where %s = :%s and %s in (:%s) | éè¿ç¬¬ä¸æ¹æå¡æä¾åæä¾ç providerId ä¸ providerUserIds ä»æ°æ®åºç¨æ·è¡¨æ¥è¯¢ userIds çæ¥è¯¢è¯å¥ã 注æï¼ sql è¯å¥ä¸ç %s å¿ é¡»åä¸ï¼é®å·å¿ é¡»ä¸æå®ç %s ç¸å¯¹åº,%sæ顺åºä¼ç¨å¯¹åºç : userIdColumnNameã tableNameã providerIdColumnNameã providerUserIdColumnName | |
ums.repository.selectFromUserConnectionSql | String | select %s, %s, %s, %s, %s, %s, %s, %s, %s, %s from %s | éè¿ç¬¬ä¸æ¹æå¡æä¾åæä¾ç providerId ä¸ providerUserIds ä»æ°æ®åºç¨æ·è¡¨æ¥è¯¢ userIds çæ¥è¯¢è¯å¥ã 注æï¼ sql è¯å¥ä¸ç %s å¿ é¡»åä¸ï¼é®å·å¿ é¡»ä¸æå®ç %s ç¸å¯¹åº, %sæ顺åºä¼ç¨å¯¹åºç : userIdColumnNameã providerIdColumnNameã providerUserIdColumnNameã displayNameColumnNameã profileUrlColumnNameã imageUrlColumnNameã accessTokenColumnNameã tokenIdColumnNameã refreshTokenColumnNameã expireTimeColumnNameã tableName | |
ums.repository.updateConnectionSql | String | update %s set %s = ?, %s = ?, %s = ?, %s = ?, %s = ?, %s = ?, %s = ? where %s = ? and %s = ? and %s = ? | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨æ´æ°è¯å¥ã 注æï¼ sql è¯å¥ä¸ç %s å¿ é¡»åä¸ï¼é®å·å¿ é¡»ä¸æå®ç %s ç¸å¯¹åº, %sæ顺åºä¼ç¨å¯¹åºç : tableNameã displayNameColumnNameã profileUrlColumnNameã imageUrlColumnNameã accessTokenColumnNameã tokenIdColumnNameã refreshTokenColumnNameã expireTimeColumnNameã userIdColumnNameã providerIdColumnNameã providerUserIdColumnName | |
ums.repository.addConnectionSql | String | insert into %s(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨æ·»å ç¨æ·è¯å¥ã 注æï¼ sql è¯å¥ä¸ç %s å¿ é¡»åä¸ï¼é®å·å¿ é¡»ä¸æå®ç %s ç¸å¯¹åº, %sæ顺åºä¼ç¨å¯¹åºç : tableNameã userIdColumnNameã providerIdColumnNameã providerUserIdColumnNameã rankColumnNameã displayNameColumnNameã profileUrlColumnNameã imageUrlColumnNameã accessTokenColumnNameã tokenIdColumnNameã refreshTokenColumnNameã expireTimeColumnName | |
ums.repository.addConnectionQueryForRankSql | String | select coalesce(max(%s) + 1, 1) as %s from %s where %s = ? and %s = ? | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨æ¥è¯¢æ·»å ç¨æ·æ¶çæé rank çå¼ã 注æï¼ sql è¯å¥ä¸ç %s å¿ é¡»åä¸ï¼é®å·å¿ é¡»ä¸æå®ç %s ç¸å¯¹åº,%sæ顺åºä¼ç¨å¯¹åºç : rankColumnNameã rankColumnNameã tableNameã userIdColumnNameã providerIdColumnName | |
ums.repository.removeConnectionsSql | String | delete from %s where %s = ? and %s = ? | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨æ ¹æ® userId ä¸ providerId å é¤å¤ä¸ªç¨æ·ã 注æï¼ sql è¯å¥ä¸ç %s å¿ é¡»åä¸ï¼é®å·å¿ é¡»ä¸æå®ç %s ç¸å¯¹åº,%sæ顺åºä¼ç¨å¯¹åºç : tableNameã userIdColumnNameã providerIdColumnName | |
ums.repository.removeConnectionSql | String | delete from %s where %s = ? and %s = ? and %s = ? | 第ä¸æ¹ç»å½ç¨æ·æ°æ®åºç¨æ·è¡¨æ ¹æ® userIdãproviderIdãproviderUserId å é¤ä¸ä¸ªç¨æ·ã 注æï¼ sql è¯å¥ä¸ç %s å¿ é¡»åä¸ï¼é®å·å¿ é¡»ä¸æå®ç %s ç¸å¯¹åº,%sæ顺åºä¼ç¨å¯¹åºç : tableNameã userIdColumnNameã providerIdColumnNameã providerUserIdColumnName |
ä¹ãåä¸è´¡ç®
- Fork æ¬é¡¹ç®
- æ°å»º Feat_xxx åæ¯
- æ交代ç
- æ°å»º Pull Request