登录认证,角色权限分配

master
shijie 4 years ago
parent b03afbf971
commit 2a143a4bd3
  1. 2
      dq-financial-api/src/main/java/com/daqing/financial/hrms/EmployeeControllerApi.java
  2. 2
      dq-financial-crms-auth/src/main/java/com/daqing/financial/crauth/config/SecurityConfig.java
  3. 7
      dq-financial-hrms-auth/pom.xml
  4. 213
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/config/SecurityConfig.java
  5. 8
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/controller/SystemLogController.java
  6. 7
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/controller/UserLoginController.java
  7. 17
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/dao/AuthEmployeeRoleDao.java
  8. 20
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/dao/AuthPermissionDao.java
  9. 17
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/dao/AuthRoleDao.java
  10. 9
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/dao/RolePermissionMapper.java
  11. 48
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/enums/Constants.java
  12. 76
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/filter/AdminAuthenticationProcessingFilter.java
  13. 124
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/filter/MyAuthenticationFilter.java
  14. 30
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/handle/AdminAuthenticationEntryPoint.java
  15. 48
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/handle/AdminAuthenticationFailureHandler.java
  16. 80
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/handle/AdminAuthenticationProvider.java
  17. 34
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/handle/AdminAuthenticationSuccessHandler.java
  18. 36
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/handle/CusAuthenticationManager.java
  19. 58
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/handle/MyAuthenticationToken.java
  20. 98
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/handle/SecurityUser.java
  21. 67
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/handle/UrlAccessDecisionManager.java
  22. 28
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/handle/UrlAccessDeniedHandler.java
  23. 116
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/handle/UrlFilterInvocationSecurityMetadataSource.java
  24. 142
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/model/ApiResult.java
  25. 42
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/model/ResultCode.java
  26. 3
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/service/RolePermissionService.java
  27. 4
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/service/UserService.java
  28. 9
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/service/impl/RolePermissionServiceImpl.java
  29. 103
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/service/impl/UserDetailsServiceImpl.java
  30. 12
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/service/impl/UserLoginServiceImpl.java
  31. 62
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/service/impl/UserServiceImpl.java
  32. 164
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/util/MultiReadHttpServletRequest.java
  33. 81
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/util/MultiReadHttpServletResponse.java
  34. 64
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/util/PasswordUtils.java
  35. 68
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/util/ResponseUtils.java
  36. 14
      dq-financial-hrms-auth/src/main/resources/mapper/hrauth/AuthEmployeeRoleDao.xml
  37. 27
      dq-financial-hrms-auth/src/main/resources/mapper/hrauth/AuthPermissionDao.xml
  38. 16
      dq-financial-hrms-auth/src/main/resources/mapper/hrauth/AuthRoleDao.xml
  39. 7
      dq-financial-hrms-auth/src/main/resources/mapper/hrauth/LoginLogMapper.xml
  40. 16
      dq-financial-hrms-auth/src/main/resources/mapper/hrauth/RolePermissionMapper.xml
  41. 4
      dq-financial-hrms-auth/src/main/resources/mapper/hrauth/SystemLogMapper.xml
  42. 4
      dq-financial-hrms-auth/src/main/resources/mapper/hrauth/UserLoginMapper.xml
  43. 5
      dq-financial-hrms/pom.xml
  44. 6
      dq-framework-common/src/main/java/com/daqing/framework/util/Md5Util.java
  45. 1
      dq-framework-model/src/main/java/com/daqing/framework/domain/hrms/RoleEntity.java
  46. 4
      dq-framework-model/src/main/java/com/daqing/framework/domain/hrms/RolePermissionEntity.java
  47. 10
      dq-framework-model/src/main/java/com/daqing/framework/domain/hrms/UserEntity.java
  48. 5
      dq-framework-model/src/main/java/com/daqing/framework/domain/hrms/response/RolePermissionResponse.java
  49. 35
      dq-govern-gateway/src/main/java/com/daqing/financial/gateway/config/ApiGlobalFilter.java

@ -22,7 +22,7 @@ public interface EmployeeControllerApi {
* 分页加条件查询员工信息 * 分页加条件查询员工信息
*/ */
@ApiOperation(value = "分页加条件查询员工信息", notes = "分页加条件查询员工信息") @ApiOperation(value = "分页加条件查询员工信息", notes = "分页加条件查询员工信息")
ResponseResult list(Integer page, Integer size, EmployeeEntity employee); ResponseResult list(Integer page, Integer size,EmployeeEntity employee);
@ApiOperation(value = "根据id删除员工信息", notes = "根据id删除员工信息") @ApiOperation(value = "根据id删除员工信息", notes = "根据id删除员工信息")
ResponseResult delete(Long[] ids); ResponseResult delete(Long[] ids);

@ -45,7 +45,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
} }
/** /**
* 认证管理器 * 认证
*/ */
@Override @Override
@Bean @Bean

