Commit 239f7354 authored by shangtx's avatar shangtx

chore: admin权限

parent f94d388b
package com.onsiteservice.admin.controller.sys;
import com.onsiteservice.admin.controller.sys.vo.LoginInitVO;
import com.onsiteservice.admin.security.pojo.AccountCredentials;
import com.onsiteservice.common.annotation.user.CurrentUserId;
import com.onsiteservice.core.result.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import static com.onsiteservice.core.result.ResultGenerator.success;
/**
* @author 潘维吉
* @date 2020/3/7 14:19
* @email 406798106@qq.com
* @description 业务控制类
*/
@Api(tags = "登录密码")
@RestController
@RequestMapping
@Validated
public class LoginController {
// @Resource
// private BaseBusinessService baseBusinessService;
@ApiOperation(value = "登录", notes = "作者: 潘维吉。 Spring Security处理, 不配置浏览器会出现CORS跨域问题")
@PostMapping("login")
public AccountCredentials login(@RequestBody AccountCredentials account) {
return account;
}
@ApiOperation(value = "获取菜单、权限、用户", notes = "作者: 潘维吉")
@GetMapping("login/init")
public Result<LoginInitVO> init(@CurrentUserId Long userId) {
return success(/*baseBusinessService.init(userId)*/);
}
}
package com.onsiteservice.admin.controller.sys.vo;
import com.onsiteservice.entity.sys.vo.MenuTreeVO;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.util.List;
/**
* @author 潘维吉
* @date 2020/3/7 14:41
* @email 406798106@qq.com
* @description 登录初始化数据
*/
@Getter
@Setter
@ToString
public class LoginInitVO<T, E> {
/**
* 当前登录用户
*/
private T userInfo;
/**
* 菜单树
*/
private List<MenuTreeVO> menuList;
/**
* 业务操作集合
*/
private List<E> operateList;
}
package com.onsiteservice.admin.security;
import com.onsiteservice.admin.security.authentication.CustomUserDetailsService;
import com.onsiteservice.admin.security.authentication.JwtAuthenticationFilter;
import com.onsiteservice.admin.security.authentication.JwtLoginFilter;
import com.onsiteservice.admin.security.handler.CustomAccessDeniedHandler;
import com.onsiteservice.admin.security.handler.CustomAuthenticationEntryPoint;
import com.onsiteservice.constant.constant.Constants;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
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.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.annotation.Resource;
/**
* 安全权限配置
*/
@Order(2) // 核心core安全配置优先级
@ConditionalOnProperty(prefix = "project.admin-security", name = {"enabled"}, matchIfMissing = true)
@Configuration
@EnableWebSecurity(debug = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Value("${project.jwt.ant-paths}")
private String antPaths;
@Resource
private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
public static void main(String[] args) {
System.out.println(new BCryptPasswordEncoder().encode("123456"));
}
/**
* 用于配置需要拦截的url路径、jwt过滤器及出异常后的处理器
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
String loginPath = Constants.REQUEST_PREFIX + "/login";
http.cors().and() // 开启cors跨域
.csrf().disable() // 禁用csrf 由于使用的是JWT,我们这里不需要csrf
.exceptionHandling()
.authenticationEntryPoint(customAuthenticationEntryPoint) // 自定义401认证异常响应数据 用来解决匿名用户访问无权限资源时的异常
.accessDeniedHandler(accessDeniedHandler()).and() // 自定义403授权异常响应数据 拒绝访问
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() // 基于token 不需要session
.authorizeRequests() // 限定签名成功的请求
.antMatchers(HttpMethod.OPTIONS).permitAll() // 跨域请求会先进行一次options请求
.antMatchers(antPaths.split(",")).permitAll() // 放行不需要认证的url
.antMatchers(HttpMethod.POST, loginPath).permitAll() // 允许POST类型登录接口
//.antMatchers("/**").permitAll() // 测试时全部运行访问
.anyRequest().authenticated() // 除上面外的所有请求全部需要鉴权认证
.and()
// 添加*/login登录请求过滤器
.addFilterBefore(new JwtLoginFilter(loginPath, authenticationManager()), UsernamePasswordAuthenticationFilter.class)
// 过滤其他请求以检查JWT在header中的存在
.addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
@Bean
public UserDetailsService customUserDetailsService() {
return new CustomUserDetailsService();
}
/**
* 用于配置UserDetailsService及PasswordEncode
*/
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService())
.passwordEncoder(passwordEncoder());//对密码的加密处理,如果user中密码没有加密,则可以不加此方法。注意加密请使用security自带的加密方式。
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public AccessDeniedHandler accessDeniedHandler() {
return new CustomAccessDeniedHandler();
}
}
package com.onsiteservice.admin.security;
import com.alibaba.fastjson.JSONObject;
import com.onsiteservice.admin.security.pojo.CustomUserDetails;
import com.onsiteservice.constant.constant.Constants;
import com.onsiteservice.core.security.jwt.JwtManager;
import com.onsiteservice.dao.mapper.sys.SysUserMapper;
import com.onsiteservice.entity.sys.SysUser;
import com.onsiteservice.util.ArrayUtils;
import com.onsiteservice.util.ReflectUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;
import tk.mybatis.mapper.entity.Condition;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
/**
* 具体模块安全通用服务
*/
@Service
@Slf4j
public class SecurityService {
@Resource
private SysUserMapper sysUserMapper;
@Resource
private HttpServletRequest httpServletRequest;
@Value("${project.admin-security.ant-paths}")
private String antPaths;
/**
* 根据用户名获取用户信息
*/
public Object getUserByName(String userName) {
Condition condition = new Condition(SysUser.class);
condition.createCriteria().andEqualTo(JwtManager.USER_NAME, userName);
return sysUserMapper.selectByCondition(condition).stream().findFirst().orElse(null);
}
/**
* 验证权限资源列表中所有权限
*/
public boolean verifyPermissions(HttpServletRequest request, List resourceList) {
if (isIgnorePath(request.getRequestURI())) {
return true;
}
String method;
AntPathRequestMatcher matcher;
if (resourceList != null) {
for (Object item : resourceList) {
String operatePath = ReflectUtils.invokeGetter(item, "operatePath");
String operateMethod = ReflectUtils.invokeGetter(item, "operateMethod");
matcher = new AntPathRequestMatcher(Constants.REQUEST_PREFIX + operatePath);
method = operateMethod == null ? "ALL" : operateMethod.toUpperCase();
if (matcher.matches(request)) {
//当权限表权限的method为ALL时表示拥有此路径的所有请求方式权利
if (method.equals(request.getMethod()) || "ALL".equals(method)) {
return true;
}
}
}
}
return false;
}
/**
* 判断请求资源是否时可忽略权限检查
*/
private boolean isIgnorePath(String path) {
if (antPaths != null) {
for (String pattern : StringUtils.deleteWhitespace(antPaths).split(",")) {
// Ant URL风格匹配
AntPathMatcher antPathMatcher = new AntPathMatcher();
if (antPathMatcher.match(pattern, path)) {
return true;
}
return false;
}
}
return false;
}
}
package com.onsiteservice.admin.security.authentication;
import com.onsiteservice.admin.security.SecurityService;
import com.onsiteservice.admin.security.pojo.CustomUserDetails;
import com.onsiteservice.util.ReflectUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import javax.annotation.Resource;
import java.util.ArrayList;
/**
* @author 潘维吉
* @date 2020/3/5 13:57
* @email 406798106@qq.com
* @description 自定义用户详情服务实现
*/
@Slf4j
public class CustomUserDetailsService implements UserDetailsService {
@Resource
private SecurityService securityService;
/**
* 提供一种从用户名可以查到用户并返回的方法 每次登陆调用
* 用户名attemptAuthentication方法传入
*/
@Override
public UserDetails loadUserByUsername(String userName) {
log.info("2. CustomUserDetailsService.loadUserByUsername");
Object user = securityService.getUserByName(userName);
// 出现异常会在unsuccessfulAuthentication方法处理响应数据
if (ObjectUtils.isEmpty(user)) {
throw new AuthenticationCredentialsNotFoundException("用户名不存在");
}
if (!(Boolean) ReflectUtils.invokeGetter(user, CustomUserDetails.IS_ENABLED)) {
throw new DisabledException("账号已被禁用");
}
return new CustomUserDetails(user, new ArrayList<>());
}
}
package com.onsiteservice.admin.security.authentication;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.onsiteservice.constant.constant.Constants;
import com.onsiteservice.core.security.jwt.JwtManager;
import com.onsiteservice.core.security.jwt.JwtPathProperties;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Collections;
/**
* JWT认证过滤器加入 spring security 管理
*/
@Slf4j
public class JwtAuthenticationFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
Authentication authentication = this.getAuthentication((HttpServletRequest) request);
SecurityContextHolder.getContext().setAuthentication(authentication);
filterChain.doFilter(request, response);
}
/**
* 解析token 从令牌中获取数据声明 除登录外 每次请求都会调用
* 将用户id存到request中 用于注解获取当前用户id
*
* @param request
*/
private Authentication getAuthentication(HttpServletRequest request) {
log.info("4. JwtAuthenticationFilter.getAuthentication");
if (!JwtPathProperties.isAuth(request.getRequestURI())) { // JWT白名单放行
// log.info("JWT白名单放行不认证: {}", request.getRequestURI());
return null;
} else {
try {
String token = request.getHeader(JwtManager.AUTHORIZATION_HEADER);
// 返回401错误
if (StringUtils.isBlank(token)) {
throw new RuntimeException();
}
Claims claims = JwtManager.parseToken(token.replace(JwtManager.BEARER, ""));
if (claims != null) {
JSONObject jsonObject = JSON.parseObject(claims.getSubject());
// 如果token验证成功,将token对应的用户id
Object userId = jsonObject.get(JwtManager.USER_ID);
// 如果token验证成功,将token对应的用户id存在request中,便于之后注入
request.setAttribute(Constants.CURRENT_USER_ID, userId);
// 如果token验证成功,将token对应的用户名
String userName = (String) jsonObject.get(JwtManager.USER_NAME);
if (userName != null) {
return new UsernamePasswordAuthenticationToken(userName, null, Collections.emptyList());
}
}
return null;
} catch (Exception e) {
log.error("从令牌中获取数据声明异常: {}", e.getMessage());
return null;
}
}
}
}
package com.onsiteservice.admin.security.authentication;
import com.alibaba.fastjson.JSON;
import com.onsiteservice.admin.security.pojo.AccountCredentials;
import com.onsiteservice.admin.security.pojo.CustomUserDetails;
import com.onsiteservice.admin.security.pojo.TokenTimeProperties;
import com.onsiteservice.admin.security.pojo.TokenVO;
import com.onsiteservice.core.config.MvcConfig;
import com.onsiteservice.core.result.Result;
import com.onsiteservice.core.security.jwt.JwtManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
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 javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import static com.onsiteservice.core.result.ResultGenerator.failCustom;
import static com.onsiteservice.core.result.ResultGenerator.success;
import static org.springframework.http.HttpStatus.UNAUTHORIZED;
/**
* @author 潘维吉
* @date 2020/3/6 10:03
* @email 406798106@qq.com
* @description 将JWT添加到我们的身份验证过程
*/
@Slf4j
public class JwtLoginFilter extends AbstractAuthenticationProcessingFilter {
public JwtLoginFilter(String url, AuthenticationManager authManager) {
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authManager);
}
/**
* 首先过滤器会调用自身的attemptAuthentication方法,从request中取出authentication,
* authentication是在SecurityContextPersistenceFilter过滤器中通过捕获用户提交的登录表单中的内容生成的一个Authentication接口实例
* 拿到authentication对象后,过滤器会调用authenticate认证授权方法,并传入该对象
*/
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException {
log.info("1. JwtLoginFilter.attemptAuthentication");
AccountCredentials account = JSON.parseObject(request.getInputStream(), AccountCredentials.class);
request.setAttribute("rememberMe", account.getRememberMe());
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
account.getUserName(), account.getPassword(), Collections.emptyList());
return getAuthenticationManager().authenticate(token);
}
/**
* 认证成功 响应数据
*/
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication auth) {
log.info("3. JwtLoginFilter.successfulAuthentication");
Object rmObj = request.getAttribute("rememberMe");
boolean rememberMe = rmObj != null && (Boolean) rmObj;
// Authentication 中包含 loadUserByUsername() 方法返回的自定义的用户数据信息
String userName = auth.getName();
Long userId = ((CustomUserDetails) auth.getPrincipal()).getUserId();
// 生成token 返回给前端
String token = JwtManager.createToken(Map.of(JwtManager.USER_ID, userId, JwtManager.USER_NAME, userName),
rememberMe ? TokenTimeProperties.rememberExpiresTime : TokenTimeProperties.expiresTime);
Result result = success(TokenVO.builder().token(token)
.expiresTime(rememberMe ? TokenTimeProperties.rememberExpiresTime : TokenTimeProperties.expiresTime).build(), "登录成功");
MvcConfig.responseResult(response, result);
}
/**
* 认证失败 响应数据
*/
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) {
log.info("3. JwtLoginFilter.unsuccessfulAuthentication");
exception.printStackTrace();
String msg = (exception instanceof InternalAuthenticationServiceException) ?
exception.getMessage() : "用户名或密码错误";
Result result = failCustom(UNAUTHORIZED.value(), msg);
MvcConfig.responseResult(response, result);
}
}
package com.onsiteservice.admin.security.handler;
import com.onsiteservice.core.config.MvcConfig;
import com.onsiteservice.core.result.Result;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import static com.onsiteservice.core.result.ResultGenerator.failCustom;
import static org.springframework.http.HttpStatus.FORBIDDEN;
/**
* @author 潘维吉
* @date 2020/3/7 10:29
* @email 406798106@qq.com
* @description 自定义返异常回信息 当用户没有访问权限时的处理器
*/
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) {
Result result = failCustom(FORBIDDEN.value(), "拒绝访问");
MvcConfig.responseResult(response, result);
}
}
package com.onsiteservice.admin.security.handler;
import com.onsiteservice.core.config.MvcConfig;
import com.onsiteservice.core.result.Result;
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;
import static com.onsiteservice.core.result.ResultGenerator.failCustom;
import static org.springframework.http.HttpStatus.UNAUTHORIZED;
/**
* @author 潘维吉
* @date 2020/3/5 16:22
* @email 406798106@qq.com
* @description 未通过认证的用户请求受保护资源时调用 用来解决匿名用户访问无权限资源时的异常
* 当未登录或者token失效访问接口时,自定义的返回结果
*/
@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) {
// 当用户试图在不提供任何凭据的情况下访问受保护的REST资源时,将调用此方法
// 我们应该发送一个未经认证的401响应,因为没有“登录页面”可以重定向到
Result result = failCustom(UNAUTHORIZED.value(), "没有访问权限");
MvcConfig.responseResult(response, result);
}
}
package com.onsiteservice.admin.security.pojo;
import lombok.Getter;
import lombok.Setter;
/**
* @author 潘维吉
* @date 2020/3/6 10:07
* @email 406798106@qq.com
* @description 前端登录请求数据
*/
@Getter
@Setter
public class AccountCredentials {
private String userName;
private String password;
private Boolean rememberMe;
}
package com.onsiteservice.admin.security.pojo;
import com.onsiteservice.util.ReflectUtils;
import lombok.Getter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import java.util.Collection;
/**
* @author 潘维吉
* @date 2020/3/5 13:57
* @email 406798106@qq.com
* @description 自定义用户信息 用于直接返回更多数据给前端 用户信息和权限
*/
@Getter
public class CustomUserDetails extends User {
/**
* 业务系统自定义用户实体属性 根据业务命名定义修改
*/
public static final String ID = "id";
public static final String COMPANY_ID = "companyId";
public static final String USERNAME = "userName";
public static final String REAL_NAME = "realName";
public static final String PASSWORD = "password";
public static final String AVATAR = "avatarUrl";
public static final String IS_ENABLED = "isEnabled";
public static final String IS_GOD = "isGod";
public static final String IS_SUPER_GOD = "isSuperGod";
private static final long serialVersionUID = 1167013428315310807L;
private Long userId;
private Long companyId;
private String realName;
private String avatarUrl;
//private List permissionList;
public CustomUserDetails(String username, String password, Collection<? extends GrantedAuthority> authorities) {
super(username, password, authorities);
}
public CustomUserDetails(Object user, Collection<? extends GrantedAuthority> authorities) {
super(ReflectUtils.invokeGetter(user, USERNAME), ReflectUtils.invokeGetter(user, PASSWORD), authorities);
this.userId = ReflectUtils.invokeGetter(user, ID);
this.companyId = ReflectUtils.invokeGetter(user, COMPANY_ID);
this.realName = ReflectUtils.invokeGetter(user, REAL_NAME);
this.avatarUrl = ReflectUtils.invokeGetter(user, AVATAR);
}
public CustomUserDetails(String username, String password, boolean enabled, boolean accountNonExpired,
boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
}
}
package com.onsiteservice.admin.security.pojo;
/**
* @author 潘维吉
* @date 2020/3/6 16:52
* @email 406798106@qq.com
* @description 过滤器中获取配置参数
*/
public class TokenTimeProperties {
/**
* 默认token有效时间 秒
*/
public static long expiresTime = 172800;
/**
* 使用记住我模式token有效时间 秒
*/
public static long rememberExpiresTime = 864000;
}
package com.onsiteservice.admin.security.pojo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* @author 潘维吉
* @date 2020/1/15 15:41
* @email 406798106@qq.com
* @description 令牌VO
*/
@ApiModel(description = "Token接口响应数据")
@Builder
@Getter
@Setter
@ToString
public class TokenVO {
/**
* 令牌Token
*/
@ApiModelProperty("令牌Token")
private String token;
/**
* Token过期时间
*/
@ApiModelProperty(value = "Token过期时间(秒)", example = "-1")
private Long expiresTime;
}
......@@ -2,4 +2,4 @@
spring:
profiles:
include:
- common-dev
- common-dev
\ No newline at end of file
# 生产环境配置
spring:
profiles:
include:
- common-prod
#
#logging:
# config: classpath:logback-spring-prod.xml
project:
swagger:
enabled: false
# 联调环境配置
spring:
profiles:
include:
- common-sit
# 测试环境配置
spring:
profiles:
include:
- common-test
......@@ -26,5 +26,4 @@ spring:
include:
- common
application:
name: onsite-service-admin
name: onsite-service-admin
\ No newline at end of file
......@@ -3,6 +3,7 @@ package com.onsiteservice.admin;
import org.jasypt.encryption.StringEncryptor;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.password.PasswordEncoder;
import javax.annotation.Resource;
......@@ -17,4 +18,11 @@ public class JasyptTest {
String password = encryptor.encrypt("antaikeji2022");
System.out.println(password);
}
@Resource
private PasswordEncoder passwordEncoder;
@Test
void password() {
System.out.println(passwordEncoder.encode("123"));
}
}
......@@ -148,10 +148,10 @@
</dependency>-->
<!--微信公众号-->
<dependency>
<!-- <dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java-mp-spring-boot-starter</artifactId>
</dependency>
</dependency>-->
<!--微信支付-->
<dependency>
<groupId>com.github.binarywang</groupId>
......
......@@ -43,7 +43,7 @@ public class RateLimiterAspect {
*/
private Map<String, RateLimiter> limitMap = Maps.newConcurrentMap();
@Pointcut("@annotation(com.monorepo.common.annotation.limit.RateLimit)")
@Pointcut("@annotation(com.onsiteservice.common.annotation.limit.RateLimit)")
public void rateLimit() {
}
......
......@@ -24,7 +24,7 @@ import java.util.Objects;
@Component
public class UniqueCheckAspect {
@Pointcut("@annotation(com.monorepo.common.annotation.validation.Unique)")
@Pointcut("@annotation(com.onsiteservice.common.annotation.validation.Unique)")
public void unique() {
}
......
......@@ -28,7 +28,7 @@ public class ServiceLogAspect {
* @return 切入点返回值
* @throws Throwable 异常信息
*/
@Around("@within(com.monorepo.common.log.ServiceLog) ||@annotation(com.monorepo.common.log.ServiceLog)")
@Around("@within(com.onsiteservice.common.log.ServiceLog) ||@annotation(com.onsiteservice.common.log.ServiceLog)")
public Object doServiceLog(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
// 拦截的实体类
......
......@@ -8,7 +8,7 @@ spring:
datasource:
url: jdbc:mysql://39.96.84.51:3306/onsite_service_dev${project.mysql-url-params}
username: onsite_service
password: ENC(dQhwSeQ6J1uCCW5zK8eBzFyES4nW0xw3)
password: ENC(oHHR1aTYVkDAYpWjQk2rD0qIqDId4m0l)
redis:
database: 8
......
# 通用prod配置
server:
# tomcat的ssl证书配置 启用https和http2 走nginx代理 nginx ssl配置即可
# http2:
# enabled: true
# ssl:
# key-store: classpath:app-api.com.pfx
# key-store-password:
# key-store-type: PKCS12
spring:
profiles:
include:
- third-service-prod
- aliyun-sms-prod
# 数据源配置
datasource:
url: jdbc:mysql://172.21.7.176:3306/wellness_unblocked${project.mysql-url-params}
username: wellness_unblocked
password: ENC(nNSzGODQTtkxJ9Rk9i2pngwzs+m+2wncypMAJ+HREg8=)
hikari:
# 池中维护的最小空闲连接数 默认10
minimum-idle: 10
# 池中最大连接数,包括闲置和使用中的连接 默认10
maximum-pool-size: 200
# 一个连接的生命时长(毫秒),超时而且没被使用则被释放(retired),缺省:30分钟
max-lifetime: 600000
# 一个连接idle状态的最大时长(毫秒),空闲连接数超过minimumIdle,而且空闲时间超过idleTimeout,则会被移除 缺省:10分钟
idle-timeout: 60000
# 等待连接池分配连接的最大时长(毫秒),超过这个时长还没可用的连接则发生SQLException, 缺省:30秒
connection-timeout: 30000
connection-test-query: SELECT 1
redis:
database: 1
# Redis服务器地址
host: 172.21.7.176
password: antaikeji2020
rabbitmq:
host: 172.21.7.176
username: root
password: antaikeji2020
## 开启Swagger的Basic认证功能
knife4j:
basic:
enable: true
username: monorepo
password: antaikeji666
# 日志配置 默认仅在控制台打印log信息 将log信息记录到文件 指定logging.file或logging.path 日志文件在10Mb大小被截断,产生新的日志文件
logging:
level:
root: error
file:
path: ./logs
logback:
rollingpolicy:
max-file-size: 20
max-history: 3
# config: classpath:logback-spring.xml # 自定义更详细的日志规则
# 通用sit联调配置
spring:
profiles:
include:
- third-service-sit
- aliyun-sms-dev
# 数据源配置
datasource:
url: jdbc:mysql://39.96.84.51:3306/wellness_unblocked_dev${project.mysql-url-params}
username: wellness_unblocked
password: ENC(dQhwSeQ6J1uCCW5zK8eBzFyES4nW0xw3)
jpa:
show-sql: true
open-in-view: false
redis:
database: 3
# 通用test配置
spring:
profiles:
include:
- third-service-test
- aliyun-sms-dev
# 数据源配置
datasource:
url: jdbc:mysql://39.96.84.51:3306/wellness_unblocked_dev${project.mysql-url-params}
username: wellness_unblocked
password: ENC(dQhwSeQ6J1uCCW5zK8eBzFyES4nW0xw3)
hikari:
# 池中维护的最小空闲连接数 默认10
minimum-idle: 10
# 池中最大连接数,包括闲置和使用中的连接 默认10
maximum-pool-size: 30
connection-timeout: 30000
connection-test-query: SELECT 1
redis:
database: 4
......@@ -24,7 +24,7 @@ spring:
use-legacy-processing: true
profiles:
include:
- onsite-service-third-service
- third-service
# 默认dev开发模式配置 prod生产模式配置java -jar xxx.jar --spring.profiles.active=prod
active: dev
......
# 第三方服务prod配置
# 阿里云配置
aliyun:
access-key-id: LTAI5t5ivKZ3B2QPpyjVrg6Q
access-key-secret: btTTn9rQvh61e4Q327hdOLliXLlj9l
oss:
enabled: true
endpoint: https://oss-cn-beijing.aliyuncs.com
bucket-name: wellness-unblocked-production
cdn-url: https://wellness-unblocked-production.oss-cn-beijing.aliyuncs.com/
default-avatar: https://health-base.oss-cn-beijing.aliyuncs.com/default-avatar.png
sms:
enabled: true
sign: 国济物业护护通
region-id: cn-beijing
time-out: 1000
batch-size: 500 # 批量发送个数
......@@ -23,9 +23,11 @@ aliyun:
# 微信配置
wx:
mappid: wxdc9fe9e7aaeddac4
appid: wxa56f0845ca456bac
# 微信支付
pay:
appId: ${wx.miniapp.appid} #微信公众号或者小程序等的appid
appId: wxa56f0845ca456bac #微信公众号或者小程序等的appid
mchId: 1602411974 #微信支付商户号
package com.onsiteservice.dao.common.schedule;/*
package com.monorepo.dao.common.schedule;
import net.javacrumbs.shedlock.core.LockProvider;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment