Commit 6687ed02 authored by SN150021's avatar SN150021

短信验证登陆SMS

parent 37fb2889
......@@ -107,33 +107,7 @@ public class AccountController {
public ResultDto requestOTP(@RequestBody MobileDto mobile) {
ResultDto resultDto = new ResultDto();
try {
accountService.sendSmsOtp(mobile.getMobile());
resultDto.setStatus(0);
} catch (ClientRequestException e) {
logger.error("fail to send sms", e);
dealClientRequestException(resultDto, e);
}
return resultDto;
}
@RequestMapping(path = "/resetAuthCode", method = RequestMethod.POST)
public ResultDto resetAuthCode(@RequestBody MobileDto mobile) {
ResultDto resultDto = new ResultDto();
try {
accountService.sendSmsOtpReset(mobile.getMobile());
resultDto.setStatus(0);
} catch (ClientRequestException e) {
logger.error("fail to send sms", e);
dealClientRequestException(resultDto, e);
}
return resultDto;
}
@RequestMapping(path = "/loginAuthCode", method = RequestMethod.POST)
public ResultDto loginAuthCode(@RequestBody MobileDto mobile) {
ResultDto resultDto = new ResultDto();
try {
accountService.loginAuthCode(mobile.getMobile());
accountService.sendSmsOtp(mobile);
resultDto.setStatus(0);
} catch (ClientRequestException e) {
logger.error("fail to send sms", e);
......
......@@ -14,7 +14,7 @@ public class Otp {
@Id
private String phone;
private String type; //0.登陆 1、
private Integer type; //0.登陆 1.注册 2.找回密码
/**
* 发送给用户的短信验证码
......@@ -26,6 +26,14 @@ public class Otp {
*/
private long createdAt;
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
public String getPhone() {
return phone;
}
......
......@@ -3,12 +3,21 @@ package com.edgec.browserbackend.account.dto;
public class MobileDto {
String mobile;
String sign;
Integer type;
String sign_time;
public String getMobile() {
return mobile;
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
......
......@@ -6,7 +6,7 @@ import org.springframework.data.mongodb.repository.MongoRepository;
public interface OtpRepository extends MongoRepository<Otp, String> {
Otp findByPhoneAndCreatedAtGreaterThanEqual(String phone, long timestamp);
Otp findByPhoneAndTypeAndCreatedAtGreaterThanEqual(String phone, Integer type, long timestamp);
}
......@@ -82,7 +82,7 @@ public interface AccountService {
Page<UserPayment> getUserPayment(Pageable pageable, String username);
void sendSmsOtp(String phone);
void sendSmsOtp(MobileDto mobileDto);
AccountDto getAccountByCellphone(String cellphone);
......@@ -112,7 +112,4 @@ public interface AccountService {
boolean setAuthorize(String username, boolean isAgree);
void sendSmsOtpReset(String mobile);
void loginAuthCode(String mobile);
}
......@@ -20,20 +20,36 @@ public class SmsUtils {
private static final int TIME_OUT = 10 * 60; //10minues
public enum SmsTemplateCode {
NEWACCOUNT("SMS_472080002"),
RESETACCOUNT("SMS_471765248");
LOGINACCOUNT(0, "SMS_472020179"),
NEWACCOUNT(1,"SMS_472080002"),
RESETACCOUNT(2,"SMS_471765248"),
;
Integer type;
String code;
SmsTemplateCode(String code) {
SmsTemplateCode(Integer type, String code) {
this.type =type;
this.code = code;
}
public Integer getType() {
return type;
}
public String getCode() {
return code;
}
public static SmsTemplateCode getByType(Integer type) {
for (SmsTemplateCode smsTemplateCode : SmsTemplateCode.values()) {
if (smsTemplateCode.type.intValue() == type.intValue()) {
return smsTemplateCode;
}
}
return null;
}
}
/**
......
......@@ -12,6 +12,7 @@ import com.edgec.browserbackend.account.service.SmsUtils;
import com.edgec.browserbackend.account.service.SmsUtils.SmsTemplateCode;
import com.edgec.browserbackend.account.utils.AccountServicePool;
import com.edgec.browserbackend.auth.exception.AuthErrorCode;
import com.edgec.browserbackend.auth.repository.UserRepository;
import com.edgec.browserbackend.auth.service.UserService;
import com.edgec.browserbackend.browser.ErrorCode.BrowserErrorCode;
import com.edgec.browserbackend.browser.domain.IpSummary;
......@@ -23,6 +24,7 @@ import com.edgec.browserbackend.browser.service.ShopService;
import com.edgec.browserbackend.common.commons.error.ClientRequestException;
import com.edgec.browserbackend.common.utils.Aes;
import com.edgec.browserbackend.common.utils.FileUtil;
import javax.annotation.Resource;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -106,6 +108,9 @@ public class AccountServiceImpl implements AccountService {
@Autowired
private GlobalFieldRepository globalFieldRepository;
@Resource
private UserRepository userRepository;
@Override
public List<UserBillList> getUserBills0(String name) {
......@@ -433,7 +438,7 @@ public class AccountServiceImpl implements AccountService {
}
// 2. 校验用户输入的短信验证码是否正确
Otp otp = otpRepository.findByPhoneAndCreatedAtGreaterThanEqual(user.getUsername(), Instant.now().minusSeconds(600).toEpochMilli());
Otp otp = otpRepository.findByPhoneAndTypeAndCreatedAtGreaterThanEqual(user.getUsername(), 1, Instant.now().minusSeconds(600).toEpochMilli());
if (otp == null) {
throw new ClientRequestException(AccountErrorCode.OTPWRONG, AccountErrorCode.OTPWRONG.getReason());
}
......@@ -881,7 +886,7 @@ public class AccountServiceImpl implements AccountService {
@Override
public void resetPasswordWithOtp(UserDto user) {
Otp otp = otpRepository.findByPhoneAndCreatedAtGreaterThanEqual(user.getUsername(),
Otp otp = otpRepository.findByPhoneAndTypeAndCreatedAtGreaterThanEqual(user.getUsername(), 2,
Instant.now().minusSeconds(600).toEpochMilli());
if (otp == null) {
throw new ClientRequestException(AccountErrorCode.OTPWRONG, AccountErrorCode.OTPWRONG.getReason());
......@@ -911,17 +916,34 @@ public class AccountServiceImpl implements AccountService {
}
@Override
public void sendSmsOtp(String phone) {
public void sendSmsOtp(MobileDto mobileDto) {
// 1. 校验注册用户是否已存在
Account existing1 = accountRepository.findByName(phone).orElse(null);
Account existing2 = accountRepository.findOneByPhoneNumber(phone);
if (existing1 != null || existing2 != null) {
throw new ClientRequestException(AccountErrorCode.NAMEEXIST, "account already exists: " + phone);
String phone = mobileDto.getMobile();
if(mobileDto.getType() == 1) {
Account existing1 = accountRepository.findByName(phone).orElse(null);
Account existing2 = accountRepository.findOneByPhoneNumber(phone);
if (existing1 != null || existing2 != null) {
throw new ClientRequestException(AccountErrorCode.NAMEEXIST,
"account already exists: " + phone);
}
}else {
com.edgec.browserbackend.auth.domain.User user = userRepository.findByUsernameAndEnabled(
phone, true).orElse(null);
if(null == user){
throw new ClientRequestException(AccountErrorCode.NAMENOTEXIST,
"account already exists: " + phone);
}
}
String code = SmsUtils.sendSmsOTP(phone, SmsTemplateCode.NEWACCOUNT);
SmsTemplateCode smsTemplateCode = SmsTemplateCode.getByType(mobileDto.getType());
if(null == smsTemplateCode){
throw new ClientRequestException(AccountErrorCode.OTHERS,
"authCode type error" + phone);
}
String code = SmsUtils.sendSmsOTP(phone, smsTemplateCode);
Otp otp = new Otp();
otp.setPhone(phone);
otp.setOtp(code);
otp.setType(mobileDto.getType());
otp.setCreatedAt(Instant.now().toEpochMilli());
otpRepository.save(otp);
}
......@@ -1170,25 +1192,6 @@ public class AccountServiceImpl implements AccountService {
}
}
@Override
public void sendSmsOtpReset(String phone) {
String code = com.edgec.browserbackend.account.service.SmsUtils.sendSmsOTP(phone, SmsTemplateCode.RESETACCOUNT);
Otp otp = new Otp();
otp.setPhone(phone);
otp.setOtp(code);
otp.setCreatedAt(Instant.now().toEpochMilli());
otpRepository.save(otp);
}
@Override
public void loginAuthCode(String mobile) {
// Otp otp = new Otp();
// otp.setPhone(phone);
// otp.setOtp(code);
// otp.setCreatedAt(Instant.now().toEpochMilli());
//otpRepository.save(otp);
}
private void notifyCustomerRegister(Account contactUs) {
StringBuilder sb = new StringBuilder();
sb.append("Name: " + contactUs.getName() + "<br/>");
......
package com.edgec.browserbackend.auth.config;
import com.edgec.browserbackend.account.repository.AccountRepository;
import com.edgec.browserbackend.account.repository.OtpRepository;
import com.edgec.browserbackend.auth.repository.UserRepository;
import com.edgec.browserbackend.auth.service.MongoTokenStore;
import com.edgec.browserbackend.auth.service.security.MongoUserDetailsService;
import java.util.ArrayList;
......@@ -36,7 +39,6 @@ import org.springframework.security.oauth2.provider.token.AuthorizationServerTok
@EnableAuthorizationServer
public class OAuth2AuthorizationNewConfig extends AuthorizationServerConfigurerAdapter {
private final String NOOP_PASSWORD_ENCODE = "{noop}";
@Autowired
private MongoTokenStore mongoTokenStore;
......@@ -54,6 +56,12 @@ public class OAuth2AuthorizationNewConfig extends AuthorizationServerConfigurerA
@Autowired
private OAuthResponseExceptionTranslator oAuthResponseExceptionTranslator;
@Autowired
private OtpRepository otpRepository;
@Autowired
private UserRepository repository;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
......@@ -111,8 +119,7 @@ public class OAuth2AuthorizationNewConfig extends AuthorizationServerConfigurerA
}
/**
* 这是从spring 的代码中 copy出来的, 默认的几个TokenGranter, 还原封不动加进去.
* 主要目的是覆盖原来的List<TokenGranter>,方便我们添加自定义的授权方式,比如SMSCodeTokenGranter短信验证码授权
* 覆盖原来的List<TokenGranter>,方便我们添加自定义的授权方式,比如SMSCodeTokenGranter短信验证码授权
*/
private List<TokenGranter> getDefaultTokenGranters(AuthorizationServerEndpointsConfigurer endpoints) {
AuthorizationServerTokenServices tokenServices = endpoints.getDefaultAuthorizationServerTokenServices();
......@@ -131,9 +138,7 @@ public class OAuth2AuthorizationNewConfig extends AuthorizationServerConfigurerA
tokenGranters.add(new ResourceOwnerPasswordTokenGranter(authenticationManager,
tokenServices, endpoints.getClientDetailsService(), requestFactory));
}
// 这里就是我们自己的授权验证
tokenGranters.add(new SMSCodeTokenGranter(tokenServices, endpoints.getClientDetailsService(), requestFactory, "sms"));
// 再有其他的验证, 就往下面添加....
tokenGranters.add(new SMSCodeTokenGranter(tokenServices, endpoints.getClientDetailsService(), requestFactory, otpRepository, repository, "sms"));
return tokenGranters;
}
......
package com.edgec.browserbackend.auth.config;
import com.edgec.browserbackend.account.domain.Account;
import com.edgec.browserbackend.account.domain.Otp;
import com.edgec.browserbackend.account.exception.AccountErrorCode;
import com.edgec.browserbackend.account.repository.AccountRepository;
import com.edgec.browserbackend.account.repository.OtpRepository;
import com.edgec.browserbackend.auth.domain.User;
import com.edgec.browserbackend.auth.domain.mongo.MongoOAuth2AccessToken;
import com.edgec.browserbackend.auth.repository.UserRepository;
import com.edgec.browserbackend.auth.repository.mongo.MongoOAuth2AccessTokenRepository;
import com.edgec.browserbackend.common.commons.error.ClientRequestException;
import java.time.Instant;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.annotation.Resource;
import org.apache.tomcat.util.net.openssl.ciphers.Authentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
......@@ -17,6 +30,7 @@ import org.springframework.security.oauth2.provider.TokenGranter;
import org.springframework.security.oauth2.provider.TokenRequest;
import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.stereotype.Component;
/**
* XXXX
......@@ -26,21 +40,44 @@ import org.springframework.security.oauth2.provider.token.AuthorizationServerTok
*/
public class SMSCodeTokenGranter extends AbstractTokenGranter {
public SMSCodeTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) {
private OtpRepository otpRepository;
private UserRepository repository;
public SMSCodeTokenGranter(
AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService,
OAuth2RequestFactory requestFactory, OtpRepository otpRepository , UserRepository repository,String grantType) {
this( tokenServices, clientDetailsService, requestFactory, grantType);
this.otpRepository = otpRepository;
this.repository = repository;
}
protected SMSCodeTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService,
OAuth2RequestFactory requestFactory, String grantType) {
super(tokenServices, clientDetailsService, requestFactory, grantType);
}
@Override
protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
Map<String, String> parameters = new LinkedHashMap<String, String>(tokenRequest.getRequestParameters());
String userMobileNo = parameters.get("mobile"); //客户端提交的用户名
String userName = parameters.get("username"); //客户端提交的用户名
String smsCode = parameters.get("smscode"); //客户端提交的验证码
User user = repository.findByUsernameAndEnabled(userName, true).orElse(null);
if (user == null) {
throw new ClientRequestException(AccountErrorCode.NAMENOTEXIST, "Username does not exist: " + userName);
}
/** 下面写自己的验证逻辑 */
// 2. 校验用户输入的短信验证码是否正确
Otp otp = otpRepository.findByPhoneAndTypeAndCreatedAtGreaterThanEqual(userName, 0, Instant.now().minusSeconds(300).toEpochMilli());
if (otp == null) {
throw new ClientRequestException(AccountErrorCode.OTPWRONG, AccountErrorCode.OTPWRONG.getReason());
}
if (!otp.getOtp().equals(smsCode)) {
throw new ClientRequestException(AccountErrorCode.OTPWRONG, AccountErrorCode.OTPWRONG.getReason());
}
User user = new User();
user.setPhone("11111111");
UsernamePasswordAuthenticationToken userAuth = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
((AbstractAuthenticationToken) userAuth).setDetails(parameters);
......
......@@ -33,7 +33,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/user/authCode", "/user/signUp", "/user/resetAuthCode",
.antMatchers("/user/authCode", "/user/signUp",
"/user/forgot**", "/0xadministrator/getconfig**");
}
......
......@@ -12,4 +12,6 @@ public interface UserRepository extends CrudRepository<User, String> {
Optional<User> findByEmail(String email);
Optional<User> findByPhone(String phone);
Optional<User> findByUsernameAndEnabled(String userName, boolean enabled);
}
......@@ -62,7 +62,7 @@ class BrowserBackendApplicationTests {
JSONObject param = new JSONObject();
param.put("day", "7");
param.put("amount", "5");
SmsUtils.sendIpSms("18711016574", SmsUtils.SmsTemplateCode.IPWILLEXPIRE_EXPIRE, param);
//SmsUtils.sendIpSms("18711016574", SmsUtils.SmsTemplateCode.IPWILLEXPIRE_EXPIRE, param);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment