parent
b03afbf971
commit
2a143a4bd3
49 changed files with 1929 additions and 130 deletions
@ -0,0 +1,17 @@ |
||||
package com.daqing.financial.hrauth.dao; |
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
import com.daqing.framework.domain.hrms.EmployeeRoleEntity; |
||||
import org.apache.ibatis.annotations.Mapper; |
||||
|
||||
/** |
||||
* |
||||
* |
||||
* @author gongsj |
||||
* @email gongsj@gmail.com |
||||
* @date 2020-09-14 09:35:05 |
||||
*/ |
||||
@Mapper |
||||
public interface AuthEmployeeRoleDao extends BaseMapper<EmployeeRoleEntity> { |
||||
|
||||
} |
@ -0,0 +1,20 @@ |
||||
package com.daqing.financial.hrauth.dao; |
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
import com.daqing.framework.domain.hrms.PermissionEntity; |
||||
import com.daqing.framework.domain.hrms.RolePermissionEntity; |
||||
import org.apache.ibatis.annotations.Mapper; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 记录菜单权限 |
||||
* |
||||
* @author gongsj |
||||
* @email gongsj@gmail.com |
||||
* @date 2020-09-07 16:26:04 |
||||
*/ |
||||
@Mapper |
||||
public interface AuthPermissionDao extends BaseMapper<PermissionEntity> { |
||||
List<RolePermissionEntity> selectRolePermiByPermiId(Long permissionId); |
||||
} |
@ -0,0 +1,17 @@ |
||||
package com.daqing.financial.hrauth.dao; |
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
import com.daqing.framework.domain.hrms.RoleEntity; |
||||
import org.apache.ibatis.annotations.Mapper; |
||||
|
||||
/** |
||||
* 员工角色表 |
||||
* |
||||
* @author gongsj |
||||
* @email gongsj@gmail.com |
||||
* @date 2020-09-07 16:26:04 |
||||
*/ |
||||
@Mapper |
||||
public interface AuthRoleDao extends BaseMapper<RoleEntity> { |
||||
|
||||
} |
@ -0,0 +1,48 @@ |
||||
package com.daqing.financial.hrauth.enums; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* <p> 全局常用变量 </p> |
||||
* |
||||
* @description : |
||||
* @author : zhengqing |
||||
* @date : 2019/10/12 14:47 |
||||
*/ |
||||
public class Constants { |
||||
|
||||
/** |
||||
* 接口url |
||||
*/ |
||||
public static Map<String,String> URL_MAPPING_MAP = new HashMap<>(); |
||||
|
||||
/** |
||||
* 获取项目根目录 |
||||
*/ |
||||
public static String PROJECT_ROOT_DIRECTORY = System.getProperty("user.dir"); |
||||
|
||||
/** |
||||
* 密码加密相关 |
||||
*/ |
||||
public static String SALT = "zhengqing"; |
||||
public static final int HASH_ITERATIONS = 1; |
||||
|
||||
/** |
||||
* 请求头 - token |
||||
*/ |
||||
public static final String REQUEST_HEADER = "X-Token"; |
||||
|
||||
/** |
||||
* 请求头类型: |
||||
* application/x-www-form-urlencoded : form表单格式 |
||||
* application/json : json格式 |
||||
*/ |
||||
public static final String REQUEST_HEADERS_CONTENT_TYPE = "application/json"; |
||||
|
||||
/** |
||||
* 未登录者角色 |
||||
*/ |
||||
public static final String ROLE_LOGIN = "role_login"; |
||||
|
||||
} |
@ -0,0 +1,76 @@ |
||||
package com.daqing.financial.hrauth.filter; |
||||
|
||||
import com.alibaba.fastjson.JSONObject; |
||||
import com.daqing.financial.hrauth.enums.Constants; |
||||
import com.daqing.financial.hrauth.handle.AdminAuthenticationFailureHandler; |
||||
import com.daqing.financial.hrauth.handle.AdminAuthenticationSuccessHandler; |
||||
import com.daqing.financial.hrauth.handle.CusAuthenticationManager; |
||||
import com.daqing.financial.hrauth.handle.MyAuthenticationToken; |
||||
import com.daqing.financial.hrauth.util.MultiReadHttpServletRequest; |
||||
import com.daqing.framework.domain.hrms.request.LoginRequest; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.security.authentication.AuthenticationServiceException; |
||||
import org.springframework.security.core.Authentication; |
||||
import org.springframework.security.core.AuthenticationException; |
||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; |
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* <p> 自定义用户密码校验过滤器 </p> |
||||
* |
||||
* @author : zhengqing |
||||
* @description : |
||||
* @date : 2019/10/12 15:32 |
||||
*/ |
||||
@Slf4j |
||||
@Component |
||||
public class AdminAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter { |
||||
|
||||
/** |
||||
* @param authenticationManager: 认证管理器 |
||||
* @param adminAuthenticationSuccessHandler: 认证成功处理 |
||||
* @param adminAuthenticationFailureHandler: 认证失败处理 |
||||
*/ |
||||
public AdminAuthenticationProcessingFilter(CusAuthenticationManager authenticationManager, AdminAuthenticationSuccessHandler adminAuthenticationSuccessHandler, AdminAuthenticationFailureHandler adminAuthenticationFailureHandler) { |
||||
super(new AntPathRequestMatcher("/hrms/auth/userlogin/login", "POST")); |
||||
this.setAuthenticationManager(authenticationManager); |
||||
this.setAuthenticationSuccessHandler(adminAuthenticationSuccessHandler); |
||||
this.setAuthenticationFailureHandler(adminAuthenticationFailureHandler); |
||||
} |
||||
|
||||
@Override |
||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { |
||||
if (request.getContentType() == null || !request.getContentType().contains(Constants.REQUEST_HEADERS_CONTENT_TYPE)) { |
||||
throw new AuthenticationServiceException("请求头类型不支持: " + request.getContentType()); |
||||
} |
||||
|
||||
//UsernamePasswordAuthenticationToken authRequest;
|
||||
MyAuthenticationToken authRequest; |
||||
try { |
||||
MultiReadHttpServletRequest wrappedRequest = new MultiReadHttpServletRequest(request); |
||||
// 将前端传递的数据转换成jsonBean数据格式
|
||||
LoginRequest user = JSONObject.parseObject(wrappedRequest.getBodyJsonStrByJson(wrappedRequest), LoginRequest.class); |
||||
Integer tenDayEffective = user.getTenDayEffective(); |
||||
Integer type = user.getType(); |
||||
String userName = user.getPhone(); |
||||
Map<String,Object> map=new HashMap<>(); |
||||
map.put("tenDayEffective",tenDayEffective); |
||||
map.put("type",type); |
||||
map.put("userName",userName); |
||||
// 将前端传递的数据转换成jsonBean数据格式
|
||||
//UserEntity user = JSONObject.parseObject(wrappedRequest.getBodyJsonStrByJson(wrappedRequest), UserEntity.class);
|
||||
authRequest = new MyAuthenticationToken(userName, user.getPassword(),null, map); |
||||
authRequest.setDetails(authenticationDetailsSource.buildDetails(wrappedRequest)); |
||||
} catch (Exception e) { |
||||
throw new AuthenticationServiceException(e.getMessage()); |
||||
} |
||||
return this.getAuthenticationManager().authenticate(authRequest); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,124 @@ |
||||
package com.daqing.financial.hrauth.filter; |
||||
|
||||
import com.daqing.financial.hrauth.enums.Constants; |
||||
import com.daqing.financial.hrauth.handle.SecurityUser; |
||||
import com.daqing.financial.hrauth.service.impl.UserDetailsServiceImpl; |
||||
import com.daqing.financial.hrauth.util.MultiReadHttpServletRequest; |
||||
import com.daqing.financial.hrauth.util.MultiReadHttpServletResponse; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.apache.commons.lang3.StringUtils; |
||||
import org.springframework.security.access.AccessDeniedException; |
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
||||
import org.springframework.security.core.context.SecurityContextHolder; |
||||
import org.springframework.stereotype.Component; |
||||
import org.springframework.util.StopWatch; |
||||
import org.springframework.web.filter.OncePerRequestFilter; |
||||
|
||||
import javax.servlet.FilterChain; |
||||
import javax.servlet.ServletException; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.IOException; |
||||
import java.io.UnsupportedEncodingException; |
||||
|
||||
/** |
||||
* <p> 访问鉴权 - 每次访问接口都会经过此 </p> |
||||
* |
||||
* @description : |
||||
* @author : zhengqing |
||||
* @date : 2019/10/12 16:17 |
||||
*/ |
||||
@Slf4j |
||||
@Component |
||||
public class MyAuthenticationFilter extends OncePerRequestFilter { |
||||
|
||||
private final UserDetailsServiceImpl userDetailsService; |
||||
|
||||
protected MyAuthenticationFilter(UserDetailsServiceImpl userDetailsService) { |
||||
this.userDetailsService = userDetailsService; |
||||
} |
||||
|
||||
@Override |
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { |
||||
System.out.println("请求头类型: " + request.getContentType()); |
||||
String token = request.getHeader("token"); |
||||
if ((request.getContentType() == null && request.getContentLength() > 0) || (request.getContentType() != null && !request.getContentType().contains(Constants.REQUEST_HEADERS_CONTENT_TYPE))) { |
||||
filterChain.doFilter(request, response); |
||||
return; |
||||
} |
||||
|
||||
MultiReadHttpServletRequest wrappedRequest = new MultiReadHttpServletRequest(request); |
||||
MultiReadHttpServletResponse wrappedResponse = new MultiReadHttpServletResponse(response); |
||||
StopWatch stopWatch = new StopWatch(); |
||||
try { |
||||
stopWatch.start(); |
||||
// 记录请求的消息体
|
||||
logRequestBody(wrappedRequest); |
||||
|
||||
// SecurityContext context = SecurityContextHolder.getContext();
|
||||
// if (context.getAuthentication() != null && context.getAuthentication().isAuthenticated()) {
|
||||
// filterChain.doFilter(wrappedRequest, wrappedResponse);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// String token = "123";
|
||||
// 前后端分离情况下,前端登录后将token储存在cookie中,每次访问接口时通过token去拿用户权限
|
||||
//String token = wrappedRequest.getHeader(Constants.REQUEST_HEADER);
|
||||
log.debug("后台检查令牌:{}", token); |
||||
if (StringUtils.isNotBlank(token)) { |
||||
// 检查token
|
||||
SecurityUser securityUser = userDetailsService.getUserByToken(token); |
||||
if (securityUser == null || securityUser.getCurrentUserInfo() == null) { |
||||
throw new AccessDeniedException("TOKEN已过期,请重新登录!"); |
||||
} |
||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(securityUser, null, securityUser.getAuthorities()); |
||||
// 全局注入角色权限信息和登录用户基本信息
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication); |
||||
} |
||||
/* else { |
||||
throw new AccessDeniedException("TOKEN不存在,请重新登录!"); |
||||
}*/ |
||||
filterChain.doFilter(wrappedRequest, wrappedResponse); |
||||
} finally { |
||||
stopWatch.stop(); |
||||
long usedTimes = stopWatch.getTotalTimeMillis(); |
||||
// 记录响应的消息体
|
||||
logResponseBody(wrappedRequest, wrappedResponse, usedTimes); |
||||
} |
||||
|
||||
} |
||||
|
||||
private String logRequestBody(MultiReadHttpServletRequest request) { |
||||
MultiReadHttpServletRequest wrapper = request; |
||||
if (wrapper != null) { |
||||
try { |
||||
String bodyJson = wrapper.getBodyJsonStrByJson(request); |
||||
String url = wrapper.getRequestURI().replace("//", "/"); |
||||
System.out.println("-------------------------------- 请求url: " + url + " --------------------------------"); |
||||
Constants.URL_MAPPING_MAP.put(url, url); |
||||
log.info("`{}` 接收到的参数: {}",url , bodyJson); |
||||
return bodyJson; |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
private void logResponseBody(MultiReadHttpServletRequest request, MultiReadHttpServletResponse response, long useTime) { |
||||
MultiReadHttpServletResponse wrapper = response; |
||||
if (wrapper != null) { |
||||
byte[] buf = wrapper.getBody(); |
||||
if (buf.length > 0) { |
||||
String payload; |
||||
try { |
||||
payload = new String(buf, 0, buf.length, wrapper.getCharacterEncoding()); |
||||
} catch (UnsupportedEncodingException ex) { |
||||
payload = "[unknown]"; |
||||
} |
||||
log.info("`{}` 耗时:{}ms 返回的参数: {}", Constants.URL_MAPPING_MAP.get(request.getRequestURI()), useTime, payload); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,30 @@ |
||||
package com.daqing.financial.hrauth.handle; |
||||
|
||||
import com.daqing.financial.hrauth.model.ApiResult; |
||||
import com.daqing.financial.hrauth.util.ResponseUtils; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.security.core.AuthenticationException; |
||||
import org.springframework.security.web.AuthenticationEntryPoint; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
|
||||
/** |
||||
* <p> 认证权限入口 - 未登录的情况下访问所有接口都会拦截到此 </p> |
||||
* |
||||
* @description : 前后端分离情况下返回json格式数据 |
||||
* @author : zhengqing |
||||
* @date : 2019/10/11 17:32 |
||||
*/ |
||||
@Slf4j |
||||
@Component |
||||
public class AdminAuthenticationEntryPoint implements AuthenticationEntryPoint { |
||||
|
||||
@Override |
||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) { |
||||
log.error(e.getMessage()); |
||||
ResponseUtils.out(response, ApiResult.fail("请先登录哦~~")); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,48 @@ |
||||
package com.daqing.financial.hrauth.handle; |
||||
|
||||
import com.daqing.financial.hrauth.model.ApiResult; |
||||
import com.daqing.financial.hrauth.util.ResponseUtils; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.security.authentication.*; |
||||
import org.springframework.security.core.AuthenticationException; |
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException; |
||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import javax.servlet.ServletException; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.IOException; |
||||
|
||||
/** |
||||
* <p> 认证失败处理 - 前后端分离情况下返回json数据格式 </p> |
||||
* |
||||
* @description : |
||||
* @author : zhengqing |
||||
* @date : 2019/10/12 15:33 |
||||
*/ |
||||
@Slf4j |
||||
@Component |
||||
public class AdminAuthenticationFailureHandler implements AuthenticationFailureHandler { |
||||
|
||||
@Override |
||||
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException { |
||||
ApiResult result; |
||||
if (e instanceof UsernameNotFoundException || e instanceof BadCredentialsException) { |
||||
result = ApiResult.fail(e.getMessage()); |
||||
} else if (e instanceof LockedException) { |
||||
result = ApiResult.fail("账户被锁定,请联系管理员!"); |
||||
} else if (e instanceof CredentialsExpiredException) { |
||||
result = ApiResult.fail("证书过期,请联系管理员!"); |
||||
} else if (e instanceof AccountExpiredException) { |
||||
result = ApiResult.fail("账户过期,请联系管理员!"); |
||||
} else if (e instanceof DisabledException) { |
||||
result = ApiResult.fail("账户被禁用,请联系管理员!"); |
||||
} else { |
||||
log.error("登录失败:", e); |
||||
result = ApiResult.fail("登录失败!"); |
||||
} |
||||
ResponseUtils.out(response, result); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,80 @@ |
||||
package com.daqing.financial.hrauth.handle; |
||||
|
||||
import com.daqing.financial.hrauth.dao.UserLoginDao; |
||||
import com.daqing.financial.hrauth.service.UserLoginService; |
||||
import com.daqing.financial.hrauth.service.impl.UserDetailsServiceImpl; |
||||
import com.daqing.framework.domain.hrms.request.LoginRequest; |
||||
import com.daqing.framework.domain.hrms.response.LoginResponse; |
||||
import com.daqing.framework.model.response.ResponseResult; |
||||
import lombok.SneakyThrows; |
||||
import org.apache.commons.collections4.MapUtils; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.security.authentication.AuthenticationProvider; |
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
||||
import org.springframework.security.core.Authentication; |
||||
import org.springframework.security.core.AuthenticationException; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import javax.annotation.Resource; |
||||
|
||||
/** |
||||
* <p> 自定义认证处理 </p> |
||||
* |
||||
* @description : |
||||
* @author : zhengqing |
||||
* @date : 2019/10/12 14:49 |
||||
*/ |
||||
@Component |
||||
public class AdminAuthenticationProvider implements AuthenticationProvider { |
||||
|
||||
@Autowired |
||||
UserDetailsServiceImpl userDetailsService; |
||||
@Resource |
||||
private UserLoginDao userMapper; |
||||
@Autowired |
||||
UserLoginService userLoginService; |
||||
|
||||
@SneakyThrows |
||||
@Override |
||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException { |
||||
MyAuthenticationToken authRequest=(MyAuthenticationToken)authentication; |
||||
String tenDayEffective= MapUtils.getString(authRequest.getParam(),"tenDayEffective","1"); |
||||
String type= MapUtils.getString(authRequest.getParam(),"type","1"); |
||||
String userName = MapUtils.getString(authRequest.getParam(),"userName",null); |
||||
// 获取前端表单中输入后返回的用户名、密码
|
||||
//String userName = (String) authentication.getPrincipal();
|
||||
String password = (String) authentication.getCredentials(); |
||||
|
||||
LoginRequest loginRequest = new LoginRequest(); |
||||
loginRequest.setPhone(userName); |
||||
loginRequest.setPassword(password); |
||||
loginRequest.setTenDayEffective(Integer.parseInt(tenDayEffective)); |
||||
loginRequest.setType(Integer.parseInt(type)); |
||||
ResponseResult login = userLoginService.login(loginRequest); |
||||
LoginResponse data = (LoginResponse) login.getData(); |
||||
|
||||
SecurityUser userInfo = (SecurityUser) userDetailsService.loadUserByUsername(userName); |
||||
|
||||
/* boolean isValid = PasswordUtils.isValidPassword(password, userInfo.getPassword(), userInfo.getCurrentUserInfo().getSalt()); |
||||
// 验证密码
|
||||
if (!isValid) { |
||||
throw new BadCredentialsException("密码错误!"); |
||||
} |
||||
|
||||
// 前后端分离情况下 处理逻辑...
|
||||
// 更新登录令牌 - 之后访问系统其它接口直接通过token认证用户权限...
|
||||
String token = PasswordUtils.encodePassword(System.currentTimeMillis() + userInfo.getCurrentUserInfo().getSalt(), userInfo.getCurrentUserInfo().getSalt()); |
||||
UserEntity user = userMapper.selectById(userInfo.getCurrentUserInfo().getId()); |
||||
user.setToken(token); |
||||
userMapper.updateById(user); |
||||
userInfo.getCurrentUserInfo().setToken(token);*/ |
||||
|
||||
userInfo.getCurrentUserInfo().setToken(data.getToken()); |
||||
return new UsernamePasswordAuthenticationToken(userInfo, password, userInfo.getAuthorities()); |
||||
} |
||||
|
||||
@Override |
||||
public boolean supports(Class<?> aClass) { |
||||
return true; |
||||
} |
||||
} |
@ -0,0 +1,34 @@ |
||||
package com.daqing.financial.hrauth.handle; |
||||
|
||||
import com.daqing.financial.hrauth.model.ApiResult; |
||||
import com.daqing.financial.hrauth.util.ResponseUtils; |
||||
import com.daqing.framework.domain.hrms.UserEntity; |
||||
import org.springframework.security.core.Authentication; |
||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import javax.servlet.ServletException; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.IOException; |
||||
|
||||
/** |
||||
* <p> 认证成功处理 </p> |
||||
* |
||||
* @description : |
||||
* @author : zhengqing |
||||
* @date : 2019/10/12 15:31 |
||||
*/ |
||||
@Component |
||||
public class AdminAuthenticationSuccessHandler implements AuthenticationSuccessHandler { |
||||
|
||||
@Override |
||||
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse response, Authentication auth) throws IOException, ServletException { |
||||
UserEntity user = new UserEntity(); |
||||
SecurityUser securityUser = ((SecurityUser) auth.getPrincipal()); |
||||
user.setAccount(securityUser.getCurrentUserInfo().getAccount()); |
||||
user.setToken(securityUser.getCurrentUserInfo().getToken()); |
||||
ResponseUtils.out(response, ApiResult.ok("登录成功!", user)); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,36 @@ |
||||
package com.daqing.financial.hrauth.handle; |
||||
|
||||
import org.springframework.security.authentication.AuthenticationManager; |
||||
import org.springframework.security.authentication.ProviderNotFoundException; |
||||
import org.springframework.security.core.Authentication; |
||||
import org.springframework.security.core.AuthenticationException; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import java.util.Objects; |
||||
|
||||
/** |
||||
* <p> 自定义认证管理器 </p> |
||||
* |
||||
* @author : zhengqing |
||||
* @description : |
||||
* @date : 2019/10/12 14:49 |
||||
*/ |
||||
@Component |
||||
public class CusAuthenticationManager implements AuthenticationManager { |
||||
|
||||
private final AdminAuthenticationProvider adminAuthenticationProvider; |
||||
|
||||
public CusAuthenticationManager(AdminAuthenticationProvider adminAuthenticationProvider) { |
||||
this.adminAuthenticationProvider = adminAuthenticationProvider; |
||||
} |
||||
|
||||
@Override |
||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException { |
||||
Authentication result = adminAuthenticationProvider.authenticate(authentication); |
||||
if (Objects.nonNull(result)) { |
||||
return result; |
||||
} |
||||
throw new ProviderNotFoundException("Authentication failed!"); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,58 @@ |
||||
package com.daqing.financial.hrauth.handle; |
||||
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken; |
||||
import org.springframework.security.core.GrantedAuthority; |
||||
|
||||
import java.util.Collection; |
||||
import java.util.Map; |
||||
|
||||
public class MyAuthenticationToken extends AbstractAuthenticationToken { |
||||
private static final long serialVersionUID = 420L; |
||||
private final Object principal; |
||||
private Object credentials; |
||||
|
||||
/** |
||||
* 参数map |
||||
*/ |
||||
private Map<String,Object> map; |
||||
|
||||
public MyAuthenticationToken(Object principal, Object credentials) { |
||||
super((Collection)null); |
||||
this.principal = principal; |
||||
this.credentials = credentials; |
||||
this.setAuthenticated(false); |
||||
} |
||||
|
||||
public MyAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities, Map<String,Object> map){ |
||||
super(authorities); |
||||
this.principal = principal; |
||||
this.credentials = credentials; |
||||
super.setAuthenticated(true); |
||||
this.map=map; |
||||
} |
||||
|
||||
public Object getCredentials() { |
||||
return this.credentials; |
||||
} |
||||
|
||||
public Object getPrincipal() { |
||||
return this.principal; |
||||
} |
||||
|
||||
public Map<String,Object> getParam(){ |
||||
return map; |
||||
} |
||||
|
||||
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { |
||||
if (isAuthenticated) { |
||||
throw new IllegalArgumentException("Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead"); |
||||
} else { |
||||
super.setAuthenticated(false); |
||||
} |
||||
} |
||||
|
||||
public void eraseCredentials() { |
||||
super.eraseCredentials(); |
||||
this.credentials = null; |
||||
} |
||||
} |
@ -0,0 +1,98 @@ |
||||
package com.daqing.financial.hrauth.handle; |
||||
|
||||
import com.daqing.framework.domain.hrms.RoleEntity; |
||||
import com.daqing.framework.domain.hrms.UserEntity; |
||||
import lombok.Data; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.security.core.GrantedAuthority; |
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority; |
||||
import org.springframework.security.core.userdetails.UserDetails; |
||||
import org.springframework.util.CollectionUtils; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collection; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* <p> 安全认证用户详情 </p> |
||||
* |
||||
* @author : zhengqing |
||||
* @description : |
||||
* @date : 2019/10/14 17:46 |
||||
*/ |
||||
@Data |
||||
@Slf4j |
||||
public class SecurityUser implements UserDetails { |
||||
/** |
||||
* 当前登录用户 |
||||
*/ |
||||
private transient UserEntity currentUserInfo; |
||||
/** |
||||
* 角色 |
||||
*/ |
||||
private transient List<RoleEntity> roleList; |
||||
|
||||
public SecurityUser() { } |
||||
|
||||
public SecurityUser(UserEntity user) { |
||||
if (user != null) { |
||||
this.currentUserInfo = user; |
||||
} |
||||
} |
||||
|
||||
public SecurityUser(UserEntity user, List<RoleEntity> roleList) { |
||||
if (user != null) { |
||||
this.currentUserInfo = user; |
||||
this.roleList = roleList; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 获取当前用户所具有的角色 |
||||
* |
||||
* @return |
||||
*/ |
||||
@Override |
||||
public Collection<? extends GrantedAuthority> getAuthorities() { |
||||
Collection<GrantedAuthority> authorities = new ArrayList<>(); |
||||
if (!CollectionUtils.isEmpty(this.roleList)) { |
||||
for (RoleEntity role : this.roleList) { |
||||
SimpleGrantedAuthority authority = new SimpleGrantedAuthority("user_role"); |
||||
authorities.add(authority); |
||||
} |
||||
} |
||||
// SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ADMIN");
|
||||
// authorities.add(authority);
|
||||
return authorities; |
||||
} |
||||
|
||||
@Override |
||||
public String getPassword() { |
||||
return currentUserInfo.getPassword(); |
||||
} |
||||
|
||||
@Override |
||||
public String getUsername() { |
||||
return currentUserInfo.getAccount(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isAccountNonExpired() { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isAccountNonLocked() { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isCredentialsNonExpired() { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isEnabled() { |
||||
return true; |
||||
} |
||||
} |
@ -0,0 +1,67 @@ |
||||
package com.daqing.financial.hrauth.handle; |
||||
|
||||
import com.daqing.financial.hrauth.enums.Constants; |
||||
import org.springframework.security.access.AccessDecisionManager; |
||||
import org.springframework.security.access.AccessDeniedException; |
||||
import org.springframework.security.access.ConfigAttribute; |
||||
import org.springframework.security.authentication.AnonymousAuthenticationToken; |
||||
import org.springframework.security.authentication.BadCredentialsException; |
||||
import org.springframework.security.core.Authentication; |
||||
import org.springframework.security.core.AuthenticationException; |
||||
import org.springframework.security.core.GrantedAuthority; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import java.util.Collection; |
||||
|
||||
/** |
||||
* <p> 对访问url进行权限认证处理 </p> |
||||
* |
||||
* @author : zhengqing |
||||
* @description : |
||||
* @date : 2019/10/15 14:21 |
||||
*/ |
||||
@Component |
||||
public class UrlAccessDecisionManager implements AccessDecisionManager { |
||||
|
||||
/** |
||||
* @param authentication: 当前登录用户的角色信息 |
||||
* @param object: 请求url信息 |
||||
* @param collection: `UrlFilterInvocationSecurityMetadataSource`中的getAttributes方法传来的,表示当前请求需要的角色(可能有多个) |
||||
* @return: void |
||||
*/ |
||||
@Override |
||||
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> collection) throws AccessDeniedException, AuthenticationException { |
||||
// 遍历角色
|
||||
for (ConfigAttribute ca : collection) { |
||||
// ① 当前url请求需要的权限
|
||||
String needRole = ca.getAttribute(); |
||||
if (Constants.ROLE_LOGIN.equals(needRole)) { |
||||
if (authentication instanceof AnonymousAuthenticationToken) { |
||||
throw new BadCredentialsException("未登录!"); |
||||
} else { |
||||
throw new AccessDeniedException("未授权该url!"); |
||||
} |
||||
} |
||||
|
||||
// ② 当前用户所具有的角色
|
||||
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities(); |
||||
for (GrantedAuthority authority : authorities) { |
||||
// 只要包含其中一个角色即可访问
|
||||
if (authority.getAuthority().equals(needRole)) { |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
throw new AccessDeniedException("请联系管理员分配权限!"); |
||||
} |
||||
|
||||
@Override |
||||
public boolean supports(ConfigAttribute configAttribute) { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public boolean supports(Class<?> aClass) { |
||||
return true; |
||||
} |
||||
} |
@ -0,0 +1,28 @@ |
||||
package com.daqing.financial.hrauth.handle; |
||||
|
||||
import com.daqing.financial.hrauth.model.ApiResult; |
||||
import com.daqing.financial.hrauth.util.ResponseUtils; |
||||
import org.springframework.security.access.AccessDeniedException; |
||||
import org.springframework.security.web.access.AccessDeniedHandler; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import javax.servlet.ServletException; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.IOException; |
||||
|
||||
|
||||
/** |
||||
* <p> 认证url权限 - 登录后访问接口无权限 - 自定义403无权限响应内容 </p> |
||||
* |
||||
* @description : 登录过后的权限处理 【注:要和未登录时的权限处理区分开哦~】 |
||||
* @author : zhengqing |
||||
* @date : 2019/10/14 18:52 |
||||
*/ |
||||
@Component |
||||
public class UrlAccessDeniedHandler implements AccessDeniedHandler { |
||||
@Override |
||||
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException { |
||||
ResponseUtils.out(response, ApiResult.fail(403, e.getMessage())); |
||||
} |
||||
} |
@ -0,0 +1,116 @@ |
||||
package com.daqing.financial.hrauth.handle; |
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
||||
import com.daqing.financial.hrauth.dao.AuthPermissionDao; |
||||
import com.daqing.financial.hrauth.dao.AuthRoleDao; |
||||
import com.daqing.financial.hrauth.dao.RolePermissionMapper; |
||||
import com.daqing.financial.hrauth.enums.Constants; |
||||
import com.daqing.framework.domain.hrms.PermissionEntity; |
||||
import com.daqing.framework.domain.hrms.RoleEntity; |
||||
import com.daqing.framework.domain.hrms.RolePermissionEntity; |
||||
import org.springframework.security.access.ConfigAttribute; |
||||
import org.springframework.security.access.SecurityConfig; |
||||
import org.springframework.security.core.context.SecurityContextHolder; |
||||
import org.springframework.security.web.FilterInvocation; |
||||
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import javax.annotation.Resource; |
||||
import java.util.Collection; |
||||
import java.util.LinkedList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* <p> 获取访问该url所需要的用户角色权限信息 </p> |
||||
* |
||||
* @author : zhengqing |
||||
* @description : 执行完之后到 `UrlAccessDecisionManager` 中认证权限 |
||||
* @date : 2019/10/15 14:36 |
||||
*/ |
||||
@Component |
||||
public class UrlFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource { |
||||
|
||||
@Resource |
||||
AuthPermissionDao permissionMapper; |
||||
@Resource |
||||
RolePermissionMapper rolePermissionMapper; |
||||
@Resource |
||||
AuthRoleDao roleMapper; |
||||
|
||||
|
||||
/*** |
||||
* 返回该url所需要的用户权限信息 |
||||
* |
||||
* @param object: 储存请求url信息 |
||||
* @return: null:标识不需要任何权限都可以访问 |
||||
*/ |
||||
@Override |
||||
public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { |
||||
// 获取当前请求url
|
||||
String beforeRequestUrl = ((FilterInvocation) object).getRequestUrl(); |
||||
String requestUrl = null; |
||||
boolean status = beforeRequestUrl.contains("?"); |
||||
if(status){ |
||||
requestUrl = beforeRequestUrl.substring(0, beforeRequestUrl.indexOf("?")); |
||||
}else{ |
||||
requestUrl = beforeRequestUrl; |
||||
} |
||||
|
||||
// TODO 忽略url请放在此处进行过滤放行
|
||||
if ("/login".equals(requestUrl) || requestUrl.contains("logout") || "/error".equals(requestUrl)) { |
||||
return null; |
||||
} |
||||
|
||||
// 数据库中所有url
|
||||
List<PermissionEntity> permissionList = permissionMapper.selectList(null); |
||||
for (PermissionEntity permission : permissionList) { |
||||
// 获取该url所对应的权限
|
||||
if (requestUrl.equals(permission.getUrl())) { |
||||
List<RolePermissionEntity> permissionEntityList = rolePermissionMapper.selectList(new QueryWrapper<RolePermissionEntity>().eq("permission_id",permission.getId())); |
||||
|
||||
SecurityUser userRole = (SecurityUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();//获取spring security封装的当前用户信息对象
|
||||
List<RoleEntity> list = userRole.getRoleList(); |
||||
|
||||
List<String> roles = new LinkedList<>(); |
||||
int isPermission = 0;//标识是否有权限,有的话跳出循环
|
||||
for(int i = 0; i < permissionEntityList.size(); i ++){ |
||||
if(isPermission > 0){ |
||||
break; |
||||
} |
||||
for(int j = 0; j < list.size(); j ++){ |
||||
if(permissionEntityList.get(i).getRoleId() == list.get(j).getId()){ |
||||
isPermission ++; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
if(isPermission > 0){ |
||||
return SecurityConfig.createList(roles.toArray(new String[roles.size()])); |
||||
}else { |
||||
return SecurityConfig.createList(Constants.ROLE_LOGIN); |
||||
} |
||||
|
||||
/* List<String> roles = new LinkedList<>(); |
||||
if (!CollectionUtils.isEmpty(permissionEntityList)){ |
||||
Integer roleId = permissionEntityList.get(0).getRoleId().intValue(); |
||||
RoleEntity role = roleMapper.selectById(roleId); |
||||
roles.add(role.getCode()); |
||||
} |
||||
// 保存该url对应角色权限信息
|
||||
return SecurityConfig.createList(roles.toArray(new String[roles.size()]));*/ |
||||
} |
||||
} |
||||
// 如果数据中没有找到相应url资源则为非法访问,要求用户登录再进行操作
|
||||
return SecurityConfig.createList(Constants.ROLE_LOGIN); |
||||
} |
||||
|
||||
@Override |
||||
public Collection<ConfigAttribute> getAllConfigAttributes() { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public boolean supports(Class<?> aClass) { |
||||
return FilterInvocation.class.isAssignableFrom(aClass); |
||||
} |
||||
} |
@ -0,0 +1,142 @@ |
||||
package com.daqing.financial.hrauth.model; |
||||
|
||||
import io.swagger.annotations.ApiModel; |
||||
import io.swagger.annotations.ApiModelProperty; |
||||
|
||||
/** |
||||
* <p> API返回参数 </p> |
||||
* |
||||
* @description : |
||||
* @author : zhengqing |
||||
* @date : 2019/7/20 11:09 |
||||
*/ |
||||
@ApiModel(value = "API返回参数") |
||||
public class ApiResult { |
||||
/** |
||||
* 消息内容 |
||||
*/ |
||||
@ApiModelProperty(value = "响应消息", required = false) |
||||
private String message; |
||||
|
||||
/** |
||||
* 成功或有效为1,失败或无效为0,token过期 |
||||
*/ |
||||
@ApiModelProperty(value = "响应码", required = true) |
||||
private Integer code; |
||||
|
||||
/** |
||||
* 响应中的数据 |
||||
*/ |
||||
@ApiModelProperty(value = "响应数据", required = false) |
||||
private Object data; |
||||
|
||||
public static ApiResult expired(String message) { |
||||
return new ApiResult(-1, message, null); |
||||
} |
||||
|
||||
public static ApiResult fail(String message) { |
||||
return new ApiResult(ResultCode.FAILURE.getCode(), message, null); |
||||
} |
||||
|
||||
/*** |
||||
* 自定义错误返回码 |
||||
* |
||||
* @param code |
||||
* @param message: |
||||
* @return: com.zhengqing.modules.common.dto.output.ApiResult |
||||
*/ |
||||
public static ApiResult fail(Integer code, String message) { |
||||
return new ApiResult(code, message, null); |
||||
} |
||||
|
||||
public static ApiResult ok(String message) { |
||||
return new ApiResult(ResultCode.SUCCESS.getCode(), message, null); |
||||
} |
||||
|
||||
public static ApiResult ok() { |
||||
return new ApiResult(ResultCode.SUCCESS.getCode(), "OK", null); |
||||
} |
||||
|
||||
public static ApiResult build(Integer code, String msg, Object data) { |
||||
return new ApiResult(ResultCode.SUCCESS.getCode(), msg, data); |
||||
} |
||||
|
||||
public static ApiResult ok(String message, Object data) { |
||||
return new ApiResult(ResultCode.SUCCESS.getCode(), message, data); |
||||
} |
||||
|
||||
/** |
||||
* 自定义返回码 |
||||
*/ |
||||
public static ApiResult ok(Integer code, String message) { |
||||
return new ApiResult(code, message); |
||||
} |
||||
|
||||
/** |
||||
* 自定义 |
||||
* |
||||
* @param code:验证码 |
||||
* @param message:返回消息内容 |
||||
* @param data:返回数据 |
||||
* @return: com.zhengqing.modules.common.dto.output.ApiResult |
||||
*/ |
||||
public static ApiResult ok(Integer code, String message, Object data) { |
||||
return new ApiResult(code, message, data); |
||||
} |
||||
|
||||
public ApiResult() { } |
||||
|
||||
public static ApiResult build(Integer code, String msg) { |
||||
return new ApiResult(code, msg, null); |
||||
} |
||||
|
||||
public ApiResult(Integer code, String msg, Object data) { |
||||
this.code = code; |
||||
this.message = msg; |
||||
this.data = data; |
||||
} |
||||
|
||||
public ApiResult(Object data) { |
||||
this.code = ResultCode.SUCCESS.getCode(); |
||||
this.message = "OK"; |
||||
this.data = data; |
||||
} |
||||
|
||||
public ApiResult(String message) { |
||||
this(ResultCode.SUCCESS.getCode(), message, null); |
||||
} |
||||
|
||||
public ApiResult(String message, Integer code) { |
||||
this.message = message; |
||||
this.code = code; |
||||
} |
||||
|
||||
public ApiResult(Integer code, String message) { |
||||
this.code = code; |
||||
this.message = message; |
||||
} |
||||
|
||||
public String getMessage() { |
||||
return message; |
||||
} |
||||
|
||||
public void setMessage(String message) { |
||||
this.message = message; |
||||
} |
||||
|
||||
public Integer getCode() { |
||||
return code; |
||||
} |
||||
|
||||
public void setCode(Integer code) { |
||||
this.code = code; |
||||
} |
||||
|
||||
public Object getData() { |
||||
return data; |
||||
} |
||||
|
||||
public void setData(Object data) { |
||||
this.data = data; |
||||
} |
||||
} |
@ -0,0 +1,42 @@ |
||||
package com.daqing.financial.hrauth.model; |
||||
|
||||
|
||||
/** |
||||
* <p> 响应码枚举 - 可参考HTTP状态码的语义 </p> |
||||
* |
||||
* @description : |
||||
* @author : zhengqing |
||||
* @date : 2019/8/22 11:09 |
||||
*/ |
||||
public enum ResultCode { |
||||
SUCCESS( 10000, "SUCCESS" ),//成功
|
||||
FAILURE( 400, "FAILURE" ),//失败
|
||||
UNAUTHORIZED( 401, "未认证或Token失效" ),//未认证(签名错误、token错误)
|
||||
USER_UNAUTHORIZED( 402, "用户名或密码不正确" ),//未通过认证
|
||||
NOT_FOUND( 404, "接口不存在" ),//接口不存在
|
||||
INTERNAL_SERVER_ERROR( 500, "服务器内部错误" );//服务器内部错误
|
||||
|
||||
private int code; |
||||
private String desc; |
||||
|
||||
ResultCode(int code, String desc) { |
||||
this.code = code; |
||||
this.desc = desc; |
||||
} |
||||
|
||||
public int getCode() { |
||||
return code; |
||||
} |
||||
|
||||
public void setCode(int code) { |
||||
this.code = code; |
||||
} |
||||
|
||||
public String getDesc() { |
||||
return desc; |
||||
} |
||||
|
||||
public void setDesc(String desc) { |
||||
this.desc = desc; |
||||
} |
||||
} |
@ -0,0 +1,103 @@ |
||||
package com.daqing.financial.hrauth.service.impl; |
||||
|
||||
import com.alibaba.fastjson.JSON; |
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
||||
import com.daqing.financial.hrauth.dao.AuthEmployeeRoleDao; |
||||
import com.daqing.financial.hrauth.dao.AuthRoleDao; |
||||
import com.daqing.financial.hrauth.dao.UserLoginDao; |
||||
import com.daqing.financial.hrauth.handle.SecurityUser; |
||||
import com.daqing.framework.domain.hrms.EmployeeRoleEntity; |
||||
import com.daqing.framework.domain.hrms.RoleEntity; |
||||
import com.daqing.framework.domain.hrms.UserEntity; |
||||
import com.daqing.framework.util.RedisUtil; |
||||
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; |
||||
import org.springframework.util.CollectionUtils; |
||||
import org.springframework.web.context.request.RequestContextHolder; |
||||
import org.springframework.web.context.request.ServletRequestAttributes; |
||||
|
||||
import javax.annotation.Resource; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import java.util.LinkedList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* <p> 自定义userDetailsService - 认证用户详情 </p> |
||||
* |
||||
* @author : zhengqing |
||||
* @description : |
||||
* @date : 2019/10/14 17:46 |
||||
*/ |
||||
@Service("userDetailsService") |
||||
public class UserDetailsServiceImpl implements UserDetailsService { |
||||
|
||||
@Resource |
||||
private UserLoginDao userMapper; |
||||
@Resource |
||||
private AuthRoleDao roleMapper; |
||||
@Resource |
||||
private AuthEmployeeRoleDao userRoleMapper; |
||||
|
||||
/*** |
||||
* 根据账号获取用户信息 |
||||
* @param username: |
||||
* @return: org.springframework.security.core.userdetails.UserDetails |
||||
*/ |
||||
@Override |
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { |
||||
// 从数据库中取出用户信息
|
||||
List<UserEntity> userList = userMapper.selectList(new QueryWrapper<UserEntity>().eq("phone_account", username)); |
||||
UserEntity user; |
||||
// 判断用户是否存在
|
||||
if (!CollectionUtils.isEmpty(userList)) { |
||||
user = userList.get(0); |
||||
} else { |
||||
throw new UsernameNotFoundException("用户名不存在或已禁用!"); |
||||
} |
||||
// 返回UserDetails实现类
|
||||
return new SecurityUser(user, getUserRoles(user.getId().intValue())); |
||||
} |
||||
|
||||
/*** |
||||
* 根据token获取用户权限与基本信息 |
||||
* |
||||
* @param token: |
||||
* @return: com.zhengqing.config.security.dto.SecurityUser |
||||
*/ |
||||
public SecurityUser getUserByToken(String token) { |
||||
UserEntity user = null; |
||||
|
||||
String userId = RedisUtil.get("dq:token:"+token); |
||||
String userEntityStr = RedisUtil.get("dq:userId:"+userId); |
||||
UserEntity systemUser = JSON.parseObject(userEntityStr,UserEntity.class); |
||||
if(systemUser != null){ |
||||
user = systemUser; |
||||
} |
||||
|
||||
/* List<UserEntity> loginList = userMapper.selectList(new QueryWrapper<UserEntity>().eq("token", token)); |
||||
if (!CollectionUtils.isEmpty(loginList)) { |
||||
user = loginList.get(0); |
||||
}*/ |
||||
return user != null ? new SecurityUser(user, getUserRoles(user.getId().intValue())) : null; |
||||
} |
||||
|
||||
/** |
||||
* 根据用户id获取角色权限信息 |
||||
* |
||||
* @param userId |
||||
* @return |
||||
*/ |
||||
private List<RoleEntity> getUserRoles(Integer userId) { |
||||
List<EmployeeRoleEntity> userRoles = userRoleMapper.selectList(new QueryWrapper<EmployeeRoleEntity>().eq("user_id", userId)); |
||||
List<RoleEntity> roleList = new LinkedList<>(); |
||||
for (EmployeeRoleEntity userRole : userRoles) { |
||||
RoleEntity role = roleMapper.selectById(userRole.getRoleId()); |
||||
roleList.add(role); |
||||
} |
||||
return roleList; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,164 @@ |
||||
package com.daqing.financial.hrauth.util; |
||||
|
||||
import com.alibaba.fastjson.JSONObject; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
|
||||
import javax.servlet.ReadListener; |
||||
import javax.servlet.ServletInputStream; |
||||
import javax.servlet.ServletRequest; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletRequestWrapper; |
||||
import java.io.*; |
||||
import java.nio.charset.Charset; |
||||
import java.util.Enumeration; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* <p> 多次读写BODY用HTTP REQUEST - 解决流只能读一次问题 </p> |
||||
* |
||||
* @author : zhengqing |
||||
* @description : |
||||
* @date : 2019/10/12 15:42 |
||||
*/ |
||||
@Slf4j |
||||
public class MultiReadHttpServletRequest extends HttpServletRequestWrapper { |
||||
|
||||
private final byte[] body; |
||||
|
||||
public MultiReadHttpServletRequest(HttpServletRequest request) throws IOException { |
||||
super(request); |
||||
body = getBodyString(request).getBytes(Charset.forName("UTF-8")); |
||||
} |
||||
|
||||
@Override |
||||
public BufferedReader getReader() throws IOException { |
||||
return new BufferedReader(new InputStreamReader(getInputStream())); |
||||
} |
||||
|
||||
@Override |
||||
public ServletInputStream getInputStream() throws IOException { |
||||
|
||||
final ByteArrayInputStream bais = new ByteArrayInputStream(body); |
||||
|
||||
return new ServletInputStream() { |
||||
|
||||
@Override |
||||
public int read() throws IOException { |
||||
return bais.read(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isFinished() { |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isReady() { |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public void setReadListener(ReadListener readListener) { |
||||
|
||||
} |
||||
}; |
||||
} |
||||
|
||||
/** |
||||
* 获取请求Body |
||||
* |
||||
* @param request |
||||
* @return |
||||
*/ |
||||
private String getBodyString(ServletRequest request) { |
||||
StringBuilder sb = new StringBuilder(); |
||||
InputStream inputStream = null; |
||||
BufferedReader reader = null; |
||||
try { |
||||
inputStream = request.getInputStream(); |
||||
reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8"))); |
||||
String line = ""; |
||||
while ((line = reader.readLine()) != null) { |
||||
sb.append(line); |
||||
} |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} finally { |
||||
if (inputStream != null) { |
||||
try { |
||||
inputStream.close(); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
if (reader != null) { |
||||
try { |
||||
reader.close(); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
} |
||||
return sb.toString(); |
||||
} |
||||
|
||||
/** |
||||
* 将前端请求的表单数据转换成json字符串 - 前后端一体的情况下使用 |
||||
* @param request: |
||||
* @return: java.lang.String |
||||
*/ |
||||
public String getBodyJsonStrByForm(ServletRequest request){ |
||||
Map<String, Object> bodyMap = new HashMap<>(16); |
||||
try { |
||||
// 参数定义
|
||||
String paraName = null; |
||||
// 获取请求参数并转换
|
||||
Enumeration<String> e = request.getParameterNames(); |
||||
while (e.hasMoreElements()) { |
||||
paraName = e.nextElement(); |
||||
bodyMap.put(paraName, request.getParameter(paraName)); |
||||
} |
||||
} catch(Exception e) { |
||||
log.error("请求参数转换错误!",e); |
||||
} |
||||
// json对象转json字符串 转javabean
|
||||
// SecurityUser user = JSONObject.parseObject(JSONObject.toJSONString(bodyMap), SecurityUser.class);
|
||||
// json对象转json字符串
|
||||
return JSONObject.toJSONString(bodyMap); |
||||
} |
||||
|
||||
/** |
||||
* 将前端传递的json数据转换成json字符串 - 前后端分离的情况下使用 |
||||
* @param request: |
||||
* @return: java.lang.String |
||||
*/ |
||||
public String getBodyJsonStrByJson(ServletRequest request){ |
||||
// StringBuilder requestStrBuilder = new StringBuilder();
|
||||
// try {
|
||||
// BufferedReader streamReader = new MultiReadHttpServletRequest(request).getReader();
|
||||
// String inputStr;
|
||||
// while ((inputStr = streamReader.readLine()) != null) {
|
||||
// requestStrBuilder.append(inputStr);
|
||||
// }
|
||||
// // 将json字符串转化为jsonbean对象
|
||||
//// User user = JSON.parseObject(requestStrBuilder.toString(), User.class);
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return requestStrBuilder.toString();
|
||||
StringBuffer json = new StringBuffer(); |
||||
String line = null; |
||||
try { |
||||
BufferedReader reader = request.getReader(); |
||||
while((line = reader.readLine()) != null) { |
||||
json.append(line); |
||||
} |
||||
} |
||||
catch(Exception e) { |
||||
log.error("请求参数转换错误!",e); |
||||
} |
||||
return json.toString(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,81 @@ |
||||
package com.daqing.financial.hrauth.util; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
|
||||
import javax.servlet.ServletOutputStream; |
||||
import javax.servlet.WriteListener; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import javax.servlet.http.HttpServletResponseWrapper; |
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.IOException; |
||||
import java.io.OutputStreamWriter; |
||||
import java.io.PrintWriter; |
||||
|
||||
/** |
||||
* <p> 多次读写BODY用HTTP RESPONSE - 解决流只能读一次问题 </p> |
||||
* |
||||
* @author : zhengqing |
||||
* @description : |
||||
* @date : 2019/10/12 15:42 |
||||
*/ |
||||
public class MultiReadHttpServletResponse extends HttpServletResponseWrapper { |
||||
|
||||
private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); |
||||
private HttpServletResponse response; |
||||
|
||||
public MultiReadHttpServletResponse(HttpServletResponse response) { |
||||
super(response); |
||||
response.setCharacterEncoding("UTF-8"); |
||||
response.setContentType("application/json"); |
||||
this.response = response; |
||||
} |
||||
|
||||
public byte[] getBody() { |
||||
return byteArrayOutputStream.toByteArray(); |
||||
} |
||||
|
||||
@Override |
||||
public ServletOutputStream getOutputStream() { |
||||
return new ServletOutputStreamWrapper(this.byteArrayOutputStream, this.response); |
||||
} |
||||
|
||||
@Override |
||||
public PrintWriter getWriter() throws IOException { |
||||
return new PrintWriter(new OutputStreamWriter(getOutputStream(), this.response.getCharacterEncoding())); |
||||
} |
||||
|
||||
|
||||
@Data |
||||
@AllArgsConstructor |
||||
private static class ServletOutputStreamWrapper extends ServletOutputStream { |
||||
|
||||
private ByteArrayOutputStream outputStream; |
||||
private HttpServletResponse response; |
||||
|
||||
@Override |
||||
public boolean isReady() { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public void setWriteListener(WriteListener listener) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void write(int b) throws IOException { |
||||
this.outputStream.write(b); |
||||
} |
||||
|
||||
@Override |
||||
public void flush() throws IOException { |
||||
if (!this.response.isCommitted()) { |
||||
byte[] body = this.outputStream.toByteArray(); |
||||
ServletOutputStream outputStream = this.response.getOutputStream(); |
||||
outputStream.write(body); |
||||
outputStream.flush(); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,64 @@ |
||||
package com.daqing.financial.hrauth.util; |
||||
|
||||
import com.daqing.financial.hrauth.enums.Constants; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.security.crypto.codec.Hex; |
||||
|
||||
import java.security.MessageDigest; |
||||
|
||||
/** |
||||
* <p> 加密工具 </p> |
||||
* |
||||
* @description: |
||||
* @author: zhengqing |
||||
* @date: 2019/10/13 0013 15:25 |
||||
*/ |
||||
@Slf4j |
||||
public class PasswordUtils { |
||||
|
||||
/** |
||||
* 校验密码是否一致 |
||||
* |
||||
* @param password: 前端传过来的密码 |
||||
* @param hashedPassword:数据库中储存加密过后的密码 |
||||
* @param salt:盐值 |
||||
* @return |
||||
*/ |
||||
public static boolean isValidPassword(String password, String hashedPassword, String salt) { |
||||
return hashedPassword.equalsIgnoreCase(encodePassword(password, salt)); |
||||
} |
||||
|
||||
/** |
||||
* 通过SHA1对密码进行编码 |
||||
* |
||||
* @param password:密码 |
||||
* @param salt:盐值 |
||||
* @return |
||||
*/ |
||||
public static String encodePassword(String password, String salt) { |
||||
String encodedPassword; |
||||
try { |
||||
MessageDigest digest = MessageDigest.getInstance("SHA-1"); |
||||
if (salt != null) { |
||||
digest.reset(); |
||||
digest.update(salt.getBytes()); |
||||
} |
||||
byte[] hashed = digest.digest(password.getBytes()); |
||||
int iterations = Constants.HASH_ITERATIONS - 1; |
||||
for (int i = 0; i < iterations; ++i) { |
||||
digest.reset(); |
||||
hashed = digest.digest(hashed); |
||||
} |
||||
encodedPassword = new String(Hex.encode(hashed)); |
||||
} catch (Exception e) { |
||||
log.error("验证密码异常:", e); |
||||
return null; |
||||
} |
||||
System.out.println("生成的密文:"+encodedPassword); |
||||
return encodedPassword; |
||||
} |
||||
|
||||
public static void main(String[] args) { |
||||
System.out.println(encodePassword("1111Aa","zhengqing")); |
||||
} |
||||
} |
@ -0,0 +1,68 @@ |
||||
package com.daqing.financial.hrauth.util; |
||||
|
||||
import com.alibaba.fastjson.JSON; |
||||
import com.alibaba.fastjson.JSONObject; |
||||
import com.daqing.financial.hrauth.model.ApiResult; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
|
||||
import javax.servlet.ServletResponse; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.IOException; |
||||
import java.io.PrintWriter; |
||||
|
||||
/** |
||||
* <p> 使用response输出JSON </p> |
||||
* |
||||
* @description : |
||||
* @author : zhengqing |
||||
* @date : 2019/10/11 17:27 |
||||
*/ |
||||
@Slf4j |
||||
public class ResponseUtils { |
||||
|
||||
/** |
||||
* 使用response输出JSON |
||||
* |
||||
* @param response |
||||
* @param result |
||||
*/ |
||||
public static void out(ServletResponse response, ApiResult result) { |
||||
PrintWriter out = null; |
||||
try { |
||||
response.setCharacterEncoding("UTF-8"); |
||||
response.setContentType("application/json"); |
||||
out = response.getWriter(); |
||||
out.println(JSON.toJSONString(result)); |
||||
} catch (Exception e) { |
||||
log.error(e + "输出JSON出错"); |
||||
} finally { |
||||
if (out != null) { |
||||
out.flush(); |
||||
out.close(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 响应内容 |
||||
* @param httpServletResponse |
||||
* @param msg |
||||
* @param status |
||||
*/ |
||||
public static void getResponse(HttpServletResponse httpServletResponse, String msg, Integer status){ |
||||
PrintWriter writer = null; |
||||
httpServletResponse.setCharacterEncoding("UTF-8"); |
||||
httpServletResponse.setContentType("application/json; charset=utf-8"); |
||||
try { |
||||
writer = httpServletResponse.getWriter(); |
||||
writer.print(JSONObject.toJSONString(new ApiResult(status,msg,null))); |
||||
} catch (IOException e) { |
||||
log.error("响应报错", e.getMessage()); |
||||
} finally { |
||||
if (writer != null){ |
||||
writer.close(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,14 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
||||
<mapper namespace="com.daqing.financial.hrauth.dao.AuthEmployeeRoleDao"> |
||||
|
||||
<!-- 可根据自己的需求,是否要使用 --> |
||||
<resultMap type="com.daqing.framework.domain.hrms.EmployeeRoleEntity" id="employeeRoleMap"> |
||||
<result property="id" column="id"/> |
||||
<result property="userId" column="user_id"/> |
||||
<result property="roleId" column="role_id"/> |
||||
</resultMap> |
||||
|
||||
|
||||
</mapper> |
@ -0,0 +1,27 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
||||
<mapper namespace="com.daqing.financial.hrauth.dao.AuthPermissionDao"> |
||||
|
||||
<!-- 可根据自己的需求,是否要使用 --> |
||||
<resultMap type="com.daqing.framework.domain.hrms.PermissionEntity" id="permissionMap"> |
||||
<result property="id" column="id"/> |
||||
<result property="code" column="code"/> |
||||
<result property="name" column="name"/> |
||||
<result property="url" column="url"/> |
||||
<result property="parentId" column="parent_id"/> |
||||
<result property="level" column="level"/> |
||||
<result property="menuOrNot" column="menu_or_not"/> |
||||
<result property="status" column="status"/> |
||||
<result property="sort" column="sort"/> |
||||
<result property="icon" column="icon"/> |
||||
<result property="createTime" column="create_time"/> |
||||
<result property="motifyTime" column="motify_time"/> |
||||
</resultMap> |
||||
|
||||
<select id="selectRolePermiByPermiId" parameterType="long" |
||||
resultType="com.daqing.framework.domain.hrms.RolePermissionEntity"> |
||||
select id, role_id, permission_id from hrms_role_permission |
||||
WHERE permission_id=#{permissionId} |
||||
</select> |
||||
</mapper> |
@ -0,0 +1,16 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
||||
<mapper namespace="com.daqing.financial.hrauth.dao.AuthRoleDao"> |
||||
|
||||
<!-- 可根据自己的需求,是否要使用 --> |
||||
<resultMap type="com.daqing.framework.domain.hrms.RoleEntity" id="roleMap"> |
||||
<result property="id" column="id"/> |
||||
<result property="name" column="name"/> |
||||
<result property="description" column="description"/> |
||||
<result property="createTime" column="create_time"/> |
||||
<result property="motifyTime" column="motify_time"/> |
||||
</resultMap> |
||||
|
||||
|
||||
</mapper> |
Loading…
Reference in new issue