人力资源系统认证服务器

master
shijie 4 years ago
parent b8d0d44e92
commit 41ef7f4b6c
  1. 28
      dq-financial-hrms-auth/pom.xml
  2. 6
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/DqFinancialHrmsAuthApplication.java
  3. 109
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/config/AuthorizationServer.java
  4. 67
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/config/SecurityConfig.java
  5. 22
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/config/TokenConfig.java
  6. 37
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/controller/UserLoginController.java
  7. 18
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/dao/UserLoginDao.java
  8. 13
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/service/UserLoginService.java
  9. 81
      dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/service/impl/UserLoginServiceImpl.java
  10. 1
      dq-financial-hrms-auth/src/main/resources/application.properties
  11. 19
      dq-financial-hrms-auth/src/main/resources/bootstrap.properties
  12. 16
      dq-financial-hrms-auth/src/main/resources/mapper/hrmsauth/UserLoginMapper.xml
  13. 7
      dq-financial-hrms/pom.xml
  14. 47
      dq-financial-hrms/src/main/java/com/daqing/financial/hrms/config/ResourceServerConfig.java
  15. 18
      dq-financial-hrms/src/main/java/com/daqing/financial/hrms/controller/UserController.java
  16. BIN
      dq-financial-hrms/target/classes/com/daqing/financial/hrms/controller/UserController.class
  17. 3
      dq-financial-hrms/target/classes/mapper/hrms/EmployeeDao.xml
  18. 3
      dq-framework-model/src/main/java/com/daqing/framework/domain/hrms/UserEntity.java
  19. 34
      dq-framework-model/src/main/java/com/daqing/framework/domain/hrms/request/UserLoginRequest.java
  20. 7
      dq-framework-model/src/main/java/com/daqing/framework/domain/hrms/response/HrmsCode.java
  21. BIN
      dq-framework-model/target/classes/com/daqing/framework/domain/hrms/response/HrmsCode.class

