Commit c5b69cf5 authored by zhouqian's avatar zhouqian

好多东西

parent a07a7965
......@@ -51,19 +51,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
<version>1.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
......
......@@ -3,22 +3,17 @@ package cn.quantgroup.xyqb;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.orm.jpa.EntityScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@ComponentScan(basePackages = {"cn.quantgroup.xyqb", "cn.quantgroup.cloudconfig"})
@EnableAutoConfiguration
@SpringBootApplication
@PropertySource(value = {"classpath:application.properties", "classpath:xyqb.properties"}, ignoreResourceNotFound = true)
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 24 * 60 * 60)
@EnableCaching
@Configuration
@EnableAspectJAutoProxy
......
......@@ -35,7 +35,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.ConverterRegistry;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.session.web.http.HeaderHttpSessionStrategy;
import org.springframework.web.filter.CharacterEncodingFilter;
import com.fasterxml.jackson.annotation.JsonInclude;
......@@ -48,11 +47,6 @@ import com.fasterxml.jackson.databind.SerializationFeature;
@Configuration
public class HttpConfig {
@Bean
HeaderHttpSessionStrategy sessionStrategy() {
return new HeaderHttpSessionStrategy();
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
......
package cn.quantgroup.xyqb.config.security;
import cn.quantgroup.xyqb.exception.PasswordErrorException;
import cn.quantgroup.xyqb.exception.UserNotExistException;
import cn.quantgroup.xyqb.exception.VerificationCodeErrorException;
import cn.quantgroup.xyqb.model.JsonResult;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* Created by Miraculous on 15/7/5.
*/
public class RESTAuthenticationEntryPoint implements AuthenticationEntryPoint {
private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().create();
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
JsonResult result = JsonResult.buildErrorStateResult("登录失败", null);
if (e instanceof UserNotExistException || e.getCause() instanceof UserNotExistException) {
result.setMsg("该用户名不存在,<br/>请重新输入或注册新账号。");
} else if (e instanceof PasswordErrorException || e.getCause() instanceof PasswordErrorException) {
result.setMsg("您的密码输入错误,<br/>请重新输入。");
}
response.setStatus(HttpStatus.SC_OK);
response.setContentType("application/javascript; charset=utf-8");
PrintWriter out = response.getWriter();
out.println(GSON.toJson(result));
out.flush();
out.close();
}
}
package cn.quantgroup.xyqb.config.security;
import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.exception.PasswordErrorException;
import cn.quantgroup.xyqb.filter.AppAuthenticatedFilter;
import cn.quantgroup.xyqb.filter.Jr58AuthenticatedFilter;
import cn.quantgroup.xyqb.filter.SmsLoginAuthenticatedFilter;
import cn.quantgroup.xyqb.util.PasswordUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.StringUtils;
/**
* Created by Miraculous on 15/7/4.
*/
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("userDetailsService")
private UserDetailsService userDetailsService;
@Autowired
private Jr58AuthenticatedFilter jr58AuthenticatedFilter;
@Autowired
private AppAuthenticatedFilter appAuthenticatedFilter;
@Autowired
private SmsLoginAuthenticatedFilter smsLoginAuthenticatedFilter;
@Value("${xyqb.security.allowedRoutes}")
private String allowedRoutes;
@Override
protected void configure(HttpSecurity http) throws Exception {
String[] allowedRoutesArr = allowedRoutes.split(",");
http
.csrf().disable()
.authorizeRequests()
.antMatchers(allowedRoutesArr).permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(new RESTAuthenticationEntryPoint())
.and()
.addFilter(jr58AuthenticatedFilter)
.addFilter(appAuthenticatedFilter)
.addFilter(smsLoginAuthenticatedFilter)
.logout();
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new PasswordEncoder() {
@Override
public String encode(CharSequence rawPass) {
return PasswordUtil.MD5(rawPass.toString().toLowerCase() + Constants.PASSWORD_SALT);
}
@Override
public boolean matches(CharSequence rawPass, String password) {
if (StringUtils.isEmpty(password)) {
throw new PasswordErrorException("密码错误");
}
if (password.equals(PasswordUtil.MD5(rawPass.toString().toLowerCase() + Constants.PASSWORD_SALT))) {
return true;
}
throw new PasswordErrorException("密码错误");
}
});
}
@Override
public UserDetailsService userDetailsServiceBean() {
return userDetailsService;
}
}
package cn.quantgroup.xyqb.controller;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.model.AuthenticationUserDetail;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
......@@ -16,11 +14,7 @@ import javax.servlet.http.HttpSession;
public interface IBaseController {
default User getCurrentUser() {
if (null == SecurityContextHolder.getContext().getAuthentication()) {
return null;
}
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
return (AuthenticationUserDetail) principal;
return null;
}
default HttpSession getSession() {
......
......@@ -4,8 +4,6 @@ import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.controller.IBaseController;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.entity.UserDetail;
import cn.quantgroup.xyqb.exception.NullUserException;
import cn.quantgroup.xyqb.exception.UserNotExistException;
import cn.quantgroup.xyqb.model.AuthBean;
import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.model.UserModel;
......@@ -17,7 +15,6 @@ import cn.quantgroup.xyqb.service.user.IUserService;
import cn.quantgroup.xyqb.util.PasswordUtil;
import cn.quantgroup.xyqb.util.ValidationUtil;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -25,7 +22,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.web.WebAttributes;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
......@@ -145,13 +141,6 @@ public class UserController implements IBaseController {
*/
@RequestMapping("/login/fast")
public JsonResult loginFast(Principal user) {
if (user == null) {
RuntimeException theLastException = (RuntimeException) getRequest().getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
if (theLastException instanceof UserNotExistException || theLastException.getCause() instanceof UserNotExistException) {
return JsonResult.buildErrorStateResult("该用户名不存在,<br/>请重新输入或注册新账号。", null);
}
throw theLastException;
}
AuthBean bean = new AuthBean(getRequest().getSession().getId(), user);
LOGGER.info("用户快速登录成功, loginFrom:{}, phoneNo:{},appChannel:{}", getCreatedFrom(), user.getName(), getAppChannel());
return new JsonResult(bean);
......
package cn.quantgroup.xyqb.exception;
import org.springframework.security.core.AuthenticationException;
/**
* @author mengfan.feng
* @time 2015-09-08 17:49
*/
public class PasswordErrorException extends AuthenticationException {
public class PasswordErrorException extends RuntimeException {
private static final long serialVersionUID = -1L;
......
package cn.quantgroup.xyqb.exception;
import org.springframework.security.core.AuthenticationException;
/**
* @author mengfan.feng
* @time 2015-09-08 17:43
*/
public class UserNotExistException extends AuthenticationException {
public class UserNotExistException extends RuntimeException{
private static final long serialVersionUID = -1L;
......
package cn.quantgroup.xyqb.exception;
import org.springframework.security.core.AuthenticationException;
/**
* Created by Miraculous on 15/7/11.
*/
public class VerificationCodeErrorException extends AuthenticationException {
public class VerificationCodeErrorException extends RuntimeException {
private static final long serialVersionUID = -1L;
......
package cn.quantgroup.xyqb.filter;
import cn.quantgroup.xyqb.model.AppUserParam;
import cn.quantgroup.xyqb.service.security.impl.UserDetailsByPhoneService;
import cn.quantgroup.xyqb.util.IPUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* @author mengfan.feng
* @time 2015-10-26 15:58
*/
@Component
public class AppAuthenticatedFilter extends AbstractPreAuthenticatedProcessingFilter {
private static final Logger LOGGER = LoggerFactory.getLogger(AppAuthenticatedFilter.class);
@Autowired
public AppAuthenticatedFilter(UserDetailsByPhoneService userDetailsService) {
PreAuthenticatedAuthenticationProvider authProvider = new PreAuthenticatedAuthenticationProvider();
authProvider.setPreAuthenticatedUserDetailsService(userDetailsService);
this.setAuthenticationManager(authProvider::authenticate);
}
@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
String path = request.getRequestURI();
if (!"/app/login".equals(path)) {
return null;
}
String requestIp = IPUtil.getRemoteIP(request);
String loginFrom = request.getParameter("registerFrom");
if(StringUtils.isBlank(loginFrom)){
loginFrom = "0";
}
LOGGER.info("第三方用户登录, loginFrom:{}, requestIp:{}", loginFrom, requestIp);
// if (!configurationService.validateIp(loginFrom, requestIp)) {
// LOGGER.info("第三方用户登录,ip校验失败, loginFrom:{}, requestIp:{}", loginFrom, requestIp);
// return null;
// }
request.setAttribute("channelId", "1");
request.setAttribute("createdFrom", loginFrom + "");
AppUserParam param = AppUserParam.builder()
.phoneNo(request.getParameter("phoneNo"))
.registerFrom(Long.valueOf(loginFrom))
.idNo(request.getParameter("idNo"))
.name(request.getParameter("name"))
.build();
return param;
}
@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
return "dummy credentials";
}
}
package cn.quantgroup.xyqb.filter;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.WebUtils;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Created by Miraculous on 15/7/4.
*/
public class CsrfHeaderFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie==null || token!=null && !token.equals(cookie.getValue())) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
}
package cn.quantgroup.xyqb.filter;
import cn.quantgroup.xyqb.service.security.impl.UserDetailsByUuidService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
@Component
public class Jr58AuthenticatedFilter extends AbstractPreAuthenticatedProcessingFilter {
@Autowired
public Jr58AuthenticatedFilter(UserDetailsByUuidService userDetailsService) {
PreAuthenticatedAuthenticationProvider authProvider = new PreAuthenticatedAuthenticationProvider();
authProvider.setPreAuthenticatedUserDetailsService(userDetailsService);
this.setAuthenticationManager(authProvider::authenticate);
}
@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
String paramValue = request.getParameter("userId");
return StringUtils.isEmpty(paramValue) ? null : paramValue.toLowerCase();
}
@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
return "dummy credentials";
}
}
package cn.quantgroup.xyqb.filter;
import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.controller.IBaseController;
import cn.quantgroup.xyqb.model.AppSmsUserParam;
import cn.quantgroup.xyqb.service.security.impl.UserDetailsBySmsService;
import cn.quantgroup.xyqb.service.sms.ISmsService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.Base64;
/**
* @author xiaoguang.xu
* @time 2016-03-08 18:24
*/
@Component
public class SmsLoginAuthenticatedFilter extends AbstractPreAuthenticatedProcessingFilter implements IBaseController {
private static final Logger LOGGER = LoggerFactory.getLogger(SmsLoginAuthenticatedFilter.class);
private static final int SMS_VERIFICATION_MAXLEN = 6;
@Autowired
private RedisTemplate<String, String> stringRedisTemplate;
@Autowired
private ISmsService smsService;
@Autowired
public SmsLoginAuthenticatedFilter(UserDetailsBySmsService userDetailsService) {
PreAuthenticatedAuthenticationProvider authProvider = new PreAuthenticatedAuthenticationProvider();
authProvider.setPreAuthenticatedUserDetailsService(userDetailsService);
this.setAuthenticationManager(authProvider::authenticate);
}
@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
String path = request.getRequestURI();
if (!"/user/login/fast".equals(path)) {
return null;
}
String authorization = request.getHeader("Authorization");
if (authorization == null) {
return AppSmsUserParam.builder().errorMsg("登陆失败").build();
}
String[] basicUserAndCode = authorization.split(" ");
if (basicUserAndCode == null || basicUserAndCode.length != 2) {
return AppSmsUserParam.builder().errorMsg("登陆失败").build();
}
if (!"Verification".equals(basicUserAndCode[0])) {
return AppSmsUserParam.builder().errorMsg("登陆失败").build();
}
String userAndCodeStr = new String(Base64.getDecoder().decode(basicUserAndCode[1]));
String[] userCodeArray = userAndCodeStr.split(":");
String verificationCode = userCodeArray[1];
String phoneNo = userCodeArray[0];
LOGGER.info("用户快速登录,phoneNo:{} , verificationCode:{}", phoneNo, verificationCode);
if (!validSmsVerificationCode(phoneNo, verificationCode)) {
LOGGER.info("用户快速登录,验证码校验失败,phoneNo:{} , verificationCode:{}", phoneNo, verificationCode);
return AppSmsUserParam.builder().phoneNo(phoneNo).errorMsg("验证码错误").build();
}
String createdFrom = request.getParameter("createdFrom");
if (StringUtils.isEmpty(createdFrom)) {
createdFrom = "1";
}
String channelId = request.getParameter("channelId");
request.setAttribute("channelId", channelId);
request.setAttribute("createdFrom", createdFrom);
AppSmsUserParam param = AppSmsUserParam.builder()
.phoneNo(phoneNo)
.registerFrom(Long.valueOf(createdFrom))
.ip(getIp())
.appChannel(getAppChannel())
.channelId(Long.parseLong(channelId))
.build();
return param;
}
/**
* 检查验证码是否正确
*
* @param phoneNo
* @param smsVerificationCode
* @return
*/
private boolean validSmsVerificationCode(String phoneNo, String smsVerificationCode) {
if (StringUtils.isEmpty(smsVerificationCode) || smsVerificationCode.length() != SMS_VERIFICATION_MAXLEN) {
return false;
}
String key = Constants.REDIS_PREFIX_VERIFICATION_CODE + phoneNo;
String randomCode = stringRedisTemplate.opsForValue().get(key);
if (StringUtils.isEmpty(randomCode)) {
return false;
}
String[] arr = randomCode.split(":");
String unqiueId = arr[0];
String code = arr[1];
if (StringUtils.equals(code, smsVerificationCode)) {
try {
smsService.getSmsSender().confirmSmsResult("1", unqiueId);
} catch (Exception e) {
LOGGER.info("短信验证像短信中心确认失效");
}
return true;
}
return false;
}
@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
return "dummy credentials";
}
}
package cn.quantgroup.xyqb.model;
import cn.quantgroup.xyqb.entity.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.LinkedList;
/**
* Created by Miraculous on 15/7/5.
*/
public class AuthenticationUserDetail extends User implements UserDetails {
private static final long serialVersionUID = -1L;
public AuthenticationUserDetail(User user) {
this.setPhoneNo(user.getPhoneNo());
this.setId(user.getId());
this.setRegisteredFrom(user.getRegisteredFrom());
this.setPassword(user.getPassword());
this.setUuid(user.getUuid());
this.setEnable(user.getEnable());
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> authorities = new LinkedList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
return authorities;
}
@Override
public String getPassword() {
return super.getPassword();
}
@Override
public String getUsername() {
return super.getPhoneNo();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return super.getEnable();
}
}
package cn.quantgroup.xyqb.service.security.impl;
import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.entity.UserDetail;
import cn.quantgroup.xyqb.exception.UserNotExistException;
import cn.quantgroup.xyqb.model.AppUserParam;
import cn.quantgroup.xyqb.model.AuthenticationUserDetail;
import cn.quantgroup.xyqb.model.IdCardInfo;
import cn.quantgroup.xyqb.model.IdType;
import cn.quantgroup.xyqb.repository.IUserDetailRepository;
import cn.quantgroup.xyqb.repository.IUserRepository;
import cn.quantgroup.xyqb.service.auth.IIdCardService;
import cn.quantgroup.xyqb.service.sms.ISmsService;
import cn.quantgroup.xyqb.service.user.ILkbUserService;
import cn.quantgroup.xyqb.service.user.IUserService;
import cn.quantgroup.xyqb.util.PasswordUtil;
import cn.quantgroup.xyqb.util.ValidationUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.stereotype.Service;
import java.sql.Timestamp;
import java.util.Random;
/**
* @author mengfan.feng
* @time 2015-10-26 16:00
*/
@Service
public class UserDetailsByPhoneService implements AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
private static final Logger LOGGER = LoggerFactory.getLogger(UserDetailsByPhoneService.class);
@Autowired
private IUserService userService;
@Autowired
private ILkbUserService lkbUserService;
@Autowired
private ISmsService smsService;
@Autowired
private IUserRepository userRepository;
@Autowired
private IIdCardService idCardService;
@Autowired
private IUserDetailRepository userDetailRepository;
private static final Random random = new Random();
@Override
public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token) throws UsernameNotFoundException {
AppUserParam param = (AppUserParam) token.getPrincipal();
User user = userService.findByPhone(param.getPhoneNo());
if (user == null) {
LOGGER.info("第三方登录用户不存在,开始注册,{}", param);
user = this.register(param);
}
if (user == null) {
throw new UserNotExistException(String.format("用户未找到, phone:%s", param.getPhoneNo()));
}
return new AuthenticationUserDetail(user);
}
/**
* 注册新用户
*
* @param param
* @return
*/
private User register(AppUserParam param) {
if (!ValidationUtil.validatePhoneNo(param.getPhoneNo())) {
return null;
}
String randomCode = String.valueOf(random.nextInt(899999) + 100000);
String uuid = lkbUserService.registerApp(param.getPhoneNo(), randomCode);
Timestamp currentTime = new Timestamp(System.currentTimeMillis());
LOGGER.info("第三方登录用户,保存 User");
User user = new User();
user.setEnable(true);
user.setPhoneNo(param.getPhoneNo());
user.setUpdatedAt(currentTime);
user.setCreatedAt(currentTime);
user.setUuid(uuid);
user.setPassword(PasswordUtil.MD5(randomCode + Constants.PASSWORD_SALT));
user.setRegisteredFrom(param.getRegisterFrom());
user = userRepository.save(user);
if (user == null) {
throw new RuntimeException("保存用户出错");
}
smsService.sendAfterRegister(param.getPhoneNo());
LOGGER.info("第三方登录用户注册成功, registerFrom:{}, phoneNo:{}, 并且已发送短信通知", param.getRegisterFrom(), param.getPhoneNo());
if (StringUtils.isNotEmpty(param.getIdNo())) {
LOGGER.info("第三方登录用户,保存 UserDetail");
IdCardInfo cardInfo;
try {
cardInfo = idCardService.getIdCardInfoWithExceptions(param.getIdNo());
UserDetail userDetail = new UserDetail();
userDetail.setIdNo(cardInfo.getIdNo());
userDetail.setPhoneNo(param.getPhoneNo());
userDetail.setName(param.getName());
userDetail.setIdType(IdType.ID_CARD);
userDetail.setUpdatedAt(currentTime);
userDetail.setCreatedAt(currentTime);
userDetail.setUserId(user.getId());
userDetail.setGender(cardInfo.getGender());
userDetailRepository.saveAndFlush(userDetail);
lkbUserService.userUpdate(user.getUuid(), param.getName(), cardInfo.getIdNo());
} catch (Exception e) {
LOGGER.error("保存 UserDetail 出现异常", e);
}
}
return user;
}
}
package cn.quantgroup.xyqb.service.security.impl;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.exception.UserNotExistException;
import cn.quantgroup.xyqb.exception.VerificationCodeErrorException;
import cn.quantgroup.xyqb.model.AppSmsUserParam;
import cn.quantgroup.xyqb.model.AuthenticationUserDetail;
import cn.quantgroup.xyqb.service.user.IUserService;
import cn.quantgroup.xyqb.util.ValidationUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.stereotype.Service;
import java.util.Random;
/**
* @author xiaoguang.xu
* @time 2016-03-16 13:00
*/
@Service
public class UserDetailsBySmsService implements AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
private static final Logger LOGGER = LoggerFactory.getLogger(UserDetailsBySmsService.class);
@Autowired
private IUserService userService;
@Override
public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token) throws UsernameNotFoundException {
AppSmsUserParam param = (AppSmsUserParam) token.getPrincipal();
if (param.getPhoneNo() == null) {
throw new UserNotExistException("用户未找到");
}
if (null != param.getErrorMsg()) {
throw new VerificationCodeErrorException(param.getErrorMsg());
}
User user = userService.findByPhone(param.getPhoneNo());
if (user == null) {
user = registerFastWhenLogin(param.getPhoneNo(), param.getChannelId(), param.getRegisterFrom(), param.getAppChannel());
if (user == null) {
throw new UserNotExistException("用户未找到");
}
}
return new AuthenticationUserDetail(user);
}
public User registerFastWhenLogin(String phoneNo, Long channelId, Long registerFrom, String appChannel) {
String password = genRandomPwd();
LOGGER.info("用户快速注册, phoneNo:{}, verificationCode:{}, channelId:{}, registerFrom:{},appChannel:{}", phoneNo, channelId, registerFrom, appChannel);
if (!ValidationUtil.validatePhoneNo(phoneNo)) {
LOGGER.info("用户快速注册失败,手机号错误, registerFrom:{}, phoneNo:{}", registerFrom, phoneNo);
throw new UserNotExistException("手机号错误");
}
if (null == registerFrom) {
registerFrom = 1L;
}
LOGGER.info("用户快速注册成功, registerFrom:{}, phoneNo:{}", registerFrom, phoneNo);
return userService.registerAndReturn(phoneNo, password, registerFrom);
}
private static final char[] PWD_BASE = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
private String genRandomPwd() {
int pwdMax = PWD_BASE.length;
int i; // 生成的随机数
int count = 0; // 生成的密码的长度
StringBuffer pwd = new StringBuffer();
Random r = new Random();
while (count < 15) {
i = Math.abs(r.nextInt(pwdMax)); // 生成的数最大为36-1
if (i >= 0 && i < PWD_BASE.length) {
pwd.append(PWD_BASE[i]);
count++;
}
}
return pwd.toString();
}
}
package cn.quantgroup.xyqb.service.security.impl;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.exception.UserNotExistException;
import cn.quantgroup.xyqb.model.AuthenticationUserDetail;
import cn.quantgroup.xyqb.service.user.IUserService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.stereotype.Service;
@Service
public class UserDetailsByUuidService implements AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
@Autowired
private IUserService userService;
@Override
public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token) throws UsernameNotFoundException {
String uuid = (String) token.getPrincipal();
if (StringUtils.isEmpty(uuid) || uuid.length() <= 10) {
throw new UserNotExistException(String.format("用户未找到, uuid:%s", uuid));
}
User user = userService.findByUuid(uuid);
if (user == null) {
throw new UserNotExistException(String.format("用户未找到, uuid:%s", uuid));
}
return new AuthenticationUserDetail(user);
}
}
package cn.quantgroup.xyqb.service.security.impl;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.exception.UserNotExistException;
import cn.quantgroup.xyqb.model.AuthenticationUserDetail;
import cn.quantgroup.xyqb.service.user.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
/**
* Created by Miraculous on 15/7/5.
*/
@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private IUserService userService;
@Override
public UserDetails loadUserByUsername(String phoneNo) throws UsernameNotFoundException {
User user = userService.findByPhone(phoneNo);
if (user == null) {
throw new UserNotExistException("未找到用户:" + phoneNo);
}else if(! user.getEnable()){
throw new UserNotExistException("用户已禁用:" + phoneNo);
}
return new AuthenticationUserDetail(user);
}
}
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