@ -43,6 +43,13 @@
<version>2.3.3.RELEASE</version> <version>2.3.3.RELEASE</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.1.6.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId> <artifactId>spring-boot-devtools</artifactId>

@ -1,67 +1,146 @@
//package com.daqing.financial.hrauth.config; package com.daqing.financial.hrauth.config;
//
//import com.daqing.financial.hrauth.service.impl.UserLoginServiceImpl; import com.daqing.financial.hrauth.filter.AdminAuthenticationProcessingFilter;
//import org.springframework.context.annotation.Bean; import com.daqing.financial.hrauth.filter.MyAuthenticationFilter;
//import org.springframework.context.annotation.Configuration; import com.daqing.financial.hrauth.handle.AdminAuthenticationEntryPoint;
//import org.springframework.security.authentication.AuthenticationManager; import com.daqing.financial.hrauth.handle.UrlAccessDecisionManager;
//import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import com.daqing.financial.hrauth.handle.UrlAccessDeniedHandler;
//import org.springframework.security.config.annotation.web.builders.HttpSecurity; import com.daqing.financial.hrauth.handle.UrlFilterInvocationSecurityMetadataSource;
//import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.context.annotation.Configuration;
//import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.http.HttpMethod;
//import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.config.annotation.ObjectPostProcessor;
//import org.springframework.security.crypto.password.PasswordEncoder; 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.builders.WebSecurity;
// * @auther River import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
// * @date 2020/9/22 10:26 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
// */ import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
//@Configuration import org.springframework.security.config.http.SessionCreationPolicy;
//@EnableWebSecurity // 开启security import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
//public class SecurityConfig extends WebSecurityConfigurerAdapter { import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
// import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
// /**
// * 不能直接new对象,否则会在注入之前被拦截器拦截 /**
// */ *  <p> Security 核心配置类 </p>
// @Bean *
// public UserLoginServiceImpl customerLoginService(){ * @author  zhengqing <br/>
// * @date  2019/9/30$ 10:58$ <br/>
// return new UserLoginServiceImpl(); * @version  <br/>
// } */
// @Configuration
// // 定义用户信息(查询用户信息),security帮助我们查询,但是需要告诉他如何去查询 @EnableWebSecurity
// @Override @EnableGlobalMethodSecurity(prePostEnabled = true)
// protected void configure(AuthenticationManagerBuilder auth) throws Exception { public class SecurityConfig extends WebSecurityConfigurerAdapter {
//
// auth.userDetailsService(customerLoginService()); /**
// } * 访问鉴权 - 认证token签名...
// */
// private final MyAuthenticationFilter myAuthenticationFilter;
// // 密码编码器,比对密码的方式 /**
// @Bean * 访问权限认证异常处理
// public PasswordEncoder passwordEncoder(){ */
// private final AdminAuthenticationEntryPoint adminAuthenticationEntryPoint;
// return new BCryptPasswordEncoder(); /**
// } * 用户密码校验过滤器
// */
// /** private final AdminAuthenticationProcessingFilter adminAuthenticationProcessingFilter;
// * 认证管理器
// */ // 上面是登录认证相关 下面为url权限相关 - ========================================================================================
// @Override
// @Bean /**
// public AuthenticationManager authenticationManagerBean() throws Exception { * 获取访问url所需要的角色信息
// */
// return super.authenticationManagerBean(); private final UrlFilterInvocationSecurityMetadataSource urlFilterInvocationSecurityMetadataSource;
// } /**
// * 认证权限处理 - 将上面所获得角色权限与当前登录用户的角色做对比如果包含其中一个角色即可正常访问
// // 安全拦截机制 */
// @Override private final UrlAccessDecisionManager urlAccessDecisionManager;
// protected void configure(HttpSecurity http) throws Exception { /**
// http.authorizeRequests() * 自定义访问无权限接口时403响应内容
// .antMatchers("/*").authenticated() // 该路径下所有请求都会被拦截 */
// .anyRequest().permitAll() // 其余的请求可以通过 private final UrlAccessDeniedHandler urlAccessDeniedHandler;
// .and()
// .formLogin() // 允许表单认证 public SecurityConfig(MyAuthenticationFilter myAuthenticationFilter, AdminAuthenticationEntryPoint adminAuthenticationEntryPoint, AdminAuthenticationProcessingFilter adminAuthenticationProcessingFilter, UrlFilterInvocationSecurityMetadataSource urlFilterInvocationSecurityMetadataSource, UrlAccessDeniedHandler urlAccessDeniedHandler, UrlAccessDecisionManager urlAccessDecisionManager) {
// .successForwardUrl("/customerLogin/loginSuccess"); // 登录成功跳转路径 this.myAuthenticationFilter = myAuthenticationFilter;
// } this.adminAuthenticationEntryPoint = adminAuthenticationEntryPoint;
//} this.adminAuthenticationProcessingFilter = adminAuthenticationProcessingFilter;
// this.urlFilterInvocationSecurityMetadataSource = urlFilterInvocationSecurityMetadataSource;
this.urlAccessDeniedHandler = urlAccessDeniedHandler;
this.urlAccessDecisionManager = urlAccessDecisionManager;
}
/**
* 权限配置
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http.antMatcher("/**").authorizeRequests();
// 禁用CSRF 开启跨域
http.csrf().disable().cors();
// 未登录认证异常
http.exceptionHandling().authenticationEntryPoint(adminAuthenticationEntryPoint);
// 登录过后访问无权限的接口时自定义403响应内容
http.exceptionHandling().accessDeniedHandler(urlAccessDeniedHandler);
// url权限认证处理
registry.withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
@Override
public <O extends FilterSecurityInterceptor> O postProcess(O o) {
o.setSecurityMetadataSource(urlFilterInvocationSecurityMetadataSource);
o.setAccessDecisionManager(urlAccessDecisionManager);
return o;
}
});
// 不创建会话 - 即通过前端传token到后台过滤器中验证是否存在访问权限
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// 登录处理 - 前后端一体的情况下
// registry.and().formLogin().loginPage("/login").defaultSuccessUrl("/").permitAll()
// // 自定义登陆用户名和密码属性名,默认为 username和password
// .usernameParameter("username").passwordParameter("password")
// // 异常处理
// .failureUrl("/login/error").permitAll()
// // 退出登录
// .and().logout().permitAll();
// 标识访问 `/home` 这个接口,需要具备`ADMIN`角色
// registry.antMatchers("/home").hasRole("ADMIN");
// 标识只能在 服务器本地ip[127.0.0.1或localhost] 访问 `/home` 这个接口,其他ip地址无法访问
// registry.antMatchers("/hrms/auth/userlogin/getBackPwd").hasIpAddress("127.0.0.1");
// 允许匿名的url - 可理解为放行接口 - 多个接口使用,分割
registry.antMatchers("/**").permitAll();
// registry.antMatchers("/**").access("hasAuthority('admin')");
// OPTIONS(选项):查找适用于一个特定网址资源的通讯选择。 在不需执行具体的涉及数据传输的动作情况下, 允许客户端来确定与资源相关的选项以及 / 或者要求, 或是一个服务器的性能
//registry.antMatchers(HttpMethod.OPTIONS, "/**").denyAll();
registry.anyRequest().authenticated();
// 自动登录 - cookie储存方式
registry.and().rememberMe();
// 其余所有请求都需要认证
registry.anyRequest().authenticated();
// 防止iframe 造成跨域
registry.and().headers().frameOptions().disable();
// 自定义过滤器在登录时认证用户名、密码
http.addFilterAt(adminAuthenticationProcessingFilter, UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(myAuthenticationFilter, BasicAuthenticationFilter.class);
}
/**
* 忽略拦截url或静态资源文件夹 - web.ignoring(): 会直接过滤该url - 将不会经过Spring Security过滤器链
* http.permitAll(): 不会绕开springsecurity验证相当于是允许该路径通过
* @param web
* @throws Exception
*/
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/**");
}
}

@ -1,26 +1,18 @@
package com.daqing.financial.hrauth.controller; package com.daqing.financial.hrauth.controller;
import com.daqing.financial.hrauth.SystemLogControllerApi; import com.daqing.financial.hrauth.SystemLogControllerApi;
import com.daqing.financial.hrauth.UserLoginControllerApi;
import com.daqing.financial.hrauth.annotation.Log; import com.daqing.financial.hrauth.annotation.Log;
import com.daqing.financial.hrauth.enums.OperationType; import com.daqing.financial.hrauth.enums.OperationType;
import com.daqing.financial.hrauth.enums.OperationUnit; import com.daqing.financial.hrauth.enums.OperationUnit;
import com.daqing.financial.hrauth.service.LoginLogService; import com.daqing.financial.hrauth.service.LoginLogService;
import com.daqing.financial.hrauth.service.SystemLogService; import com.daqing.financial.hrauth.service.SystemLogService;
import com.daqing.financial.hrauth.service.UserLoginService;
import com.daqing.framework.domain.hrms.EmployeeEntity;
import com.daqing.framework.domain.hrms.SystemLog;
import com.daqing.framework.domain.hrms.request.LoginRequest;
import com.daqing.framework.domain.hrms.request.UserLoginLogRequest; import com.daqing.framework.domain.hrms.request.UserLoginLogRequest;
import com.daqing.framework.domain.hrms.request.UserLoginRequest;
import com.daqing.framework.model.response.ResponseResult; import com.daqing.framework.model.response.ResponseResult;
import com.daqing.framework.utils.PageUtils; import com.daqing.framework.utils.PageUtils;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/** /**

@ -13,6 +13,7 @@ import com.daqing.framework.model.response.ResponseResult;
import com.daqing.framework.util.JwtUtils; import com.daqing.framework.util.JwtUtils;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -30,6 +31,7 @@ import java.net.URLEncoder;
@RestController @RestController
@RequestMapping("/hrms/auth/userlogin") @RequestMapping("/hrms/auth/userlogin")
@Api(tags = {"登录"}) @Api(tags = {"登录"})
@Slf4j
public class UserLoginController implements UserLoginControllerApi { public class UserLoginController implements UserLoginControllerApi {
@Autowired @Autowired
@ -120,13 +122,14 @@ public class UserLoginController implements UserLoginControllerApi {
@GetMapping("/user/callback") @GetMapping("/user/callback")
public void wechatUserCallback(@RequestParam(value = "code",required = true) String code, public void wechatUserCallback(@RequestParam(value = "code",required = true) String code,
String state, HttpServletResponse response) throws IOException { String state, HttpServletResponse response) throws IOException {
UserEntity user = userService.saveWeChatUser(code); log.info("来了微信回调url=============================");
UserEntity user = userService.saveWeChatUser(code,response);
if(user != null){ if(user != null){
long times = 86400; long times = 86400;
//生成jwt //生成jwt
String token = JwtUtils.createJWT(user.getId()+"","token", times); String token = JwtUtils.createJWT(user.getId()+"","token", times);
// state 当前用户的页面地址,需要拼接 http:// 这样才不会站内跳转 // state 当前用户的页面地址,需要拼接 http:// 这样才不会站内跳转
response.sendRedirect(state+"?token="+token); response.sendRedirect("http://www.huorantech.cn/dq/index.html#/Dashboard?token="+token);
//response.sendRedirect(state+"?token="+token+"&head_img="+user.getHeadImg()+"&name="+URLEncoder.encode(user.getName(),"UTF-8")); //response.sendRedirect(state+"?token="+token+"&head_img="+user.getHeadImg()+"&name="+URLEncoder.encode(user.getName(),"UTF-8"));
} }
} }

@ -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> {
}

@ -3,7 +3,8 @@ package com.daqing.financial.hrauth.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.daqing.framework.domain.hrms.PermissionEntity; import com.daqing.framework.domain.hrms.EmployeeRoleEntity;
import com.daqing.framework.domain.hrms.RolePermissionEntity;
import com.daqing.framework.domain.hrms.request.RolePermissionRequest; import com.daqing.framework.domain.hrms.request.RolePermissionRequest;
import com.daqing.framework.domain.hrms.response.RolePermissionResponse; import com.daqing.framework.domain.hrms.response.RolePermissionResponse;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@ -19,7 +20,7 @@ import java.util.List;
* @date 2020-09-07 16:26:04 * @date 2020-09-07 16:26:04
*/ */
@Mapper @Mapper
public interface RolePermissionMapper extends BaseMapper<PermissionEntity> { public interface RolePermissionMapper extends BaseMapper<RolePermissionEntity> {
IPage<RolePermissionResponse> pageByCondition(Page page); IPage<RolePermissionResponse> pageByCondition(Page page);
List<RolePermissionResponse> queryPermissionByRoleId(Long roleId); List<RolePermissionResponse> queryPermissionByRoleId(Long roleId);
@ -37,4 +38,8 @@ public interface RolePermissionMapper extends BaseMapper<PermissionEntity> {
boolean deleteHrmsRoleByRoleId(Long roleId); boolean deleteHrmsRoleByRoleId(Long roleId);
int uniqueRoleName(String name); int uniqueRoleName(String name);
EmployeeRoleEntity selectRoleByUserId(Long id);
List<RolePermissionEntity> selectRolePermiByPermiId(Long permissionId);
} }

@ -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失败或无效为0token过期
*/
@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;
}
}

@ -2,6 +2,7 @@ package com.daqing.financial.hrauth.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.daqing.framework.domain.hrms.PermissionEntity; import com.daqing.framework.domain.hrms.PermissionEntity;
import com.daqing.framework.domain.hrms.RolePermissionEntity;
import com.daqing.framework.domain.hrms.request.RolePermissionRequest; import com.daqing.framework.domain.hrms.request.RolePermissionRequest;
import com.daqing.framework.domain.hrms.response.RolePermissionResponse; import com.daqing.framework.domain.hrms.response.RolePermissionResponse;
import com.daqing.framework.utils.PageUtils; import com.daqing.framework.utils.PageUtils;
@ -15,7 +16,7 @@ import java.util.List;
* @email gongsj@gmail.com * @email gongsj@gmail.com
* @date 2020-09-07 16:26:04 * @date 2020-09-07 16:26:04
*/ */
public interface RolePermissionService extends IService<PermissionEntity> { public interface RolePermissionService extends IService<RolePermissionEntity> {
List<PermissionEntity> listWithTree(); List<PermissionEntity> listWithTree();

@ -3,10 +3,12 @@ package com.daqing.financial.hrauth.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.daqing.framework.domain.hrms.UserEntity; import com.daqing.framework.domain.hrms.UserEntity;
import javax.servlet.http.HttpServletResponse;
/** /**
* @auther River * @auther River
* @date 2020/9/22 15:00 * @date 2020/9/22 15:00
*/ */
public interface UserService extends IService<UserEntity> { public interface UserService extends IService<UserEntity> {
UserEntity saveWeChatUser(String code); UserEntity saveWeChatUser(String code, HttpServletResponse response);
} }

@ -6,9 +6,11 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.daqing.financial.hrauth.dao.RolePermissionMapper; import com.daqing.financial.hrauth.dao.RolePermissionMapper;
import com.daqing.financial.hrauth.service.RolePermissionService; import com.daqing.financial.hrauth.service.RolePermissionService;
import com.daqing.framework.domain.hrms.PermissionEntity; import com.daqing.framework.domain.hrms.PermissionEntity;
import com.daqing.framework.domain.hrms.RolePermissionEntity;
import com.daqing.framework.domain.hrms.request.RolePermissionRequest; import com.daqing.framework.domain.hrms.request.RolePermissionRequest;
import com.daqing.framework.domain.hrms.response.RolePermissionResponse; import com.daqing.framework.domain.hrms.response.RolePermissionResponse;
import com.daqing.framework.utils.PageUtils; import com.daqing.framework.utils.PageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Comparator; import java.util.Comparator;
@ -17,12 +19,13 @@ import java.util.stream.Collectors;
@Service("rolePermissionService") @Service("rolePermissionService")
public class RolePermissionServiceImpl extends ServiceImpl<RolePermissionMapper, PermissionEntity> implements RolePermissionService { public class RolePermissionServiceImpl extends ServiceImpl<RolePermissionMapper, RolePermissionEntity> implements RolePermissionService {
@Override @Override
public List<PermissionEntity> listWithTree() { public List<PermissionEntity> listWithTree() {
System.out.println("this.list()=================="+this.list()); /*System.out.println("this.list()=================="+this.list());
return getPermissionTreeList(this.list(), 0L); return getPermissionTreeList(this.list(), 0L);*/
return null;
} }
@Override @Override

@ -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;
}
}

@ -23,6 +23,7 @@ import com.daqing.framework.util.Md5Util;
import com.daqing.framework.util.RedisUtil; import com.daqing.framework.util.RedisUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -119,11 +120,14 @@ public class UserLoginServiceImpl extends ServiceImpl<UserLoginDao, UserEntity>
} }
String newPassword = Md5Util.md5(loginRequest.getPassword()+userEntity.getId()); String newPassword = Md5Util.md5(loginRequest.getPassword()+userEntity.getId());
if(!newPassword.equals(userEntity.getPassword())){ if(!newPassword.equals(userEntity.getPassword())){
return ResponseResult.FAIL(CommonCode.PASSWORD_IS_ERROR.code(), CommonCode.PASSWORD_IS_ERROR.message()); throw new UsernameNotFoundException("密码错误!");
//return ResponseResult.FAIL(CommonCode.PASSWORD_IS_ERROR.code(), CommonCode.PASSWORD_IS_ERROR.message());
} }
}else {//微信登录 }else {//微信登录
if(userEntity == null){
return ResponseResult.FAIL(CommonCode.USER_IS_NOT_EXIST.code(), CommonCode.USER_IS_NOT_EXIST.message());
}
} }
//登录成功,token生成 //登录成功,token生成
long times = 86400; long times = 86400;
@ -209,4 +213,8 @@ public class UserLoginServiceImpl extends ServiceImpl<UserLoginDao, UserEntity>
int i = userLoginDao.updatePasswordByPhoneAccount(user.getPhoneAccount(),newMD5); int i = userLoginDao.updatePasswordByPhoneAccount(user.getPhoneAccount(),newMD5);
return i > 0; return i > 0;
} }
} }

@ -3,18 +3,31 @@ package com.daqing.financial.hrauth.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.daqing.financial.hrauth.config.WeChatConfig; import com.daqing.financial.hrauth.config.WeChatConfig;
import com.daqing.financial.hrauth.dao.UserLoginDao; import com.daqing.financial.hrauth.dao.UserLoginDao;
import com.daqing.financial.hrauth.handle.MyAuthenticationToken;
import com.daqing.financial.hrauth.handle.SecurityUser;
import com.daqing.financial.hrauth.service.UserLoginService;
import com.daqing.financial.hrauth.service.UserService; import com.daqing.financial.hrauth.service.UserService;
import com.daqing.financial.hrauth.util.HttpUtils; import com.daqing.financial.hrauth.util.HttpUtils;
import com.daqing.framework.domain.hrms.UserEntity; import com.daqing.framework.domain.hrms.UserEntity;
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.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
@Service @Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserLoginDao, UserEntity> implements UserService { public class UserServiceImpl extends ServiceImpl<UserLoginDao, UserEntity> implements UserService {
@Autowired @Autowired
@ -23,8 +36,14 @@ public class UserServiceImpl extends ServiceImpl<UserLoginDao, UserEntity> imple
@Resource @Resource
private UserLoginDao userMapper; private UserLoginDao userMapper;
@Resource
private UserLoginService userLoginService;
@Resource
private UserDetailsService userDetailsService;
@Override @Override
public UserEntity saveWeChatUser(String code) { public UserEntity saveWeChatUser(String code,HttpServletResponse response) {
String accessTokenUrl = String.format(weChatConfig.getOPEN_ACCESS_TOKEN_URL(),weChatConfig.getOpenAppid(),weChatConfig.getOpenAppsecret(),code); String accessTokenUrl = String.format(weChatConfig.getOPEN_ACCESS_TOKEN_URL(),weChatConfig.getOpenAppid(),weChatConfig.getOpenAppsecret(),code);
@ -35,19 +54,50 @@ public class UserServiceImpl extends ServiceImpl<UserLoginDao, UserEntity> imple
String accessToken = (String)baseMap.get("access_token"); String accessToken = (String)baseMap.get("access_token");
String openId = (String) baseMap.get("openid"); String openId = (String) baseMap.get("openid");
log.info("accessToken========> "+accessToken+"openId========> "+openId+"code=======> "+code);
UserEntity dbUser = userMapper.findByOpenid(openId); UserEntity dbUser = userMapper.findByOpenid(openId);
if(dbUser!=null) { //更新用户,直接返回 if(dbUser!=null && dbUser.getPhoneAccount()!=null) { //dbUser不为空,存在直接让它登录
log.info("来了微信扫码登录~~~~~~~~~~~~~~~~~~~~~~~~~~~");
LoginRequest loginRequest = new LoginRequest();
loginRequest.setTenDayEffective(1);
loginRequest.setType(2);
loginRequest.setWechatId(openId);
ResponseResult login = userLoginService.login(loginRequest);
LoginResponse data = (LoginResponse) login.getData();
SecurityUser userInfo = (SecurityUser) userDetailsService.loadUserByUsername(dbUser.getPhoneAccount());
userInfo.getCurrentUserInfo().setToken(data.getToken());
new UsernamePasswordAuthenticationToken(userInfo, null, userInfo.getAuthorities());
return dbUser; return dbUser;
} }
if(dbUser == null){//openId不存在,返回绑定手机号页面,须另写绑定手机号接口
log.info("dbUser为空,openId不存在,请先绑定手机号哦~~~");
try {
response.sendRedirect("https://www.baidu.com");//跳转绑定手机号页面
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
//获取用户基本信息 //获取用户基本信息
String userInfoUrl = String.format(weChatConfig.getOPEN_USER_INFO_URL(),accessToken,openId); /* String userInfoUrl = String.format(weChatConfig.getOPEN_USER_INFO_URL(),accessToken,openId);
Map<String ,Object> baseUserMap = HttpUtils.doGet(userInfoUrl); Map<String ,Object> baseUserMap = HttpUtils.doGet(userInfoUrl);
if(baseUserMap == null || baseUserMap.isEmpty()){ if(baseUserMap == null || baseUserMap.isEmpty()){
return null; return null;
} }
UserEntity user = new UserEntity();
user.setWechatId(openId);
user.setCreateTime(new Date());
userMapper.insert(user);
return user;*/
/* String nickname = (String)baseUserMap.get("nickname"); /* String nickname = (String)baseUserMap.get("nickname");
Double sexTemp = (Double) baseUserMap.get("sex"); Double sexTemp = (Double) baseUserMap.get("sex");
@ -66,11 +116,5 @@ public class UserServiceImpl extends ServiceImpl<UserLoginDao, UserEntity> imple
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
e.printStackTrace(); e.printStackTrace();
}*/ }*/
UserEntity user = new UserEntity();
user.setWechatId(openId);
user.setCreateTime(new Date());
userMapper.insert(user);
return user;
} }
} }

@ -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>

@ -3,14 +3,11 @@
<mapper namespace="com.daqing.financial.hrauth.dao.LoginLogMapper"> <mapper namespace="com.daqing.financial.hrauth.dao.LoginLogMapper">
<!-- 可根据自己的需求,是否要使用 --> <!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.daqing.framework.domain.hrms.LoginLog" id="LoginLogMap"> <resultMap type="com.daqing.framework.domain.hrms.LoginLogEntity" id="userEntityLoginLogMap">
<result property="id" column="id"/>
</resultMap>
<resultMap type="com.daqing.framework.domain.hrms.LoginLogEntity" id="userLoginLogMap">
<result property="id" column="id"/> <result property="id" column="id"/>
</resultMap> </resultMap>
<select id="pageByCondition" parameterType="com.daqing.framework.domain.hrms.request.UserLoginLogRequest" resultMap="userLoginLogMap"> <select id="pageByCondition" parameterType="com.daqing.framework.domain.hrms.request.UserLoginLogRequest" resultMap="userEntityLoginLogMap">
SELECT SELECT
hll.user_id,hll.login_num,hll.create_time,hll.newest_time,he.`name` as empName,he.job_number, hll.user_id,hll.login_num,hll.create_time,hll.newest_time,he.`name` as empName,he.job_number,
he.phone,hp.`name` as posName,GROUP_CONCAT(hd.`name`) as deptName he.phone,hp.`name` as posName,GROUP_CONCAT(hd.`name`) as deptName