@ -50,6 +50,34 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
<version>1.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<!-- 指明版本,解决redis存储出现的问题:java.lang.NoSuchMethodError: org.springframework.data.redis.connection.RedisConnection.set([B[B)V问题 -->
<version>2.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
</dependencies>
<dependencyManagement>

@ -2,8 +2,14 @@ package com.daqing.financial.hrauth;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
@EnableFeignClients(basePackages = "com.daqing.financial.hrauth.feign")
@EnableDiscoveryClient
@SpringBootApplication
@ComponentScan(basePackages = "com.daqing")
public class DqFinancialHrmsAuthApplication {
public static void main(String[] args) {

@ -0,0 +1,109 @@
package com.daqing.financial.hrauth.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
/**
* 配置OAuth2.0授权服务器
*
* @auther River
* @date 2020/9/21 17:49
*/
@Configuration
@EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private AuthorizationCodeServices authorizationCodeServices;
@Autowired
public PasswordEncoder passwordEncoder;
/**
* 配置令牌的安全约束(允许哪些请求访问)
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
.tokenKeyAccess("permitAll()") // 公开提供公钥加密的端点(就是使用jwt令牌的时候需要的)
.checkTokenAccess("permitAll()") // 校验令牌
.allowFormAuthenticationForClients(); //允许表单提交,允许客户端访问 OAuth2 授权接口,否则请求 token 会返回 401。
}
/**
* 配置支持哪些客户端访问
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("order-client")
.secret(passwordEncoder.encode("order-secret-8888"))
.authorizedGrantTypes("refresh_token", "authorization_code", "password")
.accessTokenValiditySeconds(3600)
.scopes("all")
.and()
.withClient("user-client")
.secret(passwordEncoder.encode("user-secret-8888"))
.authorizedGrantTypes("refresh_token", "authorization_code", "password")
.accessTokenValiditySeconds(3600)
.scopes("all");
}
/**
* 配置令牌(token)的访问端点
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager) // 密码模式需要
.authorizationCodeServices(authorizationCodeServices) // 授权码模式需要
.tokenServices(tokenServices()) // 令牌的管理方式
.allowedTokenEndpointRequestMethods(HttpMethod.POST); // 允许的请求方式
}
/**
* 令牌服务
*/
@Bean
public AuthorizationServerTokenServices tokenServices(){
DefaultTokenServices service = new DefaultTokenServices();
service.setClientDetailsService(clientDetailsService); // 客户端信息的服务
service.setSupportRefreshToken(true); // 是否产生刷新令牌
service.setTokenStore(tokenStore); // 令牌的存储策略
service.setAccessTokenValiditySeconds(7200); // 令牌有效期
service.setRefreshTokenValiditySeconds(259200); // 刷新令牌有效期
return service;
}
/**
* 授权码服务(设置授权码模式的授权码如何存取,暂时在内存,后期在数据库)
*/
@Bean
public AuthorizationCodeServices authorizationCodeServices(){
return new InMemoryAuthorizationCodeServices();
}
}

@ -0,0 +1,67 @@
package com.daqing.financial.hrauth.config;
import com.daqing.financial.hrauth.service.impl.UserLoginServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* @auther River
* @date 2020/9/22 10:26
*/
@Configuration
@EnableWebSecurity // 开启security
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 不能直接new对象,否则会在注入之前被拦截器拦截
*/
@Bean
public UserLoginServiceImpl customerLoginService(){
return new UserLoginServiceImpl();
}
// 定义用户信息(查询用户信息),security帮助我们查询,但是需要告诉他如何去查询
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customerLoginService());
}
// 密码编码器,比对密码的方式
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
/**
* 认证管理器
*/
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
// 安全拦截机制
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/*").authenticated() // 该路径下所有请求都会被拦截
.anyRequest().permitAll() // 其余的请求可以通过
.and()
.formLogin() // 允许表单认证
.successForwardUrl("/customerLogin/loginSuccess"); // 登录成功跳转路径
}
}

@ -0,0 +1,22 @@
package com.daqing.financial.hrauth.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
/**
* 令牌配置类
*
* @auther River
* @date 2020/9/22 9:54
*/
@Configuration
public class TokenConfig {
@Bean
public TokenStore tokenStore(){
// 内存生成,普通令牌
return new InMemoryTokenStore();
}
}

@ -0,0 +1,37 @@
package com.daqing.financial.hrauth.controller;
import com.daqing.financial.hrauth.service.UserLoginService;
import com.daqing.framework.domain.hrms.request.UserLoginRequest;
import com.daqing.framework.model.response.ResponseResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @auther River
* @date 2020/9/22 15:27
*/
@RestController
@RequestMapping("/hrms/auth/userlogin")
public class UserLoginController {
@Autowired
private UserLoginService userLoginService;
@PostMapping("/loginSuccess")
public String loginSuccess(){
return "success";
}
@GetMapping("/test")
public String test(){
return "Hello";
}
@PostMapping("/getBackPwd")
public ResponseResult getBackPwd(@RequestBody UserLoginRequest user){
boolean result = userLoginService.getBackPwd(user);
return result ? ResponseResult.SUCCESS() : ResponseResult.FAIL();
}
}

@ -0,0 +1,18 @@
package com.daqing.financial.hrauth.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.daqing.framework.domain.hrms.UserEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* @auther River
* @date 2020/9/22 14:55
*/
@Mapper
public interface UserLoginDao extends BaseMapper<UserEntity> {
UserEntity getUser(String code);
int selectCount(String phoneAccount);
int updatePasswordByPhoneAccount(@Param("phoneAccount") String phoneAccount, @Param("password") String password);
}

@ -0,0 +1,13 @@
package com.daqing.financial.hrauth.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.daqing.framework.domain.hrms.UserEntity;
import com.daqing.framework.domain.hrms.request.UserLoginRequest;
/**
* @auther River
* @date 2020/9/22 15:00
*/
public interface UserLoginService extends IService<UserEntity> {
Boolean getBackPwd(UserLoginRequest user);
}

@ -0,0 +1,81 @@
package com.daqing.financial.hrauth.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.daqing.financial.hrauth.dao.UserLoginDao;
import com.daqing.financial.hrauth.service.UserLoginService;
import com.daqing.framework.domain.hrms.UserEntity;
import com.daqing.framework.domain.hrms.request.UserLoginRequest;
import com.daqing.framework.domain.hrms.response.HrmsCode;
import com.daqing.framework.exception.ExceptionCast;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @auther River
* @date 2020/9/22 15:01
*/
@Service("userLoginService")
public class UserLoginServiceImpl extends ServiceImpl<UserLoginDao, UserEntity> implements UserLoginService, UserDetailsService {
@Resource
private UserLoginDao userLoginDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserEntity user = userLoginDao.getUser(username);
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
System.out.println(user);
UserDetails userDetails = new User(user.getAccount(),new BCryptPasswordEncoder().encode(user.getPassword()),authorities);
return userDetails;
}
/**
* 忘记密码
*/
@Override
public Boolean getBackPwd(UserLoginRequest user){
//判断重置密码参数是否为空
if(StringUtils.isEmpty(user.getPhoneAccount())){
ExceptionCast.cast(HrmsCode.PHNOE_ACCOUNT_ILLEGAL);
}
if(StringUtils.isEmpty(user.getVerifyCode())){
ExceptionCast.cast(HrmsCode.VERIFY_CODE_ILLEGAL);
}
if(StringUtils.isEmpty(user.getNewPwd())){
ExceptionCast.cast(HrmsCode.NEW_PASSWORD_NOT_EMPTY);
}
//校验手机账号是否存在
int count = this.count(new QueryWrapper<UserEntity>()
.eq("phone_account", user.getPhoneAccount()));
if (count == 0) {
ExceptionCast.cast(HrmsCode.PHNOE_ACCOUNT_ILLEGAL);
}
//判断验证码是否匹配
//密码格式校验
Pattern pattern = Pattern.compile("^[a-zA-Z0-9]{8,20}$");
Matcher match = pattern.matcher(user.getNewPwd());
if(!match.matches()){
ExceptionCast.cast(HrmsCode.NEW_PASSWORD_ILLEGAL);
}
String newMD5 = new BCryptPasswordEncoder().encode(user.getNewPwd());
//根据手机号码修改密码
int i = userLoginDao.updatePasswordByPhoneAccount(user.getPhoneAccount(),newMD5);
return i > 0;
}
}

