This commit is contained in:
有来技术 2021-10-13 23:51:26 +08:00
parent 9c1758e9dc
commit 071e045173
9 changed files with 171 additions and 28 deletions

View File

@ -112,15 +112,8 @@
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
</dependency>
</dependencies>

View File

@ -63,7 +63,7 @@ public class AliyunSmsServiceImpl implements ISmsService {
@Override
public boolean sendSmsCode(String phoneNumber) {
String code = RandomUtil.randomNumbers(6); // 随机生成6位的手机验证码
stringRedisTemplate.opsForValue().set(AuthConstants.SMS_CODE_PREFIX + phoneNumber, code, 600, TimeUnit.SECONDS); // 验证登录成功之后删除
stringRedisTemplate.opsForValue().set(AuthConstants.SMS_CODE_PREFIX + phoneNumber, code, 600, TimeUnit.SECONDS);
boolean result = this.sendSms(phoneNumber, code);
return result;
}

View File

@ -80,34 +80,35 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
tokenEnhancers.add(jwtAccessTokenConverter());
tokenEnhancerChain.setTokenEnhancers(tokenEnhancers);
// 添加自定义授权模式
// 获取原有默认授权模式(授权码模式密码模式客户端模式简化模式)的授权者
List<TokenGranter> granterList = new ArrayList<>(Arrays.asList(endpoints.getTokenGranter()));
granterList.add(new WechatTokenGranter(endpoints.getTokenServices(), endpoints.getClientDetailsService(),
endpoints.getOAuth2RequestFactory(), authenticationManager));
// 添加验证码授权模式授权者
granterList.add(new CaptchaTokenGranter(endpoints.getTokenServices(), endpoints.getClientDetailsService(),
endpoints.getOAuth2RequestFactory(), authenticationManager, stringRedisTemplate
));
// 添加手机短信验证码授权模式的授权者
granterList.add(new SmsCodeTokenGranter(endpoints.getTokenServices(), endpoints.getClientDetailsService(),
endpoints.getOAuth2RequestFactory(), authenticationManager
));
CompositeTokenGranter compositeTokenGranter = new CompositeTokenGranter(granterList);
endpoints
.authenticationManager(authenticationManager)
.accessTokenConverter(jwtAccessTokenConverter())
.tokenEnhancer(tokenEnhancerChain)
.tokenGranter(compositeTokenGranter)
//.userDetailsService(sysUserDetailsService)
.userDetailsService(sysUserDetailsService)
/** refresh token有两种使用方式重复使用(true)非重复使用(false)默认为true
* 1 重复使用access token过期刷新时 refresh token过期时间未改变仍以初次生成的时间为准
* 2 非重复使用access token过期刷新时 refresh token过期时间延续在refresh token有效期内刷新便永不失效达到无需再次登录的目的
*/
.reuseRefreshTokens(true)
.tokenServices(tokenServices(endpoints)); // 自定义的TokenService
.reuseRefreshTokens(true);
}
public DefaultTokenServices tokenServices(AuthorizationServerEndpointsConfigurer endpoints) {
// Token增强
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
List<TokenEnhancer> tokenEnhancers = new ArrayList<>();
tokenEnhancers.add(tokenEnhancer());
@ -120,7 +121,6 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
tokenServices.setClientDetailsService(clientDetailsService);
tokenServices.setTokenEnhancer(tokenEnhancerChain);
// 多用户体系下刷新token再次认证客户端ID和 UserDetailService 的映射Map
Map<String, UserDetailsService> clientUserDetailsServiceMap = new HashMap<>();
clientUserDetailsServiceMap.put(AuthConstants.ADMIN_CLIENT_ID, sysUserDetailsService); // 系统管理客户端

View File

@ -29,7 +29,6 @@ public class SmsCodeAuthenticationProvider implements AuthenticationProvider {
private MemberFeignClient memberFeignClient;
private StringRedisTemplate redisTemplate;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
SmsCodeAuthenticationToken authenticationToken = (SmsCodeAuthenticationToken) authentication;
@ -38,13 +37,11 @@ public class SmsCodeAuthenticationProvider implements AuthenticationProvider {
String codeKey = AuthConstants.SMS_CODE_PREFIX + mobile;
String correctCode = redisTemplate.opsForValue().get(codeKey);
// 短信验证码 666666 是后门短信验证码发送功能有来考虑费用问题线上环境关闭真实环境移除后门即可
if (!code.equals("666666")) {
if (StrUtil.isBlank(correctCode) || !code.equals(correctCode)) {
throw new BizException("验证码不正确");
} else {
redisTemplate.delete(codeKey);
}
// 验证码比对
if (StrUtil.isBlank(correctCode) || !code.equals(correctCode)) {
throw new BizException("验证码不正确");
} else {
redisTemplate.delete(codeKey);
}
UserDetails userDetails = ((MemberUserDetailsServiceImpl) userDetailsService).loadUserByMobile(mobile);
WechatAuthenticationToken result = new WechatAuthenticationToken(userDetails, new HashSet<>());
@ -52,7 +49,6 @@ public class SmsCodeAuthenticationProvider implements AuthenticationProvider {
return result;
}
@Override
public boolean supports(Class<?> authentication) {
return SmsCodeAuthenticationToken.class.isAssignableFrom(authentication);

View File

@ -1,6 +1,5 @@
package com.youlai.common.elasticsearch.config;
import lombok.AllArgsConstructor;
import lombok.Setter;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
@ -19,7 +18,6 @@ import java.util.List;
*/
@ConfigurationProperties(prefix = "spring.elasticsearch.rest")
@Configuration
@AllArgsConstructor
public class RestHighLevelClientConfig {
@Setter

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>youlai-common</artifactId>
<groupId>com.youlai</groupId>
<version>2.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common-sms</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.youlai</groupId>
<artifactId>common-web</artifactId>
</dependency>
<dependency>
<groupId>com.youlai</groupId>
<artifactId>common-redis</artifactId>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,28 @@
package com.youlai.common.sms.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author <a href="mailto:xianrui0365@163.com">haoxianrui</a>
* @date 2021/10/13 22:44
*/
@ConfigurationProperties(prefix = "aliyun.sms")
@Configuration
@Data
public class AliyunSmsProperties {
private String accessKeyId;
private String accessKeySecret;
private String domain;
private String regionId;
private String templateCode;
private String signName;
}

View File

@ -0,0 +1,84 @@
package com.youlai.common.sms.service;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.profile.DefaultProfile;
import com.youlai.common.constant.AuthConstants;
import com.youlai.common.sms.config.AliyunSmsProperties;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @author <a href="mailto:xianrui0365@163.com">haoxianrui</a>
* @date 2021/10/13 23:04
*/
@Service
@RequiredArgsConstructor
public class AliyunSmsService {
private final AliyunSmsProperties aliyunSmsProperties;
private final StringRedisTemplate stringRedisTemplate;
/**
* 发送短信
*
* @param phoneNumbers 手机号多个用英文逗号(,)分割
* @param code
* @return
*/
private boolean sendSmsCode(String phoneNumbers, String code) {
String code = RandomUtil.randomNumbers(6); // 随机生成6位的手机验证码
stringRedisTemplate.opsForValue().set(AuthConstants.SMS_CODE_PREFIX + phoneNumber, code, 600, TimeUnit.SECONDS);
DefaultProfile profile = DefaultProfile.getProfile(aliyunSmsProperties.getRegionId(),
aliyunSmsProperties.getAccessKeyId(), aliyunSmsProperties.getAccessKeySecret());
IAcsClient client = new DefaultAcsClient(profile);
// 创建通用的请求对象
CommonRequest request = new CommonRequest();
// 指定请求方式
request.setSysMethod(MethodType.POST);
// 短信api的请求地址 固定
request.setSysDomain(domain);
// 签名算法版本 固定
request.setSysVersion("2017-05-25");
// 请求 API 的名称
request.setSysAction("SendSms");
// 指定地域名称
request.putQueryParameter("RegionId", regionId);
// 要给哪个手机号发送短信 指定手机号
request.putQueryParameter("PhoneNumbers", phoneNumbers);
// 您的申请签名
request.putQueryParameter("SignName", signName);
// 您申请的模板 code
request.putQueryParameter("TemplateCode", templateCode);
Map<String, Object> params = new HashMap<>();
// 这里的key就是短信模板中的 ${xxxx}
params.put("code", code);
request.putQueryParameter("TemplateParam", JSONUtil.toJsonStr(params));
try {
CommonResponse response = client.getCommonResponse(request);
return response.getHttpResponse().isSuccess();
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace();
}
return false;
}
}

View File

@ -21,5 +21,6 @@
<module>common-rabbitmq</module>
<module>common-elasticsearch</module>
<module>common-log</module>
<module>common-sms</module>
</modules>
</project>