@ -3,6 +3,11 @@
<mapper namespace="com.daqing.financial.hrauth.dao.RolePermissionMapper"> <mapper namespace="com.daqing.financial.hrauth.dao.RolePermissionMapper">
<resultMap type="com.daqing.framework.domain.hrms.RolePermissionEntity" id="rolePermissionMap">
<result property="id" column="id"/>
<result property="roleId" column="role_id"/>
<result property="permissionId" column="permission_id"/>
</resultMap>
<!-- 可根据自己的需求,是否要使用 --> <!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.daqing.framework.domain.hrms.PermissionEntity" id="permissionMap"> <resultMap type="com.daqing.framework.domain.hrms.PermissionEntity" id="permissionMap">
<result property="id" column="id"/> <result property="id" column="id"/>
@ -18,6 +23,7 @@
<result property="createTime" column="create_time"/> <result property="createTime" column="create_time"/>
<result property="motifyTime" column="motify_time"/> <result property="motifyTime" column="motify_time"/>
</resultMap> </resultMap>
<delete id="deleteHrmsRolePermission"> <delete id="deleteHrmsRolePermission">
delete from hrms_role_permission where role_id=#{roleId} delete from hrms_role_permission where role_id=#{roleId}
</delete> </delete>
@ -79,4 +85,14 @@
select count(0) from hrms_role where `name` = #{name} select count(0) from hrms_role where `name` = #{name}
</select> </select>
<select id="selectRoleByUserId" parameterType="long" resultType="com.daqing.framework.domain.hrms.EmployeeRoleEntity">
select role_id from hrms_employee_role where user_id=#{userId}
</select>
<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> </mapper>