@ -0,0 +1,19 @@
#<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
spring.application.name=dq-financial-hrms
#<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>ַ
spring.cloud.nacos.config.server-addr=192.168.31.142:8848
spring.cloud.nacos.config.namespace=7632bdaa-3381-4669-b3f9-2fc73be451e8
#spring.cloud.nacos.config.group=prod
spring.cloud.nacos.config.ext-config[0].data-id=datasource.yml
spring.cloud.nacos.config.ext-config[0].group=dev
spring.cloud.nacos.config.ext-config[0].refresh=true
spring.cloud.nacos.config.ext-config[1].data-id=mybatis.yml
spring.cloud.nacos.config.ext-config[1].group=dev
spring.cloud.nacos.config.ext-config[1].refresh=true
spring.cloud.nacos.config.ext-config[2].data-id=other.yml
spring.cloud.nacos.config.ext-config[2].group=dev
spring.cloud.nacos.config.ext-config[2].refresh=true

@ -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.UserLoginDao">
<update id="updatePasswordByPhoneAccount">
update hrms_user set password = #{password} where phone_account = #{phoneAccount}
</update>
<select id="getUser" parameterType="string" resultType="com.daqing.framework.domain.hrms.UserEntity">
SELECT account,password FROM hrms_user WHERE account = #{account}
</select>
<select id="selectCount" resultType="java.lang.Integer">
select count(1) from hrms_user where phone_account = #{phoneAccount}
</select>
</mapper>

@ -61,6 +61,13 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.5.RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<dependencyManagement>

@ -0,0 +1,47 @@
package com.daqing.financial.hrms.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Value("${security.oauth2.client.client-id}")
private String clientId;
@Value("${security.oauth2.client.client-secret}")
private String secret;
@Value("${security.oauth2.authorization.check-token-access}")
private String checkTokenEndpointUrl;
/* @Autowired
private RedisConnectionFactory redisConnectionFactory;*/
/* @Bean
public TokenStore redisTokenStore (){
return new RedisTokenStore(redisConnectionFactory);
}*/
@Bean
public RemoteTokenServices tokenService() {
RemoteTokenServices tokenService = new RemoteTokenServices();
tokenService.setClientId(clientId);
tokenService.setClientSecret(secret);
tokenService.setCheckTokenEndpointUrl(checkTokenEndpointUrl);
return tokenService;
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenServices(tokenService());
}
}

@ -5,6 +5,9 @@ import com.daqing.framework.domain.hrms.UserEntity;
import com.daqing.framework.model.response.ResponseResult;
import com.daqing.framework.utils.PageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
@ -79,4 +82,19 @@ public class UserController {
return ResponseResult.SUCCESS();
}
/**
* 只有当访问用户具有 ROLE_ADMIN 权限时才能访问否则返回 401 未授权
* 通过 Authentication 参数或者 SecurityContextHolder.getContext().getAuthentication() 可以拿到授权信息进行查看
* @param authentication
* @return
*/
@GetMapping(value = "get")
@PreAuthorize("hasAnyRole('ROLE_ADMIN')")
public Object get(Authentication authentication){
//Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
authentication.getCredentials();
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails)authentication.getDetails();
String token = details.getTokenValue();
return token;
}
}

@ -65,7 +65,8 @@
</select>
<select id="pageByCondition" resultMap="employeeMap">
SELECT e.id eid,e.name emp_name,d.name dept_name,u.account,e.job_number,u.create_time,p.name pos_name
SELECT e.id eid,e.name emp_name,d.name
,u.account,e.job_number,u.create_time,p.name pos_name
FROM hrms_employee e
LEFT JOIN hrms_employee_dept ed ON e.id = ed.employee_id
LEFT JOIN hrms_dept d ON d.id = ed.dept_id

@ -3,10 +3,10 @@ package com.daqing.framework.domain.hrms;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
* 人资管理系统员工账号信息表用于存储员工账号密码等登录相关数据
@ -77,5 +77,4 @@ public class UserEntity implements Serializable {
* 更新时间
*/
private Date motifyTime;
}

@ -0,0 +1,34 @@
package com.daqing.framework.domain.hrms.request;
import lombok.Data;
import java.io.Serializable;
/**
* 登录找回密码请求体对象
*
* @author gongsj
* @email gongsj@gmail.com
* @date 2020-09-07 17:12:14
*/
@Data
public class UserLoginRequest implements Serializable {
/**
* 手机账号
*/
private String phoneAccount;
/**A
* 密码
*/
private String password;
/**
* 验证码
*/
private String verifyCode;
/**
* 新密码
*/
private String newPwd;
}

@ -20,8 +20,15 @@ public enum HrmsCode implements ResultCode {
DEPT_LEVEL_ILLEGAL(false, 22003, "部门层级不可超出5级!"),
DEPT_EMP_EXSIT(false, 22004, "请将部门下所有员工移除后再执行删除操作!"),
DEPT_POSITION_EXSIT(false, 22005, "该部门下已存在该职位!"),
PHNOE_ACCOUNT_ILLEGAL(false,33001,"手机号码为空"),
VERIFY_CODE_ILLEGAL(false,33002,"短信验证码为空"),
NEW_PASSWORD_NOT_EMPTY(false,33003,"新密码不能为空"),
NEW_PASSWORD_ILLEGAL(false,33004,"新密码格式不正确"),
EMP_POSITION_EXSIT(false, 22006, "该职位下已关联员工!");
/**
* 操作是否成功
*/

Loading…
Cancel
Save