|
@@ -6,15 +6,18 @@ import cn.reghao.devops.manager.account.model.po.User;
|
|
|
import cn.reghao.devops.manager.account.security.exceptioin.AccountLoginException;
|
|
import cn.reghao.devops.manager.account.security.exceptioin.AccountLoginException;
|
|
|
import cn.reghao.devops.manager.account.security.form.AccountAuthToken;
|
|
import cn.reghao.devops.manager.account.security.form.AccountAuthToken;
|
|
|
import cn.reghao.devops.manager.account.service.AccountAuthService;
|
|
import cn.reghao.devops.manager.account.service.AccountAuthService;
|
|
|
|
|
+import cn.reghao.devops.manager.account.service.CodeService;
|
|
|
|
|
+import cn.reghao.devops.manager.account.service.PubkeyService;
|
|
|
|
|
+import cn.reghao.devops.manager.util.CacheKeys;
|
|
|
import cn.reghao.jutil.web.ServletUtil;
|
|
import cn.reghao.jutil.web.ServletUtil;
|
|
|
import com.github.benmanes.caffeine.cache.Cache;
|
|
import com.github.benmanes.caffeine.cache.Cache;
|
|
|
-import org.springframework.security.authentication.DisabledException;
|
|
|
|
|
import org.springframework.security.core.Authentication;
|
|
import org.springframework.security.core.Authentication;
|
|
|
import org.springframework.security.core.context.SecurityContext;
|
|
import org.springframework.security.core.context.SecurityContext;
|
|
|
import org.springframework.security.core.context.SecurityContextHolder;
|
|
import org.springframework.security.core.context.SecurityContextHolder;
|
|
|
import org.springframework.security.core.userdetails.UserDetails;
|
|
import org.springframework.security.core.userdetails.UserDetails;
|
|
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
|
|
|
|
+import org.springframework.security.web.authentication.preauth.PreAuthenticatedCredentialsNotFoundException;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
import javax.servlet.http.Cookie;
|
|
import javax.servlet.http.Cookie;
|
|
@@ -29,54 +32,69 @@ public class AccountAuthServiceImpl implements AccountAuthService {
|
|
|
private final String domain = "";
|
|
private final String domain = "";
|
|
|
private final Cache<String, Object> caffeineCache;
|
|
private final Cache<String, Object> caffeineCache;
|
|
|
private final UserRepository userRepository;
|
|
private final UserRepository userRepository;
|
|
|
|
|
+ private final CodeService codeService;
|
|
|
|
|
+ private final PubkeyService pubkeyService;
|
|
|
private final PasswordEncoder passwordEncoder;
|
|
private final PasswordEncoder passwordEncoder;
|
|
|
|
|
|
|
|
public AccountAuthServiceImpl(Cache<String, Object> caffeineCache, UserRepository userRepository,
|
|
public AccountAuthServiceImpl(Cache<String, Object> caffeineCache, UserRepository userRepository,
|
|
|
- PasswordEncoder passwordEncoder) {
|
|
|
|
|
|
|
+ CodeService codeService, PubkeyService pubkeyService, PasswordEncoder passwordEncoder) {
|
|
|
this.caffeineCache = caffeineCache;
|
|
this.caffeineCache = caffeineCache;
|
|
|
this.userRepository = userRepository;
|
|
this.userRepository = userRepository;
|
|
|
|
|
+ this.codeService = codeService;
|
|
|
|
|
+ this.pubkeyService = pubkeyService;
|
|
|
this.passwordEncoder = passwordEncoder;
|
|
this.passwordEncoder = passwordEncoder;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public AccountAuthToken getPreAuthentication(AccountLoginDto userLoginDto) {
|
|
|
|
|
- String principal = userLoginDto.getUsername();
|
|
|
|
|
- String credential = userLoginDto.getPassword();
|
|
|
|
|
- Boolean rememberMe = userLoginDto.getRememberMe();
|
|
|
|
|
|
|
+ public AccountAuthToken getPreAuthentication(AccountLoginDto accountLoginDto) {
|
|
|
|
|
+ String principal = accountLoginDto.getPrincipal();
|
|
|
|
|
+ String credential = accountLoginDto.getCredential();
|
|
|
|
|
+ String captchaCode = accountLoginDto.getCaptchaCode();
|
|
|
|
|
+ Boolean rememberMe = accountLoginDto.getRememberMe();
|
|
|
|
|
+
|
|
|
|
|
+ String savedCaptchaCode = codeService.getCaptcha();
|
|
|
|
|
+ if (savedCaptchaCode == null) {
|
|
|
|
|
+ String errMsg = "当前会话已过期, 请刷新页面后重新登录. 或者检查浏览器是否禁用了 cookie";
|
|
|
|
|
+ throw new PreAuthenticatedCredentialsNotFoundException(errMsg);
|
|
|
|
|
+ } else if (!savedCaptchaCode.equalsIgnoreCase(captchaCode)) {
|
|
|
|
|
+ String errMsg = "图形验证码不正确...";
|
|
|
|
|
+ throw new PreAuthenticatedCredentialsNotFoundException(errMsg);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ String decryptCredential;
|
|
|
|
|
+ try {
|
|
|
|
|
+ decryptCredential = pubkeyService.decrypt(credential);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ throw new PreAuthenticatedCredentialsNotFoundException(e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
String loginId = ServletUtil.getSessionId();
|
|
String loginId = ServletUtil.getSessionId();
|
|
|
- return new AccountAuthToken(loginId, rememberMe, principal, credential);
|
|
|
|
|
|
|
+ return new AccountAuthToken(loginId, rememberMe, principal, decryptCredential);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
|
|
User user = userRepository.findByUsername(username);
|
|
User user = userRepository.findByUsername(username);
|
|
|
- if (user != null) {
|
|
|
|
|
- return user;
|
|
|
|
|
- } else {
|
|
|
|
|
- // Spring Security 会将 UsernameNotFoundException 捕获并替换,使得前端无法看到信息
|
|
|
|
|
- //throw new UsernameNotFoundException(email + " 未注册");
|
|
|
|
|
- throw new DisabledException(username + " 未注册");
|
|
|
|
|
|
|
+ if (user == null) {
|
|
|
|
|
+ String errMsg = String.format("帐号 %s 不存在", username);
|
|
|
|
|
+ throw new UsernameNotFoundException(errMsg);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ return user;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public AccountAuthToken authByPassword(AccountAuthToken authToken) {
|
|
public AccountAuthToken authByPassword(AccountAuthToken authToken) {
|
|
|
String username = (String) authToken.getPrincipal();
|
|
String username = (String) authToken.getPrincipal();
|
|
|
- User userDetail = (User) loadUserByUsername(username);
|
|
|
|
|
- if (userDetail == null) {
|
|
|
|
|
- String errMsg = String.format("帐号 %s 未注册", username);
|
|
|
|
|
- throw new UsernameNotFoundException(errMsg);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ User user = (User) loadUserByUsername(username);
|
|
|
String password = (String) authToken.getCredentials();
|
|
String password = (String) authToken.getCredentials();
|
|
|
- String encodedPassword = passwordEncoder.encode(password + userDetail.getSalt());
|
|
|
|
|
- if (!userDetail.getPassword().equals(encodedPassword)) {
|
|
|
|
|
|
|
+ String encodedPassword = passwordEncoder.encode(password + user.getSalt());
|
|
|
|
|
+ if (!user.getPassword().equals(encodedPassword)) {
|
|
|
String errMsg = "账号或密码不正确";
|
|
String errMsg = "账号或密码不正确";
|
|
|
throw new AccountLoginException(errMsg);
|
|
throw new AccountLoginException(errMsg);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return new AccountAuthToken(authToken, userDetail);
|
|
|
|
|
|
|
+ return new AccountAuthToken(authToken, user);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -89,7 +107,7 @@ public class AccountAuthServiceImpl implements AccountAuthService {
|
|
|
Cookie cookie3 = generateCookie(cookieName, userdata, timeout);
|
|
Cookie cookie3 = generateCookie(cookieName, userdata, timeout);
|
|
|
ServletUtil.getResponse().addCookie(cookie3);
|
|
ServletUtil.getResponse().addCookie(cookie3);
|
|
|
|
|
|
|
|
- String loginSuccessKey = String.format("account:login:success:%s:%s:%s", userId, plat, loginId);
|
|
|
|
|
|
|
+ String loginSuccessKey = CacheKeys.getLoginSuccessKey(userId, plat, loginId);
|
|
|
if (timeout == 0) {
|
|
if (timeout == 0) {
|
|
|
timeout = 3600*24*30;
|
|
timeout = 3600*24*30;
|
|
|
}
|
|
}
|