邮箱-登录
This commit is contained in:
@@ -87,7 +87,7 @@ public class AccountBlockCheckService {
|
||||
return checkBlocked(ip, BlockTypeEnum.BLOCK_IP);
|
||||
}
|
||||
|
||||
public Long checkReturnEndTime(Long erbanNo, String phone, String deviceId, String ip){
|
||||
public Long checkReturnEndTime(Long erbanNo, String phone, String email, String deviceId, String ip){
|
||||
Long endTime = checkBlockedErbanNoReturnBlockEndTime(erbanNo);
|
||||
if (null != endTime){
|
||||
return endTime;
|
||||
@@ -96,6 +96,10 @@ public class AccountBlockCheckService {
|
||||
if (null != endTime){
|
||||
return endTime;
|
||||
}
|
||||
endTime = checkBlockedEmailReturnBlockEndTime(email);
|
||||
if (null != endTime){
|
||||
return endTime;
|
||||
}
|
||||
endTime = checkBlockedDeviceReturnBlockEndTime(deviceId);
|
||||
if (null != endTime){
|
||||
return endTime;
|
||||
@@ -143,6 +147,12 @@ public class AccountBlockCheckService {
|
||||
return checkBlockedReturnBlockEndTime(phone, BlockTypeEnum.BLOCK_PHONE);
|
||||
}
|
||||
|
||||
public Long checkBlockedEmailReturnBlockEndTime(String email){
|
||||
if (!StringUtils.hasText(email)){
|
||||
return null;
|
||||
}
|
||||
return checkBlockedReturnBlockEndTime(email, BlockTypeEnum.BLOCK_EMAIL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询设备是否被封禁
|
||||
|
@@ -71,7 +71,7 @@ public class EmailController extends BaseController {
|
||||
return new BusiResult<>(BusiStatus.ACCOUNT_BLOCK_ERROR, I18NMessageSourceUtil.getMessage(ACCOUNT_LOGIN_BLOCK_MSG, new Object[]{emailAddress}, PartitionEnum.ENGLISH.getId()));
|
||||
}
|
||||
|
||||
emailService.sendEmailCode(emailAddress, type, deviceInfo, ip, null, true);
|
||||
emailService.sendEmailCode(emailAddress, type, deviceInfo, ip, null, false);
|
||||
|
||||
return new BusiResult<>(BusiStatus.SMS_SEND_SUCCESS);
|
||||
}
|
||||
|
@@ -17,6 +17,8 @@ public enum GrantTypeEnum {
|
||||
APPLE("apple"),
|
||||
|
||||
VERIFY_CODE("verify_code"),
|
||||
|
||||
EMAIL("email"),
|
||||
;
|
||||
|
||||
private final String value;
|
||||
|
@@ -53,6 +53,11 @@ public enum LoginTypeEnum {
|
||||
*/
|
||||
FACEBOOK((byte) 10),
|
||||
|
||||
/**
|
||||
* 邮箱登录
|
||||
* */
|
||||
EMAIL((byte) 11),
|
||||
|
||||
;
|
||||
|
||||
private final byte value;
|
||||
|
@@ -33,6 +33,11 @@
|
||||
<artifactId>accompany-sms-service</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.accompany</groupId>
|
||||
<artifactId>accompany-email-service</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.accompany</groupId>
|
||||
<artifactId>accompany-mq-service</artifactId>
|
||||
|
@@ -9,6 +9,8 @@ import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
|
||||
public interface MyUserDetailsService extends UserDetailsService {
|
||||
|
||||
UserDetails loadUserByEmail(String email, String code, DeviceInfo deviceInfo, String ipAddress) throws Exception;
|
||||
|
||||
UserDetails loadUserByPhone(String phone, String phoneAreaCode, String smsCode, DeviceInfo deviceInfo, String ipAddress) throws Exception;
|
||||
|
||||
UserDetails loadUserByOpenId(String openid, Byte type, DeviceInfo deviceInfo, String ipAddress, String unionId) throws Exception;
|
||||
|
@@ -7,6 +7,7 @@ import com.accompany.common.device.DeviceInfo;
|
||||
import com.accompany.common.redis.RedisKey;
|
||||
import com.accompany.common.status.BusiStatus;
|
||||
import com.accompany.common.utils.CommonUtil;
|
||||
import com.accompany.core.enumeration.PartitionEnum;
|
||||
import com.accompany.core.exception.ServiceException;
|
||||
import com.accompany.core.model.Account;
|
||||
import com.accompany.core.model.AccountLoginRecord;
|
||||
@@ -23,6 +24,7 @@ import com.accompany.core.service.region.RegionNetworkService;
|
||||
import com.accompany.core.service.user.PhoneBlackService;
|
||||
import com.accompany.core.service.user.UsersBaseService;
|
||||
import com.accompany.core.util.I18NMessageSourceUtil;
|
||||
import com.accompany.email.service.EmailService;
|
||||
import com.accompany.oauth2.constant.LoginTypeEnum;
|
||||
import com.accompany.oauth2.exception.CustomOAuth2Exception;
|
||||
import com.accompany.oauth2.model.AccountDetails;
|
||||
@@ -71,9 +73,9 @@ public class MyUserDetailsServiceImpl implements MyUserDetailsService {
|
||||
@Autowired
|
||||
private SmsService smsService;
|
||||
@Autowired
|
||||
private SysConfService sysConfService;
|
||||
private EmailService emailService;
|
||||
@Autowired
|
||||
private PhoneBlackService phoneBlackService;
|
||||
private SysConfService sysConfService;
|
||||
@Autowired
|
||||
private RegionNetworkService regionService;
|
||||
@Autowired
|
||||
@@ -125,6 +127,16 @@ public class MyUserDetailsServiceImpl implements MyUserDetailsService {
|
||||
return new AccountDetails(account);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByEmail(String email, String code, DeviceInfo deviceInfo, String ipAddress) throws Exception {
|
||||
Account account = accountService.getAccountByEmail(email);
|
||||
if (account == null) {
|
||||
throw new CustomOAuth2Exception(CustomOAuth2Exception.USER_NOT_EXISTED,
|
||||
BusiStatus.USER_NOT_EXISTED.getReasonPhrase());
|
||||
}
|
||||
return new AccountDetails(account);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByPhone(String phone, String phoneAreaCode, String smsCode, DeviceInfo deviceInfo, String ipAddress)
|
||||
throws Exception {
|
||||
@@ -159,33 +171,36 @@ public class MyUserDetailsServiceImpl implements MyUserDetailsService {
|
||||
|
||||
@Override
|
||||
public void login(String reqUserName, UserDetails userDetails, LoginTypeEnum loginType, DeviceInfo deviceInfo,
|
||||
String ip, String openId, String unionId, String smsCode) throws Exception {
|
||||
String ip, String openId, String unionId, String code) throws Exception {
|
||||
AccountDetails details = (AccountDetails) userDetails;
|
||||
Account account = details.getAccount();
|
||||
Long uid = account.getUid();
|
||||
|
||||
String deviceId = deviceInfo.getDeviceId();
|
||||
String client = deviceInfo.getClient();
|
||||
String app = deviceInfo.getApp();
|
||||
String appVersion = deviceInfo.getAppVersion();
|
||||
Long uid = account.getUid();
|
||||
Date date = new Date();
|
||||
|
||||
// 拦截指定账号登录
|
||||
Users users = usersBaseService.getUsersByUid(account.getUid());
|
||||
if (users != null && NEED_INTERCEPT_USER_TYPE.contains(users.getDefUser())) {
|
||||
throw new ServiceException(BusiStatus.ILLEGAL_OPERATE);
|
||||
}
|
||||
|
||||
Long blockEndTime = accountBlockCheckService.checkReturnEndTime(account.getErbanNo(), account.getPhone(), deviceId, ip);
|
||||
Long blockEndTime = accountBlockCheckService.checkReturnEndTime(account.getErbanNo(), account.getPhone(), account.getEmail(), deviceId, ip);
|
||||
//检查账号、设备号、号段是否封禁
|
||||
if (null != blockEndTime){
|
||||
CustomOAuth2Exception exception = new CustomOAuth2Exception(CustomOAuth2Exception.ACCOUNT_ERROR, "");
|
||||
Integer partitionId = users.getPartitionId();
|
||||
exception.addAdditionalInformation("reason", I18NMessageSourceUtil.getMessage(ACCOUNT_LOGIN_BLOCK_MSG, new Object[]{users.getErbanNo()}, partitionId));
|
||||
Integer partitionId = null != users? users.getPartitionId(): PartitionEnum.ENGLISH.getId();
|
||||
exception.addAdditionalInformation("reason", I18NMessageSourceUtil.getMessage(ACCOUNT_LOGIN_BLOCK_MSG, new Object[]{account.getErbanNo()}, partitionId));
|
||||
exception.addAdditionalInformation("date", String.valueOf(blockEndTime));
|
||||
throw exception;
|
||||
}
|
||||
|
||||
//校验验证码
|
||||
checkSmsCodeByUserType(account, smsCode, loginType, deviceInfo.getApp());
|
||||
checkCodeByUserType(account, code, loginType);
|
||||
|
||||
accountManageService.checkAccountCancel(uid);
|
||||
//更新account信息
|
||||
String newToken = null;
|
||||
@@ -194,6 +209,7 @@ public class MyUserDetailsServiceImpl implements MyUserDetailsService {
|
||||
} else {
|
||||
newToken = accountService.refreshAndGetNetEaseToken(account);
|
||||
}
|
||||
|
||||
account.setNeteaseToken(newToken);
|
||||
account.setApp(deviceInfo.getApp());
|
||||
account.setAppVersion(deviceInfo.getAppVersion());
|
||||
@@ -210,8 +226,10 @@ public class MyUserDetailsServiceImpl implements MyUserDetailsService {
|
||||
account.setLastLoginTime(date);
|
||||
account.setLastLoginIp(ip);
|
||||
accountService.updateById(account);
|
||||
|
||||
//更新用户正在使用的app字段
|
||||
userAppService.updateCurrentApp(uid, app, date, ip, appVersion);
|
||||
|
||||
//将用户信息登记
|
||||
AccountLoginRecord accountLoginRecord = buildAccountLoginRecord(ip, account, loginType.getValue(), deviceInfo, openId);
|
||||
loginRecordService.addAccountLoginRecordAsync(accountLoginRecord);
|
||||
@@ -269,21 +287,24 @@ public class MyUserDetailsServiceImpl implements MyUserDetailsService {
|
||||
* 普通用户需要用手机验证码登录,官方账号和公会账号不校验验证码
|
||||
*
|
||||
* @param account
|
||||
* @param smsCode
|
||||
* @param appName
|
||||
* @param code
|
||||
*/
|
||||
private void checkSmsCodeByUserType(Account account, String smsCode, LoginTypeEnum loginType, String appName) {
|
||||
private void checkCodeByUserType(Account account, String code, LoginTypeEnum loginType) {
|
||||
//是否手机号登录
|
||||
Boolean isPhone = LoginTypeEnum.ID.getValue() == loginType.getValue();
|
||||
if (!isPhone) {
|
||||
boolean needVerifyCode = LoginTypeEnum.ID.getValue() == loginType.getValue()
|
||||
|| LoginTypeEnum.EMAIL.getValue() == loginType.getValue();
|
||||
if (!needVerifyCode) {
|
||||
return;
|
||||
}
|
||||
if (StringUtils.isEmpty(smsCode)) {
|
||||
if (!StringUtils.hasText(code)) {
|
||||
throw new CustomOAuth2Exception(CustomOAuth2Exception.VERIFY_CODE_ERROR,
|
||||
BusiStatus.VERIFY_CODE_ERROR.getReasonPhrase());
|
||||
}
|
||||
|
||||
if (!smsService.verifySmsCode(account.getPhone(), smsCode)) {
|
||||
boolean verifyResult = LoginTypeEnum.ID.getValue() == loginType.getValue()?
|
||||
smsService.verifySmsCode(account.getPhone(), code):
|
||||
emailService.verifyEmailCode(account.getEmail(), code);
|
||||
if (!verifyResult) {
|
||||
throw new CustomOAuth2Exception(CustomOAuth2Exception.VERIFY_CODE_ERROR,
|
||||
BusiStatus.VERIFY_CODE_ERROR.getReasonPhrase());
|
||||
}
|
||||
|
@@ -0,0 +1,56 @@
|
||||
package com.accompany.oauth2.support.email;
|
||||
|
||||
import com.accompany.common.device.DeviceInfo;
|
||||
import com.accompany.oauth2.constant.LoginTypeEnum;
|
||||
import com.accompany.oauth2.exception.CustomOAuth2Exception;
|
||||
import com.accompany.oauth2.service.MyUserDetailsService;
|
||||
import com.accompany.oauth2.util.RequestContextHolderUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.beanutils.BeanUtils;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
public class EmailAuthenticationProvider implements AuthenticationProvider {
|
||||
|
||||
private final MyUserDetailsService userDetailsService;
|
||||
|
||||
public EmailAuthenticationProvider(MyUserDetailsService userDetailsService) {
|
||||
this.userDetailsService = userDetailsService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||
Map<String, ?> params = (Map<String, ?>) authentication.getDetails();
|
||||
String email = authentication.getName();
|
||||
String code = (String) authentication.getCredentials();
|
||||
DeviceInfo deviceInfo = new DeviceInfo();
|
||||
try {
|
||||
BeanUtils.populate(deviceInfo, params);
|
||||
} catch (Exception e) {
|
||||
log.error("populate deviceInfo fail", e);
|
||||
}
|
||||
|
||||
UserDetails userDetails = null;
|
||||
try {
|
||||
userDetails = userDetailsService.loadUserByEmail(email, code, deviceInfo, RequestContextHolderUtils.getRemoteAddr());
|
||||
userDetailsService.login(email, userDetails, LoginTypeEnum.EMAIL, deviceInfo, code);
|
||||
} catch (CustomOAuth2Exception e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
return new EmailAuthenticationToken(userDetails, Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<?> aClass) {
|
||||
return EmailAuthenticationToken.class.isAssignableFrom(aClass);
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package com.accompany.oauth2.support.email;
|
||||
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
|
||||
public class EmailAuthenticationToken extends AbstractAuthenticationToken {
|
||||
|
||||
protected static final String EMAIL = "email";
|
||||
|
||||
protected static final String CODE = "code";
|
||||
|
||||
private final Object principal;
|
||||
private final Object credentials;
|
||||
|
||||
public EmailAuthenticationToken(Object principal, Object credentials) {
|
||||
super(null);
|
||||
this.principal = principal;
|
||||
this.credentials = credentials;
|
||||
this.setAuthenticated(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCredentials() {
|
||||
return credentials;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPrincipal() {
|
||||
return principal;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,39 @@
|
||||
package com.accompany.oauth2.support.email;
|
||||
|
||||
import com.accompany.oauth2.constant.GrantTypeEnum;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
|
||||
import org.springframework.security.oauth2.provider.*;
|
||||
import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
|
||||
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class EmailTokenGranter extends AbstractTokenGranter {
|
||||
|
||||
private final AuthenticationManager authenticationManager;
|
||||
|
||||
public EmailTokenGranter(AuthenticationManager authenticationManager,
|
||||
AuthorizationServerTokenServices tokenServices,
|
||||
ClientDetailsService clientDetailsService,
|
||||
OAuth2RequestFactory requestFactory) {
|
||||
super(tokenServices, clientDetailsService, requestFactory, GrantTypeEnum.EMAIL.getValue());
|
||||
this.authenticationManager = authenticationManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
|
||||
Map<String, String> parameters = tokenRequest.getRequestParameters();
|
||||
String email = parameters.get(EmailAuthenticationToken.EMAIL);
|
||||
String code = parameters.get(EmailAuthenticationToken.CODE);
|
||||
EmailAuthenticationToken token = new EmailAuthenticationToken(email, code);
|
||||
token.setDetails(parameters);
|
||||
Authentication authentication = authenticationManager.authenticate(token);
|
||||
if (authentication == null || !authentication.isAuthenticated()) {
|
||||
throw new InvalidGrantException("Could not authenticate user: " + email);
|
||||
}
|
||||
OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);
|
||||
return new OAuth2Authentication(storedOAuth2Request, authentication);
|
||||
}
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
package com.accompany.oauth2.ticket;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.accompany.common.device.DeviceInfo;
|
||||
import com.accompany.core.model.Account;
|
||||
import com.accompany.core.model.AccountLoginRecord;
|
||||
@@ -106,7 +107,7 @@ public class TicketServices implements InitializingBean {
|
||||
Account account = accountDetails.getAccount();
|
||||
Long uid = account.getUid();
|
||||
Users users = usersBaseService.getUsersByUid(uid);
|
||||
Long blockEndTime = accountBlockCheckService.checkReturnEndTime(account.getErbanNo(), account.getPhone(), "", "");
|
||||
Long blockEndTime = accountBlockCheckService.checkReturnEndTime(account.getErbanNo(), account.getPhone(), account.getEmail(), StrUtil.EMPTY, StrUtil.EMPTY);
|
||||
//检查账号、设备号、号段是否封禁
|
||||
if (null != blockEndTime){
|
||||
CustomOAuth2Exception exception = new CustomOAuth2Exception(CustomOAuth2Exception.ACCOUNT_ERROR, "");
|
||||
|
@@ -5,6 +5,7 @@ import com.accompany.oauth2.constant.GrantTypeEnum;
|
||||
import com.accompany.oauth2.exception.CustomOAuth2WebResponseExceptionTranslator;
|
||||
import com.accompany.oauth2.jwt.JwtTicketConverter;
|
||||
import com.accompany.oauth2.jwt.JwtTokenConverter;
|
||||
import com.accompany.oauth2.support.email.EmailTokenGranter;
|
||||
import com.accompany.oauth2.support.password.PasswordTokenGranter;
|
||||
import com.accompany.oauth2.support.verify.VerifyCodeTokenGranter;
|
||||
import com.accompany.oauth2.ticket.RedisTicketStore;
|
||||
@@ -120,6 +121,7 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
|
||||
if (authenticationManager != null) {
|
||||
tokenGranters.add(new PasswordTokenGranter(authenticationManager, tokenServices, clientDetails, requestFactory));
|
||||
tokenGranters.add(new VerifyCodeTokenGranter(authenticationManager, tokenServices, clientDetails, requestFactory));
|
||||
tokenGranters.add(new EmailTokenGranter(authenticationManager, tokenServices, clientDetails, requestFactory));
|
||||
}
|
||||
return new CompositeTokenGranter(tokenGranters);
|
||||
}
|
||||
|
Reference in New Issue
Block a user