🔖 Releasing / Version tags. 2.6.2

This commit is contained in:
冷冷 2020-01-01 19:15:23 +08:00
parent 604b6ee928
commit 3b124cee31
34 changed files with 447 additions and 365 deletions

View File

@ -33,10 +33,10 @@
依赖 | 版本
---|---
Spring Boot | 2.2.2.RELEASE
Spring Cloud | Hoxton.RELEASE
Spring Cloud | Hoxton.SR1
Spring Security OAuth2 | 2.3.6
Mybatis Plus | 3.3.0
hutool | 5.0.6
hutool | 5.1.0
Avue | 2.2.0

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</parent>
<artifactId>pig-auth</artifactId>
@ -44,53 +44,34 @@
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-upms-api</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</dependency>
<!--security-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-security</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</dependency>
<!--JDBC相关-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--freemarker-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!--spring security 、oauth、jwt依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
<exclusions>
<!--旧版本 redis操作有问题-->
<exclusion>
<artifactId>spring-security-oauth2</artifactId>
<groupId>org.springframework.security.oauth</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>${security.oauth.version}</version>
</dependency>
<!--数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--web 模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!--排除tomcat依赖-->
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@ -16,6 +16,7 @@
package com.pig4cloud.pig.auth.config;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import com.pig4cloud.pig.common.core.constant.SecurityConstants;
import com.pig4cloud.pig.common.security.component.PigWebResponseExceptionTranslator;
import com.pig4cloud.pig.common.security.service.PigClientDetailsService;
@ -81,14 +82,14 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
.userDetailsService(userDetailsService)
.authenticationManager(authenticationManager)
.reuseRefreshTokens(false)
.pathMapping("/oauth/confirm_access", "/token/confirm_access")
.exceptionTranslator(new PigWebResponseExceptionTranslator());
}
@Bean
public TokenStore tokenStore() {
RedisTokenStore tokenStore = new RedisTokenStore(redisConnectionFactory);
tokenStore.setPrefix(SecurityConstants.PROJECT_PREFIX + SecurityConstants.OAUTH_PREFIX);
tokenStore.setPrefix(CacheConstants.PROJECT_OAUTH_ACCESS);
return tokenStore;
}

View File

