Commit bb9a9d55 authored by xiaozhe.chen's avatar xiaozhe.chen

添加修改手机号后台管理接口

parent 6ec2efac
......@@ -11,7 +11,7 @@
<parent>
<groupId>cn.quantgroup</groupId>
<artifactId>commons-parent</artifactId>
<version>0.2.4</version>
<version>0.2.5.5</version>
</parent>
......@@ -25,6 +25,7 @@
<okhttp.version>3.4.2</okhttp.version>
<retrofit.version>2.1.0</retrofit.version>
<rxjava.version>1.2.3</rxjava.version>
<org.springframework.security.version>3.2.7.RELEASE</org.springframework.security.version>
</properties>
<build>
......@@ -116,9 +117,43 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--spring security 兼容 start-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${org.springframework.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${org.springframework.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
<version>${org.springframework.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${org.springframework.security.version}</version>
</dependency>
<!--security 不兼容. 降级到 1.5.4 完全OK-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>1.5.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
<version>1.5.4.RELEASE</version>
</dependency>
<!--spring security 兼容 end-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
<version>1.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
......
package cn.quantgroup.customer.config.http.mvc.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;
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.customer.config.http.security;
import cn.quantgroup.customer.rest.JsonResult;
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;
import static cn.quantgroup.customer.constant.Constant.GSON;
public class RESTAuthenticationEntryPoint implements AuthenticationEntryPoint {
private static final String UN_AUTHORIZED_RESULT = GSON.toJson(new JsonResult("UnAuthorized request", 401L, ""));
@Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
httpServletResponse.setStatus(HttpStatus.SC_UNAUTHORIZED);
httpServletResponse.setContentType("application/javascript; charset=utf-8");
PrintWriter out = httpServletResponse.getWriter();
out.println(UN_AUTHORIZED_RESULT);
out.close();
}
}
package cn.quantgroup.customer.config.http.security;
import cn.quantgroup.customer.config.http.mvc.filter.CsrfHeaderFilter;
import cn.quantgroup.customer.constant.Constant;
import cn.quantgroup.customer.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import cn.quantgroup.customer.util.PwdUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Bean;
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.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
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.security.web.session.HttpSessionEventPublisher;
import org.springframework.web.cors.CorsUtils;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
import org.springframework.util.StringUtils;
@Slf4j
@EnableWebSecurity
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, jsr250Enabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final IUserService userService;
......@@ -35,37 +34,50 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
String allowedRoutes = "/test/**";
String[] allowedRoutesArr = allowedRoutes.split(",");
http
.authorizeRequests()
.antMatchers("/tech/health/check").permitAll()
.antMatchers("/user/login").permitAll()
.antMatchers("/user/logout-success").permitAll()
/*test*/
.antMatchers("/test/**").permitAll()
//.antMatchers("/user/**").permitAll()
/*test*/
.anyRequest().authenticated()
.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
.and().sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true)
.and().and().logout().invalidateHttpSession(true).clearAuthentication(true)
.logoutSuccessUrl("/user/logout-success").deleteCookies(Constant.COOKIE_NAME)
.and();
.antMatchers(allowedRoutesArr)
.permitAll().anyRequest().authenticated()
.and()
.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
.csrf().csrfTokenRepository(csrfTokenRepository())
.and()
.csrf()
.disable()
.logout();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(passwordEncoder);
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(new PasswordEncoder() {
@Override
public String encode(CharSequence rawPass) {
return PwdUtil.MD5(rawPass.toString().toLowerCase() + Constant.PASSWORD_SALT);
}
@Override
public boolean matches(CharSequence rawPass, String password) {
if (StringUtils.isEmpty(password)) {
return false;
}
return password.equals(PwdUtil.MD5(rawPass.toString().toLowerCase() + Constant.PASSWORD_SALT));
}
});
}
@Override
public UserDetailsService userDetailsServiceBean() {
return userService;
}
@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
}
......@@ -7,7 +7,7 @@ import org.springframework.session.web.http.HeaderHttpSessionStrategy;
import org.springframework.session.web.http.HttpSessionStrategy;
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = Constant.COOKIE_AND_SESSION_EXPIRE_TIMEOUT_SECONDS, redisNamespace = Constant.CUSTOMER_SESSION_NAMESPACE)
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = Constant.COOKIE_AND_SESSION_EXPIRE_TIMEOUT_SECONDS)
public class WebSessionConfig {
@Bean(name = "httpSessionStrategy")
public HttpSessionStrategy httpSessionStrategy() {
......
package cn.quantgroup.customer.entity;
import cn.quantgroup.customer.enums.RoleTypeEnum;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.persistence.*;
import java.sql.Timestamp;
@Entity
@Table(name = "role")
@Getter
@Setter
@ToString
public class Role {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "remark")
private String remark;
@Column(name = "role_type")
private RoleTypeEnum roleType;
@Column(name = "company_id")
private Long companyId;
@Column(name = "created_at")
private Timestamp createdAt;
@Column(name = "updated_at")
private Timestamp updatedAt;
public enum Role {
/*
| 初审|终审|统计|查询|催收|催收减免|修改订单状态
———————————————
管理员 |√ |√ |√ |√ |√ |x |x
主管 |√ |√ |√ |√ |√ |x |x
终审人员 |√ |√ |x |√ |x |x |x
初审人员 |√ |x |x |√ |x |x |x
催收人员 |x |x |x |x |√ |x |x
催收主管 |x |x |x |x |√ |√ |x
运营人员 |x |x |x |x |x |x |√
*/
ADMINISTRATOR("管理员"),
SUPERVISOR("主管"),
FINAL_AUDITOR("终审人员"),
FIRST_AUDITOR("初审人员"),
CUSTOMER_SERVICE("客服人员"),
DEBT_COLLECTOR("催收人员"),
DEBT_SUPERVISOR("催收主管"),
OPERATOR("运营人员");
private String name;
Role(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return name;
}
}
......@@ -3,21 +3,17 @@ package cn.quantgroup.customer.entity;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import javax.persistence.*;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.List;
@Entity
@Table(name = "user", uniqueConstraints = {@UniqueConstraint(columnNames = {"username"})})
@Getter
@Setter
@ToString
public class User implements Serializable, UserDetails {
public class User implements Serializable {
private static final long serialVersionUID = 1L;
......@@ -35,14 +31,14 @@ public class User implements Serializable, UserDetails {
@Column(name = "password", nullable = false)
private String password;
@Column(name = "company_id")
private Long companyId;
@Column(name = "enable")
private Boolean enable;
@Column(name = "role")
private Long role;
@Column(name = "company_id")
private Long companyId;
private Role role;
@Column(name = "created_at")
private Timestamp createdAt;
......@@ -50,41 +46,78 @@ public class User implements Serializable, UserDetails {
@Column(name = "updated_at")
private Timestamp updatedAt;
@Transient
private List<? extends GrantedAuthority> authorities;
public User() {
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
public Boolean isEnable() {
return enable;
}
@Override
public String getPassword() {
return this.password;
public void setEnable(Boolean enable) {
this.enable = enable;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Override
public String getUsername() {
return this.username;
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Long getCompanyId() {
return companyId;
}
public void setCompanyId(Long companyId) {
this.companyId = companyId;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
@Override
public boolean isAccountNonExpired() {
return true;
public Timestamp getCreatedAt() {
return createdAt;
}
@Override
public boolean isAccountNonLocked() {
return true;
public void setCreatedAt(Timestamp createdAt) {
this.createdAt = createdAt;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
public Timestamp getUpdatedAt() {
return updatedAt;
}
@Override
public boolean isEnabled() {
return this.enable;
public void setUpdatedAt(Timestamp updatedAt) {
this.updatedAt = updatedAt;
}
}
package cn.quantgroup.customer.rest;
import cn.quantgroup.customer.entity.User;
import cn.quantgroup.customer.enums.ErrorCodeEnum;
import cn.quantgroup.customer.rest.param.LoginParam;
import cn.quantgroup.customer.rest.param.ModifyPhoneAudit;
......@@ -8,13 +7,13 @@ import cn.quantgroup.customer.rest.param.ModifyPhoneFeedback;
import cn.quantgroup.customer.rest.param.ModifyPhoneQuery;
import cn.quantgroup.customer.rest.vo.AuthUserVo;
import cn.quantgroup.customer.service.IUserService;
import cn.quantgroup.riskcontrol.model.AuthenticationUserDetail;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
......@@ -47,7 +46,7 @@ public class UserRest {
session.setAttribute(SPRING_SECURITY_CONTEXT, SecurityContextHolder.getContext());
if (authentication != null && authentication.isAuthenticated()) {
User principal = (User) authentication.getPrincipal();
AuthenticationUserDetail principal = (AuthenticationUserDetail) authentication.getPrincipal();
AuthUserVo authUserVo = AuthUserVo.parse(principal);
return JsonResult.buildSuccessResult(LOGIN_SUCCESS, authUserVo);
}
......@@ -55,7 +54,7 @@ public class UserRest {
}
@PostMapping(value = "/logout")
public JsonResult logout(@AuthenticationPrincipal User user) {
public JsonResult logout() {
return JsonResult.buildSuccessResult(LOGOUT_SUCCESS, null);
}
......
package cn.quantgroup.customer.rest.vo;
import cn.quantgroup.customer.entity.User;
import cn.quantgroup.riskcontrol.model.AuthenticationUserDetail;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
......@@ -17,7 +17,7 @@ public class AuthUserVo {
private String username;
private List<String> authorities;
public static AuthUserVo parse(User user) {
public static AuthUserVo parse(AuthenticationUserDetail user) {
AuthUserVo.AuthUserVoBuilder builder = AuthUserVo.builder();
builder.username(user.getUsername());
if (CollectionUtils.isNotEmpty(user.getAuthorities())) {
......
......@@ -15,6 +15,7 @@ import cn.quantgroup.customer.rest.param.ModifyPhoneFeedback;
import cn.quantgroup.customer.rest.param.ModifyPhoneQuery;
import cn.quantgroup.customer.service.IUserService;
import cn.quantgroup.customer.service.http.IHttpService;
import cn.quantgroup.riskcontrol.model.AuthenticationUserDetail;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
......@@ -61,21 +62,7 @@ public class UserServiceImpl implements IUserService {
if (user == null) {
throw new UsernameNotFoundException("user: " + userName + " do not exist!");
}
/*
List<UserRole> userRoles = findUserRoleByUserId(user.getId());
if (CollectionUtils.isNotEmpty(userRoles)) {
List<RoleAuthority> roleAuthorityList = findRoleAuthorityByRoleIds(
userRoles.stream().map(UserRole::getRoleId).collect(Collectors.toList()));
if (CollectionUtils.isNotEmpty(roleAuthorityList)) {
List<Authority> authorities = findAuthorityByAuthorityIds(
roleAuthorityList.stream().map(RoleAuthority::getAuthorityId).collect(Collectors.toList()));
user.setAuthorities(authorities);
}
}
*/
return user;
return new AuthenticationUserDetail(user);
}
@Override
......
package cn.quantgroup.riskcontrol.model;
import cn.quantgroup.customer.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;
public class AuthenticationUserDetail extends User implements UserDetails {
private static final long serialVersionUID = 1L;
public AuthenticationUserDetail(User user) {
this.setUsername(user.getUsername());
this.setId(user.getId());
this.setRole(user.getRole());
this.setCompanyId(user.getCompanyId());
this.setName(user.getName());
this.setPassword(user.getPassword());
this.setEnable(user.isEnable());
}
@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.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return isEnable();
}
}
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