Merge remote-tracking branch 'origin/master'

This commit is contained in:
edgar 2022-06-23 08:49:32 +08:00
commit 3b110521ce
38 changed files with 440 additions and 88 deletions

View File

@ -1,5 +1,7 @@
### 版本信息
- ⭐️ [4.x 版本点击这里提问,此处不回复](https://support.pig4cloud.com)
- pig版本:
- 是否修改包名:

View File

@ -1,5 +1,5 @@
<p align="center">
<img src="https://img.shields.io/badge/Pig-3.4-success.svg" alt="Build Status">
<img src="https://img.shields.io/badge/Pig-3.5-success.svg" alt="Build Status">
<img src="https://img.shields.io/badge/Spring%20Cloud-2021-blue.svg" alt="Coverage Status">
<img src="https://img.shields.io/badge/Spring%20Boot-2.7-blue.svg" alt="Downloads">
<img src="https://img.shields.io/github/license/pig-mesh/pig"/>
@ -27,6 +27,8 @@
## 微信群 [禁广告]
![](https://minio.pigx.vip/oss/1648184189.png)
## 快速开始
### 核心依赖
@ -38,7 +40,7 @@
| Spring Cloud Alibaba | 2021.0.1.0 |
| Spring Authorization Server | 0.3.0 |
| Mybatis Plus | 3.5.2 |
| hutool | 5.8.2 |
| hutool | 5.8.3 |
| Avue | 2.6.18 |
### 模块说明
@ -104,12 +106,12 @@ cnpm install && cnpm run build:docker && cd docker && docker-compose up -d
<table>
<tr>
<td><a href="https://www.bilibili.com/video/av45084065" target="_blank"><img src="https://gitee.com/pig4cloud/oss/raw/master/2020-9/20200901133006.png"></a></td>
<td><a href="https://www.bilibili.com/video/av77344954" target="_blank"><img src="https://gitee.com/pig4cloud/oss/raw/master/2020-9/20200901133059.png"></a></td>
<td><a href="https://www.bilibili.com/video/av45084065" target="_blank"><img src="https://minio.pigx.vip/oss/1655474345.jpg"></a></td>
<td><a href="https://www.bilibili.com/video/av77344954" target="_blank"><img src="https://minio.pigx.vip/oss/1655474359.jpg"></a></td>
</tr>
<tr>
<td><a href="https://www.bilibili.com/video/BV1J5411476V" target="_blank"><img src="https://gitee.com/pig4cloud/oss/raw/master/2020-9/20200901133114.png"></a></td>
<td><a href="https://www.bilibili.com/video/BV14p4y197K5" target="_blank"><img src="https://gitee.com/pig4cloud/oss/raw/master/2020-9/20200901133124.png"></a></td>
<td><a href="https://www.bilibili.com/video/BV1J5411476V" target="_blank"><img src="https://minio.pigx.vip/oss/1655474369.jpg"></a></td>
<td><a href="https://www.bilibili.com/video/BV14p4y197K5" target="_blank"><img src="https://minio.pigx.vip/oss/1655474381.jpg"></a></td>
</tr>
</table>
@ -120,7 +122,8 @@ cnpm install && cnpm run build:docker && cd docker && docker-compose up -d
pig 开源软件遵循 [Apache 2.0 协议](https://www.apache.org/licenses/LICENSE-2.0.html)。
允许商业使用但务必保留类作者、Copyright 信息。
![](https://gitee.com/pig4cloud/oss/raw/master/2020-10-9/1602229452602-image.png)
![](https://minio.pigx.vip/oss/1655474288.jpg)
### 其他说明
@ -130,6 +133,3 @@ pig 开源软件遵循 [Apache 2.0 协议](https://www.apache.org/licenses/LICEN
2. 欢迎提交 [issue](https://gitee.com/log4j/pig/issues),请写清楚遇到问题的原因、开发环境、复显步骤。
3. 联系作者 <a href="mailto:pig4cloud@qq.com">pig4cloud@qq.com</a>
[![Stargazers over time](https://whnb.wang/img/log4j/pig?e=604800)](https://whnb.wang/log4j/pig?e=604800)

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
</parent>
<artifactId>pig-auth</artifactId>

View File

@ -69,8 +69,10 @@ public class AuthorizationServerConfiguration {
tokenEndpoint.accessTokenRequestConverter(accessTokenRequestConverter()) // 注入自定义的授权认证Converter
.accessTokenResponseHandler(new PigAuthenticationSuccessEventHandler()) // 登录成功处理器
.errorResponseHandler(new PigAuthenticationFailureEventHandler());// 登录失败处理器
}).authorizationEndpoint( // 授权码端点个性化confirm页面
authorizationEndpoint -> authorizationEndpoint.consentPage(SecurityConstants.CUSTOM_CONSENT_PAGE_URI)));
}).clientAuthentication(oAuth2ClientAuthenticationConfigurer -> // 个性化客户端认证
oAuth2ClientAuthenticationConfigurer.errorResponseHandler(new PigAuthenticationFailureEventHandler()))// 处理客户端认证异常
.authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint// 授权码端点个性化confirm页面
.consentPage(SecurityConstants.CUSTOM_CONSENT_PAGE_URI)));
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
DefaultSecurityFilterChain securityFilterChain = http.requestMatcher(endpointsMatcher)

View File

@ -19,9 +19,9 @@ package com.pig4cloud.pig.auth.config;
import com.pig4cloud.pig.auth.support.core.FormIdentityLoginConfigurer;
import com.pig4cloud.pig.auth.support.core.PigDaoAuthenticationProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.core.annotation.Order;
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.WebSecurityCustomizer;
import org.springframework.security.web.SecurityFilterChain;
/**
@ -49,9 +49,21 @@ public class WebSecurityConfiguration {
return http.build();
}
/**
* 暴露静态资源
*
* https://github.com/spring-projects/spring-security/issues/10938
* @param http
* @return
* @throws Exception
*/
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("/actuator/**", "/css/**", "/error");
@Order(0)
SecurityFilterChain resources(HttpSecurity http) throws Exception {
http.requestMatchers((matchers) -> matchers.antMatchers("/actuator/**", "/css/**", "/error"))
.authorizeHttpRequests((authorize) -> authorize.anyRequest().permitAll()).requestCache().disable()
.securityContext().disable().sessionManagement().disable();
return http.build();
}
}

View File

@ -22,6 +22,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pig.admin.api.entity.SysOauthClientDetails;
import com.pig4cloud.pig.admin.api.feign.RemoteClientDetailsService;
import com.pig4cloud.pig.admin.api.vo.TokenVo;
import com.pig4cloud.pig.auth.support.handler.PigAuthenticationFailureEventHandler;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import com.pig4cloud.pig.common.core.constant.CommonConstants;
import com.pig4cloud.pig.common.core.constant.SecurityConstants;
@ -44,18 +45,19 @@ import org.springframework.security.authentication.event.LogoutSuccessEvent;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.OAuth2TokenType;
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter;
import org.springframework.security.oauth2.core.http.converter.OAuth2ErrorHttpMessageConverter;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
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.HttpServletResponse;
import java.security.Principal;
import java.util.List;
@ -75,7 +77,7 @@ public class PigTokenEndpoint {
private final HttpMessageConverter<OAuth2AccessTokenResponse> accessTokenHttpResponseConverter = new OAuth2AccessTokenResponseHttpMessageConverter();
private final HttpMessageConverter<OAuth2Error> errorHttpResponseConverter = new OAuth2ErrorHttpMessageConverter();
private final AuthenticationFailureHandler authenticationFailureHandler = new PigAuthenticationFailureEventHandler();
private final OAuth2AuthorizationService authorizationService;
@ -135,21 +137,20 @@ public class PigTokenEndpoint {
*/
@SneakyThrows
@GetMapping("/check_token")
public void checkToken(String token, HttpServletResponse response) {
public void checkToken(String token, HttpServletResponse response, HttpServletRequest request) {
ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
if (StrUtil.isBlank(token)) {
httpResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
this.errorHttpResponseConverter.write(new OAuth2Error(OAuth2ErrorCodesExpand.TOKEN_MISSING), null,
httpResponse);
this.authenticationFailureHandler.onAuthenticationFailure(request, response,
new InvalidBearerTokenException(OAuth2ErrorCodesExpand.TOKEN_MISSING));
}
OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
// 如果令牌不存在 返回401
if (authorization == null) {
httpResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
this.errorHttpResponseConverter.write(new OAuth2Error(OAuth2ErrorCodesExpand.TOKEN_MISSING), null,
httpResponse);
if (authorization == null || authorization.getAccessToken() == null) {
this.authenticationFailureHandler.onAuthenticationFailure(request, response,
new InvalidBearerTokenException(OAuth2ErrorCodesExpand.INVALID_BEARER_TOKEN));
}
Map<String, Object> claims = authorization.getAccessToken().getClaims();
@ -166,6 +167,10 @@ public class PigTokenEndpoint {
@DeleteMapping("/{token}")
public R<Boolean> removeToken(@PathVariable("token") String token) {
OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
if (authorization == null) {
return R.ok();
}
OAuth2Authorization.Token<OAuth2AccessToken> accessToken = authorization.getAccessToken();
if (accessToken == null || StrUtil.isBlank(accessToken.getToken().getTokenValue())) {
return R.ok();

View File

@ -29,8 +29,6 @@ import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
@ -73,15 +71,13 @@ public class PigAuthenticationFailureEventHandler implements AuthenticationFailu
logVo.setUpdateBy(username);
SpringContextHolder.publishEvent(new SysLogEvent(logVo));
// 写出错误信息
sendErrorResponse(request, response, exception);
sendErrorResponse(response, exception);
}
private void sendErrorResponse(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException {
OAuth2Error error = ((OAuth2AuthenticationException) exception).getError();
private void sendErrorResponse(HttpServletResponse response, AuthenticationException exception) throws IOException {
ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
httpResponse.setStatusCode(HttpStatus.BAD_REQUEST);
this.errorHttpResponseConverter.write(R.failed(error.getDescription()), MediaType.APPLICATION_JSON,
httpResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
this.errorHttpResponseConverter.write(R.failed(exception.getLocalizedMessage()), MediaType.APPLICATION_JSON,
httpResponse);
}

View File

@ -6,7 +6,7 @@
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-bom</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
<packaging>pom</packaging>
<name>pig-common-bom</name>
@ -17,7 +17,6 @@
<pig.common.version>${project.version}</pig.common.version>
<spring-boot.version>2.7.0</spring-boot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<security.oauth.version>2.1.8.RELEASE</security.oauth.version>
<log4j2.version>2.17.1</log4j2.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>

View File

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

View File

@ -21,6 +21,11 @@ public interface ErrorCodes {
/**
* 用户已存在
*/
String SYS_USER_EXISTING = "sys.user.existing";
/**
* 用户名已存在
*/
String SYS_USER_USERNAME_EXISTING = "sys.user.username.existing";
/**

View File

@ -76,7 +76,7 @@ public class R<T> implements Serializable {
return restResult(data, CommonConstants.FAIL, msg);
}
private static <T> R<T> restResult(T data, int code, String msg) {
public static <T> R<T> restResult(T data, int code, String msg) {
R<T> apiResult = new R<>();
apiResult.setCode(code);
apiResult.setData(data);

View File

@ -0,0 +1,289 @@
/*
*
* 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.core.util;
import cn.hutool.core.util.ObjectUtil;
import com.pig4cloud.pig.common.core.constant.CommonConstants;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
/**
* 简化{@code R<T>} 的访问操作,例子 <pre>
* R<Integer> result = R.ok(0);
* // 使用场景1: 链式操作: 断言然后消费
* RetOps.of(result)
* .assertCode(-1,r -> new RuntimeException("error "+r.getCode()))
* .assertDataNotEmpty(r -> new IllegalStateException("oops!"))
* .useData(System.out::println);
*
* // 使用场景2: 读取原始值(data),这里返回的是Optional
* RetOps.of(result).getData().orElse(null);
*
* // 使用场景3: 类型转换
* R<String> s = RetOps.of(result)
* .assertDataNotNull(r -> new IllegalStateException("nani??"))
* .map(i -> Integer.toHexString(i))
* .peek();
* </pre>
*
* @author CJ (power4j@outlook.com)
* @date 2022/5/12
* @since 4.4
*/
public class RetOps<T> {
/** 状态码为成功 */
public static final Predicate<R<?>> CODE_SUCCESS = r -> CommonConstants.SUCCESS == r.getCode();
/** 数据有值 */
public static final Predicate<R<?>> HAS_DATA = r -> ObjectUtil.isNotEmpty(r.getData());
/** 数据有值,并且包含元素 */
public static final Predicate<R<?>> HAS_ELEMENT = r -> ObjectUtil.isNotEmpty(r.getData());
/** 状态码为成功并且有值 */
public static final Predicate<R<?>> DATA_AVAILABLE = CODE_SUCCESS.and(HAS_DATA);
private final R<T> original;
// ~ 初始化
// ===================================================================================================
RetOps(R<T> original) {
this.original = original;
}
public static <T> RetOps<T> of(R<T> original) {
return new RetOps<>(Objects.requireNonNull(original));
}
// ~ 杂项方法
// ===================================================================================================
/**
* 观察原始值
* @return R
*/
public R<T> peek() {
return original;
}
/**
* 读取{@code code}的值
* @return 返回code的值
*/
public int getCode() {
return original.getCode();
}
/**
* 读取{@code data}的值
* @return 返回 Optional 包装的data
*/
public Optional<T> getData() {
return Optional.of(original.getData());
}
/**
* 有条件地读取{@code data}的值
* @param predicate 断言函数
* @return 返回 Optional 包装的data,如果断言失败返回empty
*/
public Optional<T> getDataIf(Predicate<? super R<?>> predicate) {
return predicate.test(original) ? getData() : Optional.empty();
}
/**
* 读取{@code msg}的值
* @return 返回Optional包装的 msg
*/
public Optional<String> getMsg() {
return Optional.of(original.getMsg());
}
/**
* {@code code}的值进行相等性测试
* @param value 基准值
* @return 返回ture表示相等
*/
public boolean codeEquals(int value) {
return original.getCode() == value;
}
/**
* {@code code}的值进行相等性测试
* @param value 基准值
* @return 返回ture表示不相等
*/
public boolean codeNotEquals(int value) {
return !codeEquals(value);
}
/**
* 是否成功
* @return 返回ture表示成功
* @see CommonConstants#SUCCESS
*/
public boolean isSuccess() {
return codeEquals(CommonConstants.SUCCESS);
}
/**
* 是否失败
* @return 返回ture表示失败
*/
public boolean notSuccess() {
return !isSuccess();
}
// ~ 链式操作
// ===================================================================================================
/**
* 断言{@code code}的值
* @param expect 预期的值
* @param func 用户函数,负责创建异常对象
* @param <Ex> 异常类型
* @return 返回实例以便于继续进行链式操作
* @throws Ex 断言失败时抛出
*/
public <Ex extends Exception> RetOps<T> assertCode(int expect, Function<? super R<T>, ? extends Ex> func)
throws Ex {
if (codeNotEquals(expect)) {
throw func.apply(original);
}
return this;
}
/**
* 断言成功
* @param func 用户函数,负责创建异常对象
* @param <Ex> 异常类型
* @return 返回实例以便于继续进行链式操作
* @throws Ex 断言失败时抛出
*/
public <Ex extends Exception> RetOps<T> assertSuccess(Function<? super R<T>, ? extends Ex> func) throws Ex {
return assertCode(CommonConstants.SUCCESS, func);
}
/**
* 断言业务数据有值
* @param func 用户函数,负责创建异常对象
* @param <Ex> 异常类型
* @return 返回实例以便于继续进行链式操作
* @throws Ex 断言失败时抛出
*/
public <Ex extends Exception> RetOps<T> assertDataNotNull(Function<? super R<T>, ? extends Ex> func) throws Ex {
if (Objects.isNull(original.getData())) {
throw func.apply(original);
}
return this;
}
/**
* 断言业务数据有值,并且包含元素
* @param func 用户函数,负责创建异常对象
* @param <Ex> 异常类型
* @return 返回实例以便于继续进行链式操作
* @throws Ex 断言失败时抛出
*/
public <Ex extends Exception> RetOps<T> assertDataNotEmpty(Function<? super R<T>, ? extends Ex> func) throws Ex {
if (ObjectUtil.isNotEmpty(original.getData())) {
throw func.apply(original);
}
return this;
}
/**
* 对业务数据(data)转换
* @param mapper 业务数据转换函数
* @param <U> 数据类型
* @return 返回新实例以便于继续进行链式操作
*/
public <U> RetOps<U> map(Function<? super T, ? extends U> mapper) {
R<U> result = R.restResult(mapper.apply(original.getData()), original.getCode(), original.getMsg());
return of(result);
}
/**
* 对业务数据(data)转换
* @param predicate 断言函数
* @param mapper 业务数据转换函数
* @param <U> 数据类型
* @return 返回新实例以便于继续进行链式操作
* @see RetOps#CODE_SUCCESS
* @see RetOps#HAS_DATA
* @see RetOps#HAS_ELEMENT
* @see RetOps#DATA_AVAILABLE
*/
public <U> RetOps<U> mapIf(Predicate<? super R<T>> predicate, Function<? super T, ? extends U> mapper) {
R<U> result = R.restResult(mapper.apply(original.getData()), original.getCode(), original.getMsg());
return of(result);
}
// ~ 数据消费
// ===================================================================================================
/**
* 消费数据,注意此方法保证数据可用
* @param consumer 消费函数
*/
public void useData(Consumer<? super T> consumer) {
consumer.accept(original.getData());
}
/**
* 条件消费(错误代码匹配某个值)
* @param consumer 消费函数
* @param codes 错误代码集合,匹配任意一个则调用消费函数
*/
public void useDataOnCode(Consumer<? super T> consumer, int... codes) {
useDataIf(o -> Arrays.stream(codes).filter(c -> original.getCode() == c).findFirst().isPresent(), consumer);
}
/**
* 条件消费(错误代码表示成功)
* @param consumer 消费函数
*/
public void useDataIfSuccess(Consumer<? super T> consumer) {
useDataIf(CODE_SUCCESS, consumer);
}
/**
* 条件消费
* @param predicate 断言函数
* @param consumer 消费函数,断言函数返回{@code true}时被调用
* @see RetOps#CODE_SUCCESS
* @see RetOps#HAS_DATA
* @see RetOps#HAS_ELEMENT
* @see RetOps#DATA_AVAILABLE
*/
public void useDataIf(Predicate<? super R<T>> predicate, Consumer<? super T> consumer) {
if (predicate.test(original)) {
consumer.accept(original.getData());
}
}
}

View File

@ -1,23 +1,24 @@
sys.user.update.passwordError=\u539f\u5bc6\u7801\u9519\u8bef\uff0c\u4fee\u6539\u5931\u8d25
sys.user.query.error=\u83b7\u53d6\u5f53\u524d\u7528\u6237\u4fe1\u606f\u5931\u8d25
sys.user.update.passwordError=\u539F\u5BC6\u7801\u9519\u8BEF\uFF0C\u4FEE\u6539\u5931\u8D25
sys.user.query.error=\u83B7\u53D6\u5F53\u524D\u7528\u6237\u4FE1\u606F\u5931\u8D25
sys.user.existing=\u7528\u6237\u5DF2\u5B58\u5728
sys.user.username.existing={0} \u7528\u6237\u540D\u5DF2\u5B58\u5728
sys.user.userInfo.empty={0} \u7528\u6237\u4fe1\u606f\u4e3a\u7a7a
sys.user.userInfo.empty={0} \u7528\u6237\u4FE1\u606F\u4E3A\u7A7A
sys.dept.deptName.inexistence={0} \u90e8\u95e8\u540d\u79f0\u4e0d\u5b58\u5728
sys.dept.deptName.inexistence={0} \u90E8\u95E8\u540D\u79F0\u4E0D\u5B58\u5728
sys.post.postName.inexistence={0} \u5c97\u4f4d\u540d\u79f0\u4e0d\u5b58\u5728
sys.post.nameOrCode.existing={0} {1} \u5c97\u4f4d\u540d\u6216\u5c97\u4f4d\u7f16\u7801\u5df2\u7ecf\u5b58\u5728
sys.post.postName.inexistence={0} \u5C97\u4F4D\u540D\u79F0\u4E0D\u5B58\u5728
sys.post.nameOrCode.existing={0} {1} \u5C97\u4F4D\u540D\u6216\u5C97\u4F4D\u7F16\u7801\u5DF2\u7ECF\u5B58\u5728
sys.role.roleName.inexistence={0} \u89d2\u8272\u540d\u79f0\u4e0d\u5b58\u5728
sys.role.nameOrCode.existing={0} {1} \u89d2\u8272\u540d\u6216\u89d2\u8272\u7f16\u7801\u5df2\u7ecf\u5b58\u5728
sys.role.roleName.inexistence={0} \u89D2\u8272\u540D\u79F0\u4E0D\u5B58\u5728
sys.role.nameOrCode.existing={0} {1} \u89D2\u8272\u540D\u6216\u89D2\u8272\u7F16\u7801\u5DF2\u7ECF\u5B58\u5728
sys.param.delete.system=\u7cfb\u7edf\u5185\u7f6e\u53c2\u6570\u4e0d\u80fd\u5220\u9664
sys.param.delete.system=\u7CFB\u7EDF\u5185\u7F6E\u53C2\u6570\u4E0D\u80FD\u5220\u9664
sys.param.config.error={0} \u7CFB\u7EDF\u53C2\u6570\u914D\u7F6E\u9519\u8BEF
sys.menu.delete.existing=\u83dc\u5355\u542b\u6709\u4e0b\u7ea7\u4e0d\u80fd\u5220\u9664
sys.menu.delete.existing=\u83DC\u5355\u542B\u6709\u4E0B\u7EA7\u4E0D\u80FD\u5220\u9664
sys.app.sms.often=\u9a8c\u8bc1\u7801\u53d1\u9001\u8fc7\u9891\u7e41
sys.app.phone.unregistered={0} \u624b\u673a\u53f7\u672a\u6ce8\u518c
sys.app.sms.often=\u9A8C\u8BC1\u7801\u53D1\u9001\u8FC7\u9891\u7E41
sys.app.phone.unregistered={0} \u624B\u673A\u53F7\u672A\u6CE8\u518C
sys.dict.delete.system=\u7cfb\u7edf\u5185\u7f6e\u5b57\u5178\u9879\u76ee\u4e0d\u80fd\u5220\u9664
sys.dict.update.system=\u7cfb\u7edf\u5185\u7f6e\u5b57\u5178\u9879\u76ee\u4e0d\u80fd\u4fee\u6539
sys.dict.delete.system=\u7CFB\u7EDF\u5185\u7F6E\u5B57\u5178\u9879\u76EE\u4E0D\u80FD\u5220\u9664
sys.dict.update.system=\u7CFB\u7EDF\u5185\u7F6E\u5B57\u5178\u9879\u76EE\u4E0D\u80FD\u4FEE\u6539

View File

@ -21,7 +21,7 @@
<parent>
<artifactId>pig-common</artifactId>
<groupId>com.pig4cloud</groupId>
<version>3.5.0</version>
<version>3.5.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -23,7 +23,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
</parent>
<artifactId>pig-common-job</artifactId>

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
</parent>
<artifactId>pig-common-log</artifactId>

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
</parent>
<artifactId>pig-common-mybatis</artifactId>

View File

@ -23,7 +23,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
</parent>
<artifactId>pig-common-seata</artifactId>

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
</parent>
<artifactId>pig-common-security</artifactId>
@ -56,7 +56,7 @@
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
<dependency>
<groupId>io.springboot.security</groupId>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-authorization-server</artifactId>
<version>${spring.authorization.version}</version>
</dependency>

View File

@ -1,3 +1,4 @@
/*
* Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
*

View File

@ -5,7 +5,8 @@ import com.pig4cloud.pig.admin.api.entity.SysOauthClientDetails;
import com.pig4cloud.pig.admin.api.feign.RemoteClientDetailsService;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import com.pig4cloud.pig.common.core.constant.SecurityConstants;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.core.util.RetOps;
import com.pig4cloud.pig.common.security.util.OAuthClientException;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.cache.annotation.Cacheable;
@ -82,12 +83,13 @@ public class PigRemoteRegisteredClientRepository implements RegisteredClientRepo
@SneakyThrows
@Cacheable(value = CacheConstants.CLIENT_DETAILS_KEY, key = "#clientId", unless = "#result == null")
public RegisteredClient findByClientId(String clientId) {
R<SysOauthClientDetails> detailsR = clientDetailsService.getClientDetailsById(clientId,
SecurityConstants.FROM_IN);
SysOauthClientDetails clientDetails = detailsR.getData();
SysOauthClientDetails clientDetails = RetOps
.of(clientDetailsService.getClientDetailsById(clientId, SecurityConstants.FROM_IN))
.assertDataNotNull(result -> new OAuthClientException("clientId 不合法")).getData().get();
RegisteredClient.Builder builder = RegisteredClient.withId(clientDetails.getClientId())
.clientId(clientDetails.getClientSecret())
.clientId(clientDetails.getClientId())
.clientSecret(SecurityConstants.NOOP + clientDetails.getClientSecret())
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);

View File

@ -35,4 +35,9 @@ public interface OAuth2ErrorCodesExpand {
/** 未知的登录异常 */
String UN_KNOW_LOGIN_ERROR = "un_know_login_error";
/**
* 不合法的Token
*/
String INVALID_BEARER_TOKEN = "invalid_bearer_token";
}

View File

@ -0,0 +1,29 @@
package com.pig4cloud.pig.common.security.util;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
/**
* @author lengleng
* @description OAuthClientException 异常信息
*/
public class OAuthClientException extends OAuth2AuthenticationException {
/**
* Constructs a <code>ScopeException</code> with the specified message.
* @param msg the detail message.
*/
public OAuthClientException(String msg) {
super(new OAuth2Error(msg), msg);
}
/**
* Constructs a {@code ScopeException} with the specified message and root cause.
* @param msg the detail message.
* @param cause root cause
*/
public OAuthClientException(String msg, Throwable cause) {
super(new OAuth2Error(msg), cause);
}
}

View File

@ -24,7 +24,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
</parent>
<artifactId>pig-common-swagger</artifactId>

View File

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

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
</parent>
<artifactId>pig-gateway</artifactId>

View File

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

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-upms</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
</parent>
<artifactId>pig-upms-api</artifactId>

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-upms</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
</parent>
<artifactId>pig-upms-biz</artifactId>

View File

@ -16,6 +16,7 @@
package com.pig4cloud.pig.admin.controller;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@ -115,15 +116,18 @@ public class UserController {
}
/**
* 根据用户名查询用户信息
* @param username 用户名
* 判断用户是否存在
* @param userDTO 查询条件
* @return
*/
@GetMapping("/details/{username}")
public R<SysUser> user(@PathVariable String username) {
SysUser condition = new SysUser();
condition.setUsername(username);
return R.ok(userService.getOne(new QueryWrapper<>(condition)));
@Inner(false)
@GetMapping("/check/exsit")
public R<Boolean> isExsit(UserDTO userDTO) {
List<SysUser> sysUserList = userService.list(new QueryWrapper<>(userDTO));
if (CollUtil.isNotEmpty(sysUserList)) {
return R.ok(Boolean.TRUE, MsgUtils.getMessage(ErrorCodes.SYS_USER_EXISTING));
}
return R.ok(Boolean.FALSE);
}
/**

View File

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

View File

@ -22,7 +22,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-visual</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
</parent>
<artifactId>pig-codegen</artifactId>

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-visual</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
</parent>
<artifactId>pig-monitor</artifactId>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-visual</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
</parent>
<artifactId>pig-sentinel-dashboard</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-visual</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
</parent>
<artifactId>pig-xxl-job-admin</artifactId>

View File

@ -21,7 +21,7 @@
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
</parent>
<artifactId>pig-visual</artifactId>

View File

@ -22,7 +22,7 @@
<groupId>com.pig4cloud</groupId>
<artifactId>pig</artifactId>
<name>${project.artifactId}</name>
<version>3.5.0</version>
<version>3.5.1</version>
<packaging>pom</packaging>
<url>https://www.pig4cloud.com</url>
@ -34,8 +34,8 @@
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring-boot-admin.version>2.6.7</spring-boot-admin.version>
<spring.authorization.version>0.3.0</spring.authorization.version>
<hutool.version>5.8.2</hutool.version>
<spring.authorization.version>0.3.1</spring.authorization.version>
<hutool.version>5.8.3</hutool.version>
<dynamic-ds.version>3.5.1</dynamic-ds.version>
<captcha.version>2.2.2</captcha.version>
<velocity.version>2.3</velocity.version>