@ -16,13 +16,10 @@
package com.pig4cloud.pig.auth.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pig4cloud.pig.common.security.handler.MobileLoginSuccessHandler;
import com.pig4cloud.pig.common.security.handler.FormAuthenticationFailureHandler;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
@ -30,9 +27,7 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
/**
* @author lengleng
@ -43,22 +38,21 @@ import org.springframework.security.web.authentication.AuthenticationSuccessHand
@Order(90)
@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Autowired
private ObjectMapper objectMapper;
@Autowired
private ClientDetailsService clientDetailsService;
@Lazy
@Autowired
private AuthorizationServerTokenServices defaultAuthorizationServerTokenServices;
@Override
@SneakyThrows
protected void configure(HttpSecurity http) {
http
.formLogin()
.loginPage("/token/login")
.loginProcessingUrl("/token/form")
.failureHandler(authenticationFailureHandler())
.and()
.authorizeRequests()
.antMatchers(
"/token/**",
"/actuator/**",
"/token/**").permitAll()
"/mobile/**").permitAll()
.anyRequest().authenticated()
.and().csrf().disable();
}
@ -71,15 +65,10 @@ public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
}
@Bean
public AuthenticationSuccessHandler mobileLoginSuccessHandler() {
return MobileLoginSuccessHandler.builder()
.objectMapper(objectMapper)
.clientDetailsService(clientDetailsService)
.passwordEncoder(passwordEncoder())
.defaultAuthorizationServerTokenServices(defaultAuthorizationServerTokenServices).build();
public AuthenticationFailureHandler authenticationFailureHandler() {
return new FormAuthenticationFailureHandler();
}
/**
* https://spring.io/blog/2017/11/01/spring-security-5-0-0-rc1-released#password-storage-updated
* Encoded password does not look like BCrypt

View File

@ -19,30 +19,37 @@ package com.pig4cloud.pig.auth.endpoint;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import com.pig4cloud.pig.common.core.constant.CommonConstants;
import com.pig4cloud.pig.common.core.constant.SecurityConstants;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.security.service.PigUser;
import com.pig4cloud.pig.common.security.annotation.Inner;
import com.pig4cloud.pig.common.security.util.SecurityUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.CacheManager;
import org.springframework.data.redis.core.ConvertingCursor;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.common.util.OAuth2Utils;
import org.springframework.security.oauth2.provider.AuthorizationRequest;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -51,15 +58,55 @@ import java.util.Map;
* @date 2019/2/1
* 删除token端点
*/
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/token")
public class PigTokenEndpoint {
private static final String PROJECT_OAUTH_ACCESS = SecurityConstants.PROJECT_PREFIX + SecurityConstants.OAUTH_PREFIX + "access:";
private static final String CURRENT = "current";
private static final String SIZE = "size";
private final ClientDetailsService clientDetailsService;
private final TokenStore tokenStore;
private final RedisTemplate redisTemplate;
private final CacheManager cacheManager;
/**
* 认证页面
*
* @param modelAndView
* @param error 表单登录失败处理回调的错误信息
* @return ModelAndView
*/
@GetMapping("/login")
public ModelAndView require(ModelAndView modelAndView, @RequestParam(required = false) String error) {
modelAndView.setViewName("ftl/login");
modelAndView.addObject("error", error);
return modelAndView;
}
/**
* 确认授权页面
*
* @param request
* @param session
* @param modelAndView
* @return
*/
@GetMapping("/confirm_access")
public ModelAndView confirm(HttpServletRequest request, HttpSession session, ModelAndView modelAndView) {
Map<String, Object> scopeList = (Map<String, Object>) request.getAttribute("scopes");
modelAndView.addObject("scopeList", scopeList.keySet());
Object auth = session.getAttribute("authorizationRequest");
if (auth != null) {
AuthorizationRequest authorizationRequest = (AuthorizationRequest) auth;
ClientDetails clientDetails = clientDetailsService.loadClientByClientId(authorizationRequest.getClientId());
modelAndView.addObject("app", clientDetails.getAdditionalInformation());
modelAndView.addObject("user", SecurityUtils.getUser());
}
modelAndView.setViewName("ftl/confirm");
return modelAndView;
}
/**
* 退出并删除token
@ -75,13 +122,21 @@ public class PigTokenEndpoint {
String tokenValue = authHeader.replace(OAuth2AccessToken.BEARER_TYPE, StrUtil.EMPTY).trim();
OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
if (accessToken == null || StrUtil.isBlank(accessToken.getValue())) {
return R.ok();
return R.ok(Boolean.TRUE, "退出失败token 无效");
}
OAuth2Authentication auth2Authentication = tokenStore.readAuthentication(accessToken);
// 清空用户信息
cacheManager.getCache(CacheConstants.USER_DETAILS)
.evict(auth2Authentication.getName());
// 清空access token
tokenStore.removeAccessToken(accessToken);
// 清空 refresh token
OAuth2RefreshToken refreshToken = accessToken.getRefreshToken();
tokenStore.removeRefreshToken(refreshToken);
return R.ok();
return R.ok(Boolean.TRUE);
}
/**
@ -90,12 +145,10 @@ public class PigTokenEndpoint {
* @param token token
* @param from 内部调用标志
*/
@Inner
@DeleteMapping("/{token}")
public R<Boolean> removeToken(@PathVariable("token") String token, @RequestHeader(required = false) String from) {
if (StrUtil.isBlank(from)) {
return null;
}
return R.ok(redisTemplate.delete(PROJECT_OAUTH_ACCESS + token));
public R<Boolean> removeToken(@PathVariable("token") String token) {
return R.ok(redisTemplate.delete(CacheConstants.PROJECT_OAUTH_ACCESS + token));
}
@ -103,68 +156,28 @@ public class PigTokenEndpoint {
* 查询token
*
* @param params 分页参数
* @param from 标志
* @return
*/
@Inner
@PostMapping("/page")
public R getTokenPage(@RequestBody Map<String, Object> params, @RequestHeader(required = false) String from) {
if (StrUtil.isBlank(from)) {
return null;
}
List<Map<String, String>> list = new ArrayList<>();
if (StringUtils.isEmpty(MapUtil.getInt(params, CURRENT)) || StringUtils.isEmpty(MapUtil.getInt(params, SIZE))) {
params.put(CURRENT, 1);
params.put(SIZE, 20);
}
public R<Page> tokenList(@RequestBody Map<String, Object> params) {
//根据分页参数获取对应数据
List<String> pages = findKeysForPage(PROJECT_OAUTH_ACCESS + "*", MapUtil.getInt(params, CURRENT), MapUtil.getInt(params, SIZE));
List<String> pages = findKeysForPage(CacheConstants.PROJECT_OAUTH_ACCESS
, MapUtil.getInt(params, CommonConstants.CURRENT)
, MapUtil.getInt(params, CommonConstants.SIZE));
for (String page : pages) {
String accessToken = StrUtil.subAfter(page, PROJECT_OAUTH_ACCESS, true);
OAuth2AccessToken token = tokenStore.readAccessToken(accessToken);
Map<String, String> map = new HashMap<>(8);
map.put(OAuth2AccessToken.TOKEN_TYPE, token.getTokenType());
map.put(OAuth2AccessToken.ACCESS_TOKEN, token.getValue());
map.put(OAuth2AccessToken.EXPIRES_IN, token.getExpiresIn() + "");
OAuth2Authentication oAuth2Auth = tokenStore.readAuthentication(token);
Authentication authentication = oAuth2Auth.getUserAuthentication();
map.put(OAuth2Utils.CLIENT_ID, oAuth2Auth.getOAuth2Request().getClientId());
map.put(OAuth2Utils.GRANT_TYPE, oAuth2Auth.getOAuth2Request().getGrantType());
if (authentication instanceof UsernamePasswordAuthenticationToken) {
UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) authentication;
if (authenticationToken.getPrincipal() instanceof PigUser) {
PigUser user = (PigUser) authenticationToken.getPrincipal();
map.put("user_id", user.getId() + "");
map.put("username", user.getUsername() + "");
}
} else if (authentication instanceof PreAuthenticatedAuthenticationToken) {
//刷新token方式
PreAuthenticatedAuthenticationToken authenticationToken = (PreAuthenticatedAuthenticationToken) authentication;
if (authenticationToken.getPrincipal() instanceof PigUser) {
PigUser user = (PigUser) authenticationToken.getPrincipal();
map.put("user_id", user.getId() + "");
map.put("username", user.getUsername() + "");
}
}
list.add(map);
}
Page result = new Page(MapUtil.getInt(params, CURRENT), MapUtil.getInt(params, SIZE));
result.setRecords(list);
result.setTotal(Long.valueOf(redisTemplate.keys(PROJECT_OAUTH_ACCESS + "*").size()));
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
Page result = new Page(MapUtil.getInt(params, CommonConstants.CURRENT), MapUtil.getInt(params, CommonConstants.SIZE));
result.setRecords(redisTemplate.opsForValue().multiGet(pages));
result.setTotal((long) redisTemplate.keys(CacheConstants.PROJECT_OAUTH_ACCESS).size());
return R.ok(result);
}
private List<String> findKeysForPage(String patternKey, int pageNum, int pageSize) {
ScanOptions options = ScanOptions.scanOptions().match(patternKey).build();
ScanOptions options = ScanOptions.scanOptions().count(1000L)
.match(patternKey).build();
RedisSerializer<String> redisSerializer = (RedisSerializer<String>) redisTemplate.getKeySerializer();
Cursor cursor = (Cursor) redisTemplate.executeWithStickyConnection(redisConnection -> new ConvertingCursor<>(redisConnection.scan(options), redisSerializer::deserialize));
List<String> result = new ArrayList<>();
@ -185,6 +198,12 @@ public class PigTokenEndpoint {
tmpIndex++;
cursor.next();
}
try {
cursor.close();
} catch (IOException e) {
log.error("关闭cursor 失败");
}
return result;
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
.sign_body {
padding-top: 40px;
padding-bottom: 40px;
background-color: #eee;
}
.form-signin {
max-width: 330px;
padding: 15px;
margin: 0 auto;
}
.form-margin-top {
margin-top: 50px;
}
.form-signin .form-signin-heading,
.form-signin .checkbox {
margin-bottom: 10px;
}
.form-signin .checkbox {
font-weight: normal;
}
.form-signin .form-control {
position: relative;
height: auto;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 10px;
font-size: 16px;
}
.form-signin .form-control:focus {
z-index: 2;
}
.form-signin input[type="email"] {
margin-bottom: -1px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.form-signin input[type="password"] {
margin-bottom: 10px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
footer{
text-align: center;
position:absolute;
bottom:0;
width:100%;
height:100px;
}

View File

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<html>
<head>
<meta charset="UTF-8"/>
<meta name="viewport"
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>
<title>PigX第三方授权</title>
<link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css"/>
<link rel="stylesheet" type="text/css" href="/static/css/signin.css"/>
</head>
<body>
<nav class="navbar navbar-default container-fluid">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">开放平台</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-5">
<p class="navbar-text navbar-right">
<a target="_blank" href="https://pig4cloud.com">技术支持</a>
</p>
<p class="navbar-text navbar-right">
<a target="_blank" href="https://pig4cloud.com">${user.username}</a>
</p>
</div>
</div>
</nav>
<div style="padding-top: 80px;width: 300px; color: #555; margin:0px auto;">
<form id='confirmationForm' name='confirmationForm' action="/oauth/authorize" method='post'>
<input name='user_oauth_approval' value='true' type='hidden'/>
<p>
<a href="${app.website!''}" target="_blank">${app.appName!'未定义应用名称'}</a> 将获得以下权限:</p>
<ul class="list-group">
<li class="list-group-item"> <span>
<#list scopeList as scope>
<input type="hidden" name="${scope}" value="true"/>
<input type="checkbox" disabled checked="checked"/><label>${scope}</label>
</#list>
</ul>
<p class="help-block">授权后表明你已同意 <a>服务协议</a></p>
<button class="btn btn-success pull-right" type="submit" id="write-email-btn">授权</button>
</p>
</form>
</div>
<footer>
<p>support by: pig4cloud.com</p>
<p>email: <a href="mailto:wangiegie@gmail.com">wangiegie@gmail.com</a>.</p>
</footer>
</body>
</html>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="">
<meta name="author" content="">
<title>PigX微服务统一认证</title>
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/css/signin.css" rel="stylesheet">
</head>
<body class="sign_body">
<div class="container form-margin-top">
<form class="form-signin" action="/token/form" method="post">
<h2 class="form-signin-heading" align="center">统一认证系统</h2>
<input type="text" name="username" class="form-control form-margin-top" placeholder="账号" required autofocus>
<input type="password" name="password" class="form-control" placeholder="密码" required>
<button class="btn btn-lg btn-primary btn-block" type="submit">sign in</button>
<#if error??>
<span style="color: red; ">${error}</span>
</#if>
</form>
</div>
<footer>
<p>support by: pig4cloud</p>
<p>email: <a href="mailto:pig4cloud@qq.com">pig4cloud@qq.com</a>.</p>
</footer>
</body>
</html>

View File

@ -22,7 +22,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</parent>
<artifactId>pig-codegen</artifactId>
@ -35,7 +35,7 @@
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-swagger</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</dependency>
<!--注册中心客户端-->
<dependency>
@ -61,13 +61,13 @@
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-core</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</dependency>
<!--安全模块-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-security</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</dependency>
<!--代码生成模板引擎-->
<dependency>
@ -75,18 +75,6 @@
<groupId>org.apache.velocity</groupId>
<version>${velocity.version}</version>
</dependency>
<!--web 模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!--排除tomcat依赖-->
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</parent>
<artifactId>pig-common-core</artifactId>

View File

@ -0,0 +1,48 @@
package com.pig4cloud.pig.common.core.constant;
/**
* @author lengleng
* @date 2020年01月01日
* <p>
* 缓存的key 常量
*/
public interface CacheConstants {
/**
* oauth 缓存前缀
*/
String PROJECT_OAUTH_ACCESS = "pig_oauth:access:";
/**
* 验证码前缀
*/
String DEFAULT_CODE_KEY = "DEFAULT_CODE_KEY:";
/**
* 菜单信息缓存
*/
String MENU_DETAILS = "menu_details";
/**
* 用户信息缓存
*/
String USER_DETAILS = "user_details";
/**
* 字典信息缓存
*/
String DICT_DETAILS = "dict_details";
/**
* oauth 客户端信息
*/
String CLIENT_DETAILS_KEY = "pig_oauth:client:details";
/**
* 参数缓存
*/
String PARAMS_DETAILS = "params_details";
}

View File

@ -73,4 +73,14 @@ public interface CommonConstants {
* 验证码前缀
*/
String DEFAULT_CODE_KEY = "DEFAULT_CODE_KEY_";
/**
* 当前页
*/
String CURRENT = "current";
/**
* size
*/
String SIZE = "size";
}

View File

@ -30,10 +30,6 @@ public interface SecurityConstants {
*/
String PROJECT_PREFIX = "pig_";
/**
* oauth 相关前缀
*/
String OAUTH_PREFIX = "oauth:";
/**
* 项目的license
*/
@ -49,10 +45,6 @@ public interface SecurityConstants {
*/
String FROM = "from";
/**
* 手机号登录URL
*/
String MOBILE_TOKEN_URL = "/mobile/token";
/**
* 默认登录URL
@ -64,11 +56,6 @@ public interface SecurityConstants {
*/
String REFRESH_TOKEN = "refresh_token";
/**
* oauth 客户端信息
*/
String CLIENT_DETAILS_KEY = PROJECT_PREFIX + OAUTH_PREFIX + "client:details";
/**
* {bcrypt} 加密的特征码
*/

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</parent>
<artifactId>pig-common-log</artifactId>
@ -35,13 +35,13 @@
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-core</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</dependency>
<!--UPMS接口模块-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-upms-api</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</dependency>
<!--安全依赖获取上下文信息-->
<dependency>

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</parent>
<artifactId>pig-common-security</artifactId>
@ -35,7 +35,7 @@
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-core</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</dependency>
<!--安全模块-->
<dependency>
@ -50,7 +50,7 @@
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-upms-api</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.common.security.handler;
import cn.hutool.http.HttpUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.Charset;
/**
* @author lengleng
* @date 2019-08-20
* <p>
* 表单登录失败处理逻辑
*/
@Slf4j
public class FormAuthenticationFailureHandler implements AuthenticationFailureHandler {
/**
* Called when an authentication attempt fails.
*
* @param request the request during which the authentication attempt occurred.
* @param response the response.
* @param exception the exception which was thrown to reject the authentication
*/
@Override
@SneakyThrows
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) {
log.debug("表单登录失败:{}", exception.getLocalizedMessage());
response.sendRedirect(String.format("/token/login?error=%s"
, HttpUtil.encodeParams(exception.getMessage(), Charset.defaultCharset())));
}
}

View File

@ -1,105 +0,0 @@
/*
* Copyright (c) 2019-2020, 冷冷 (wangiegie@gmail.com).
* <p>
* Licensed under the GNU Lesser General Public License 3.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pig4cloud.pig.common.security.handler;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.CharsetUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pig4cloud.pig.common.core.constant.CommonConstants;
import com.pig4cloud.pig.common.security.util.AuthUtils;
import lombok.Builder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
import org.springframework.security.oauth2.common.exceptions.UnapprovedClientAuthenticationException;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestValidator;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author lengleng
* @date 2019/2/1
* 手机号登录成功返回oauth token
*/
@Slf4j
@Builder
public class MobileLoginSuccessHandler implements AuthenticationSuccessHandler {
private static final String BASIC_ = "Basic ";
private ObjectMapper objectMapper;
private PasswordEncoder passwordEncoder;
private ClientDetailsService clientDetailsService;
private AuthorizationServerTokenServices defaultAuthorizationServerTokenServices;
/**
* Called when a user has been successfully authenticated.
* 调用spring security oauth API 生成 oAuth2AccessToken
*
* @param request the request which caused the successful authentication
* @param response the response
* @param authentication the <tt>Authentication</tt> object which was created during
*/
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
String header = request.getHeader(HttpHeaders.AUTHORIZATION);
if (header == null || !header.startsWith(BASIC_)) {
throw new UnapprovedClientAuthenticationException("请求头中client信息为空");
}
try {
String[] tokens = AuthUtils.extractAndDecodeHeader(header);
assert tokens.length == 2;
String clientId = tokens[0];
ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
//校验secret
if (!passwordEncoder.matches(tokens[1], clientDetails.getClientSecret())) {
throw new InvalidClientException("Given client ID does not match authenticated client");
}
TokenRequest tokenRequest = new TokenRequest(MapUtil.newHashMap(), clientId, clientDetails.getScope(), "mobile");
//校验scope
new DefaultOAuth2RequestValidator().validateScope(tokenRequest, clientDetails);
OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);
OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
OAuth2AccessToken oAuth2AccessToken = defaultAuthorizationServerTokenServices.createAccessToken(oAuth2Authentication);
log.info("获取token 成功:{}", oAuth2AccessToken.getValue());
response.setCharacterEncoding(CharsetUtil.UTF_8);
response.setContentType(CommonConstants.CONTENT_TYPE);
PrintWriter printWriter = response.getWriter();
printWriter.append(objectMapper.writeValueAsString(oAuth2AccessToken));
} catch (IOException e) {
throw new BadCredentialsException(
"Failed to decode basic authentication token");
}
}
}

View File

@ -16,10 +16,9 @@
package com.pig4cloud.pig.common.security.service;
import com.pig4cloud.pig.common.core.constant.SecurityConstants;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import lombok.SneakyThrows;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
@ -45,7 +44,7 @@ public class PigClientDetailsService extends JdbcClientDetailsService {
*/
@Override
@SneakyThrows
@Cacheable(value = SecurityConstants.CLIENT_DETAILS_KEY, key = "#clientId", unless = "#result == null")
@Cacheable(value = CacheConstants.CLIENT_DETAILS_KEY, key = "#clientId", unless = "#result == null")
public ClientDetails loadClientByClientId(String clientId) {
return super.loadClientByClientId(clientId);
}

View File

@ -21,6 +21,7 @@ import cn.hutool.core.util.StrUtil;
import com.pig4cloud.pig.admin.api.dto.UserInfo;
import com.pig4cloud.pig.admin.api.entity.SysUser;
import com.pig4cloud.pig.admin.api.feign.RemoteUserService;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import com.pig4cloud.pig.common.core.constant.CommonConstants;
import com.pig4cloud.pig.common.core.constant.SecurityConstants;
import com.pig4cloud.pig.common.core.util.R;
@ -62,7 +63,7 @@ public class PigUserDetailsServiceImpl implements UserDetailsService {
@Override
@SneakyThrows
public UserDetails loadUserByUsername(String username) {
Cache cache = cacheManager.getCache("user_details");
Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS);
if (cache != null && cache.get(username) != null) {
return (PigUser) cache.get(username).get();
}

View File

@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</parent>
<artifactId>pig-common-swagger</artifactId>
@ -40,11 +40,5 @@
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.fox.version}</version>
</dependency>
<!--knife4j是为Java MVC框架集成Swagger生成Api文档的增强-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-micro-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</parent>
<artifactId>pig-common</artifactId>

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</parent>
<artifactId>pig-gateway</artifactId>
@ -59,7 +59,7 @@
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-core</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</dependency>
<!--接口文档-->
<dependency>
@ -70,7 +70,7 @@
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-swagger</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</dependency>
</dependencies>

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</parent>
<artifactId>pig-monitor</artifactId>
@ -46,18 +46,6 @@
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--web 模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!--排除tomcat依赖-->
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</parent>
<artifactId>pig-register</artifactId>

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-upms</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</parent>
<artifactId>pig-upms-api</artifactId>
@ -35,7 +35,7 @@
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-core</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</dependency>
</dependencies>
</project>

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-upms</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</parent>
<artifactId>pig-upms-biz</artifactId>
@ -34,25 +34,25 @@
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-upms-api</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</dependency>
<!--安全模块-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-security</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</dependency>
<!--日志处理-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-log</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</dependency>
<!--接口文档-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-swagger</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</dependency>
<!--注册中心客户端-->
<dependency>
@ -75,18 +75,6 @@
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--web 模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!--排除tomcat依赖-->
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@ -25,7 +25,7 @@ import com.pig4cloud.pig.admin.api.vo.MenuVO;
import com.pig4cloud.pig.admin.mapper.SysMenuMapper;
import com.pig4cloud.pig.admin.mapper.SysRoleMenuMapper;
import com.pig4cloud.pig.admin.service.SysMenuService;
import com.pig4cloud.pig.common.core.constant.CommonConstants;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import com.pig4cloud.pig.common.core.util.R;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
@ -49,14 +49,14 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
private final SysRoleMenuMapper sysRoleMenuMapper;
@Override
@Cacheable(value = "menu_details", key = "#roleId + '_menu'")
@Cacheable(value = CacheConstants.MENU_DETAILS, key = "#roleId + '_menu'")
public List<MenuVO> getMenuByRoleId(Integer roleId) {
return baseMapper.listMenusByRoleId(roleId);
}
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = "menu_details", allEntries = true)
@CacheEvict(value = CacheConstants.MENU_DETAILS, allEntries = true)
public R removeMenuById(Integer id) {
// 查询父节点为当前节点的节点
List<SysMenu> menuList = this.list(Wrappers.<SysMenu>query()
@ -74,7 +74,7 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
}
@Override
@CacheEvict(value = "menu_details", allEntries = true)
@CacheEvict(value = CacheConstants.MENU_DETAILS, allEntries = true)
public Boolean updateMenuById(SysMenu sysMenu) {
return this.updateById(sysMenu);
}

View File

@ -20,7 +20,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.admin.api.entity.SysOauthClientDetails;
import com.pig4cloud.pig.admin.mapper.SysOauthClientDetailsMapper;
import com.pig4cloud.pig.admin.service.SysOauthClientDetailsService;
import com.pig4cloud.pig.common.core.constant.SecurityConstants;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
@ -42,7 +42,7 @@ public class SysOauthClientDetailsServiceImpl extends ServiceImpl<SysOauthClient
* @return
*/
@Override
@CacheEvict(value = SecurityConstants.CLIENT_DETAILS_KEY, key = "#id")
@CacheEvict(value = CacheConstants.CLIENT_DETAILS_KEY, key = "#id")
public Boolean removeClientDetailsById(String id) {
return this.removeById(id);
}
@ -54,7 +54,7 @@ public class SysOauthClientDetailsServiceImpl extends ServiceImpl<SysOauthClient
* @return
*/
@Override
@CacheEvict(value = SecurityConstants.CLIENT_DETAILS_KEY, key = "#clientDetails.clientId")
@CacheEvict(value = CacheConstants.CLIENT_DETAILS_KEY, key = "#clientDetails.clientId")
public Boolean updateClientDetailsById(SysOauthClientDetails clientDetails) {
return this.updateById(clientDetails);
}

View File

@ -22,6 +22,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.admin.api.entity.SysRoleMenu;
import com.pig4cloud.pig.admin.mapper.SysRoleMenuMapper;
import com.pig4cloud.pig.admin.service.SysRoleMenuService;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import lombok.AllArgsConstructor;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
@ -53,7 +54,7 @@ public class SysRoleMenuServiceImpl extends ServiceImpl<SysRoleMenuMapper, SysRo
*/
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = "menu_details", key = "#roleId + '_menu'")
@CacheEvict(value = CacheConstants.MENU_DETAILS, key = "#roleId + '_menu'")
public Boolean saveRoleMenus(String role, Integer roleId, String menuIds) {
this.remove(Wrappers.<SysRoleMenu>query().lambda()
.eq(SysRoleMenu::getRoleId, roleId));
@ -71,7 +72,7 @@ public class SysRoleMenuServiceImpl extends ServiceImpl<SysRoleMenuMapper, SysRo
}).collect(Collectors.toList());
//清空userinfo
cacheManager.getCache("user_details").clear();
cacheManager.getCache(CacheConstants.USER_DETAILS).clear();
return this.saveBatch(roleMenuList);
}
}

View File

@ -23,6 +23,7 @@ import com.pig4cloud.pig.admin.api.entity.SysRoleMenu;
import com.pig4cloud.pig.admin.mapper.SysRoleMapper;
import com.pig4cloud.pig.admin.mapper.SysRoleMenuMapper;
import com.pig4cloud.pig.admin.service.SysRoleService;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
@ -61,7 +62,7 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
* @return
*/
@Override
@CacheEvict(value = "menu_details", allEntries = true)
@CacheEvict(value = CacheConstants.MENU_DETAILS, allEntries = true)
@Transactional(rollbackFor = Exception.class)
public Boolean removeRoleById(Integer id) {
sysRoleMenuMapper.delete(Wrappers

View File

@ -24,14 +24,17 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.admin.api.dto.UserDTO;
import com.pig4cloud.pig.admin.api.dto.UserInfo;
import com.pig4cloud.pig.admin.api.entity.*;
import com.pig4cloud.pig.admin.api.entity.SysDept;
import com.pig4cloud.pig.admin.api.entity.SysRole;
import com.pig4cloud.pig.admin.api.entity.SysUser;
import com.pig4cloud.pig.admin.api.entity.SysUserRole;
import com.pig4cloud.pig.admin.api.vo.MenuVO;
import com.pig4cloud.pig.admin.api.vo.UserVO;
import com.pig4cloud.pig.admin.mapper.SysUserMapper;
import com.pig4cloud.pig.admin.service.*;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import com.pig4cloud.pig.common.core.constant.CommonConstants;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.security.util.SecurityUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
@ -148,7 +151,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
* @return Boolean
*/
@Override
@CacheEvict(value = "user_details", key = "#sysUser.username")
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#sysUser.username")
public Boolean removeUserById(SysUser sysUser) {
sysUserRoleService.removeRoleByUserId(sysUser.getUserId());
this.removeById(sysUser.getUserId());
@ -156,7 +159,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
}
@Override
@CacheEvict(value = "user_details", key = "#userDto.username")
@CacheEvict(value =CacheConstants.USER_DETAILS, key = "#userDto.username")
public R<Boolean> updateUserInfo(UserDTO userDto) {
UserVO userVO = baseMapper.getUserVoByUsername(userDto.getUsername());
SysUser sysUser = new SysUser();
@ -176,7 +179,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
}
@Override
@CacheEvict(value = "user_details", key = "#userDto.username")
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username")
public Boolean updateUser(UserDTO userDto) {
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(userDto, sysUser);
@ -218,21 +221,4 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
return this.list(Wrappers.<SysUser>query().lambda()
.eq(SysUser::getDeptId, parentId));
}
/**
* 获取当前用户的子部门信息
*
* @return 子部门列表
*/
private List<Integer> getChildDepts() {
Integer deptId = SecurityUtils.getUser().getDeptId();
//获取当前部门的子部门
return sysDeptRelationService
.list(Wrappers.<SysDeptRelation>query().lambda()
.eq(SysDeptRelation::getAncestor, deptId))
.stream()
.map(SysDeptRelation::getDescendant)
.collect(Collectors.toList());
}
}

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
</parent>
<artifactId>pig-upms</artifactId>

34
pom.xml
View File

@ -27,28 +27,26 @@
<groupId>com.pig4cloud</groupId>
<artifactId>pig</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
<name>${project.artifactId}</name>
<packaging>pom</packaging>
<url>https://www.pig4cloud.com</url>
<properties>
<spring-boot.version>2.2.2.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
<spring-cloud.version>Hoxton.SR1</spring-cloud.version>
<spring-cloud-alibaba.version>2.1.1.RELEASE</spring-cloud-alibaba.version>
<spring-platform.version>Cairo-SR8</spring-platform.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring-boot-admin.version>2.2.0</spring-boot-admin.version>
<hutool.version>5.0.6</hutool.version>
<spring-boot-admin.version>2.2.1</spring-boot-admin.version>
<hutool.version>5.1.0</hutool.version>
<mybatis-plus.version>3.3.0</mybatis-plus.version>
<kaptcha.version>0.0.9</kaptcha.version>
<velocity.version>1.7</velocity.version>
<jasypt.version>2.1.0</jasypt.version>
<swagger.fox.version>2.9.2</swagger.fox.version>
<knife4j.version>1.9.6</knife4j.version>
<security.oauth.version>2.3.6.RELEASE</security.oauth.version>
</properties>
<dependencies>
@ -134,11 +132,18 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<!--稳定版本替代spring security bom内置-->
<!--web 模块-->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>${security.oauth.version}</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
<exclusions>
<!--排除tomcat依赖-->
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
@ -171,15 +176,6 @@
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<target>${maven.compiler.target}</target>
<source>${maven.compiler.source}</source>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>