@ -3,11 +3,11 @@
<mapper namespace="com.daqing.financial.hrauth.dao.SystemLogMapper"> <mapper namespace="com.daqing.financial.hrauth.dao.SystemLogMapper">
<!-- 可根据自己的需求,是否要使用 --> <!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.daqing.framework.domain.hrms.SystemLog" id="SystemLogMap"> <resultMap type="com.daqing.framework.domain.hrms.SystemLog" id="systemLogMap">
<result property="id" column="id"/> <result property="id" column="id"/>
</resultMap> </resultMap>
<select id="pageByCondition" resultMap="SystemLogMap"> <select id="pageByCondition" resultMap="systemLogMap">
SELECT * SELECT *
FROM FROM
sys_action_log sys_action_log

@ -17,7 +17,7 @@
</update> </update>
<select id="getUser" parameterType="string" resultType="com.daqing.framework.domain.hrms.UserEntity"> <select id="getUser" parameterType="string" resultType="com.daqing.framework.domain.hrms.UserEntity">
SELECT account,password FROM hrms_user WHERE account = #{account} SELECT id,account,password FROM hrms_user WHERE account = #{account}
</select> </select>
<select id="selectCount" resultType="java.lang.Integer"> <select id="selectCount" resultType="java.lang.Integer">
select count(1) from hrms_user where phone_account = #{phoneAccount} select count(1) from hrms_user where phone_account = #{phoneAccount}
@ -38,7 +38,7 @@
SELECT id,account,password FROM hrms_user WHERE phone_account = #{phoneAccount} SELECT id,account,password FROM hrms_user WHERE phone_account = #{phoneAccount}
</select> </select>
<select id="findByOpenid" parameterType="string" resultType="com.daqing.framework.domain.hrms.UserEntity"> <select id="findByOpenid" parameterType="string" resultType="com.daqing.framework.domain.hrms.UserEntity">
select id from hrms_user where wechat_id = #{openId} select id,phone_account from hrms_user where wechat_id = #{openId}
</select> </select>
</mapper> </mapper>

@ -41,6 +41,11 @@
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<!-- <dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>-->
</dependencies> </dependencies>
<dependencyManagement> <dependencyManagement>

@ -22,12 +22,12 @@ public class Md5Util {
} }
public static void main(String[] args) throws UnsupportedEncodingException { public static void main(String[] args) throws UnsupportedEncodingException {
System.out.printf(md5("1234562")); System.out.printf(md5("1111Aa5"));
/*String s = URLEncoder.encode("www.occupationlab.com", "utf-8"); /*String s = URLEncoder.encode("www.occupationlab.com", "utf-8");
System.out.println(s);*/ System.out.println(s);*/
//System.out.printf(md5("1234561")); //System.out.printf(md5("1234561"));
String s = URLEncoder.encode("www.occupationlab.com", "utf-8"); String s = URLEncoder.encode("www.occupationlab.com", "utf-8");
System.out.println(s); //System.out.println(s);
System.out.println(md5("1234564")); //System.out.println(md5("1234564"));
} }
} }

@ -41,5 +41,4 @@ public class RoleEntity implements Serializable {
* 更新时间 * 更新时间
*/ */
private Date motifyTime; private Date motifyTime;
} }

@ -1,6 +1,7 @@
package com.daqing.framework.domain.hrms; package com.daqing.framework.domain.hrms;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
@ -16,7 +17,7 @@ import lombok.Data;
* @date 2020-09-07 16:26:04 * @date 2020-09-07 16:26:04
*/ */
@Data @Data
@TableName("hrms_role_permission") @TableName(value = "hrms_role_permission")
public class RolePermissionEntity implements Serializable { public class RolePermissionEntity implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -32,6 +33,7 @@ public class RolePermissionEntity implements Serializable {
/** /**
* 权限id * 权限id
*/ */
@TableField("permission_id")
private Long permissionId; private Long permissionId;
} }

@ -78,4 +78,14 @@ public class UserEntity implements Serializable {
*/ */
private Date motifyTime; private Date motifyTime;
/**
* Token
*/
private String token;
/**
* 盐值
*/
//private String salt;
} }

@ -61,4 +61,9 @@ public class RolePermissionResponse implements Serializable {
*/ */
private Integer sort; private Integer sort;
/**
* 权限标识
*/
private String code;
} }

@ -58,26 +58,29 @@ public class ApiGlobalFilter implements GlobalFilter, Ordered {
response.getHeaders().add("Content-Type", "text/json;charset=UTF-8"); response.getHeaders().add("Content-Type", "text/json;charset=UTF-8");
return response.writeWith(Mono.just(buffer)); return response.writeWith(Mono.just(buffer));
//有数据 //有数据
}else { }//else {
//校验token // //校验token
boolean isVerify = verifyJWT(token); // boolean isVerify = verifyJWT(token);
//String userId = RedisUtil.get("dq:token:"+token); // //String userId = RedisUtil.get("dq:token:"+token);
if (! isVerify){ // if (! isVerify){
JSONObject message = new JSONObject(); // JSONObject message = new JSONObject();
message.put("message", "登录已失效,请重新登录"); // message.put("message", "登录已失效,请重新登录");
message.put("code", "401"); // message.put("code", "401");
byte[] bits = message.toString().getBytes(StandardCharsets.UTF_8); // byte[] bits = message.toString().getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = response.bufferFactory().wrap(bits); // DataBuffer buffer = response.bufferFactory().wrap(bits);
response.setStatusCode(HttpStatus.UNAUTHORIZED); // response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().add("Content-Type", "text/json;charset=UTF-8"); // response.getHeaders().add("Content-Type", "text/json;charset=UTF-8");
return response.writeWith(Mono.just(buffer)); // return response.writeWith(Mono.just(buffer));
} // }
//将现在的request,添加当前身份 // //将现在的request,添加当前身份
// ServerHttpRequest mutableReq = exchange.getRequest().mutate().header("Authorization", token).build();
// ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build();
// return chain.filter(mutableExchange);
// }
ServerHttpRequest mutableReq = exchange.getRequest().mutate().header("Authorization", token).build(); ServerHttpRequest mutableReq = exchange.getRequest().mutate().header("Authorization", token).build();
ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build(); ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build();
return chain.filter(mutableExchange); return chain.filter(mutableExchange);
} }
}
return chain.filter(exchange); return chain.filter(exchange);
} }

Loading…
Cancel
Save