diff --git a/blade-auth/src/main/java/org/springblade/core/oauth2/endpoint/OAuth2TokenEndPoint.java b/blade-auth/src/main/java/org/springblade/core/oauth2/endpoint/OAuth2TokenEndPoint.java new file mode 100644 index 00000000..d94945da --- /dev/null +++ b/blade-auth/src/main/java/org/springblade/core/oauth2/endpoint/OAuth2TokenEndPoint.java @@ -0,0 +1,195 @@ +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by FernFlower decompiler) +// + +package org.springblade.core.oauth2.endpoint; + +import com.wf.captcha.SpecCaptcha; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import java.time.Duration; +import java.util.UUID; +import lombok.Generated; +import org.springblade.core.cache.utils.CacheUtil; +import org.springblade.core.jwt.JwtUtil; +import org.springblade.core.jwt.props.JwtProperties; +import org.springblade.core.launch.props.BladeProperties; +import org.springblade.core.log.annotation.ApiLog; +import org.springblade.core.oauth2.exception.OAuth2Exception; +import org.springblade.core.oauth2.granter.TokenGranter; +import org.springblade.core.oauth2.granter.TokenGranterFactory; +import org.springblade.core.oauth2.handler.AuthorizationHandler; +import org.springblade.core.oauth2.handler.TokenHandler; +import org.springblade.core.oauth2.provider.OAuth2Request; +import org.springblade.core.oauth2.provider.OAuth2Response; +import org.springblade.core.oauth2.provider.OAuth2Token; +import org.springblade.core.oauth2.provider.OAuth2Validation; +import org.springblade.core.oauth2.service.OAuth2User; +import org.springblade.core.oauth2.utils.OAuth2ExceptionUtil; +import org.springblade.core.oauth2.utils.OAuth2LogUtil; +import org.springblade.core.redis.cache.BladeRedis; +import org.springblade.core.secure.BladeUser; +import org.springblade.core.secure.utils.AuthUtil; +import org.springblade.core.tool.support.Kv; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@Tag( + name = "用户授权认证", + description = "1 - OAuth2授权认证端点" +) +public class OAuth2TokenEndPoint { + private final BladeRedis bladeRedis; + private final JwtProperties jwtProperties; + private final BladeProperties bladeProperties; + private final TokenGranterFactory granterFactory; + private final AuthorizationHandler authorizationHandler; + private final TokenHandler tokenHandler; + + @PostMapping({"/oauth/token"}) + @Operation( + summary = "获取Token", + description = "OAuth2认证接口", + parameters = {@Parameter( + in = ParameterIn.QUERY, + name = "username", + description = "账号", + schema = @Schema( + type = "string" +) +), @Parameter( + in = ParameterIn.QUERY, + name = "password", + description = "密码", + schema = @Schema( + type = "string" +) +), @Parameter( + in = ParameterIn.QUERY, + name = "grant_type", + description = "授权类型", + schema = @Schema( + type = "string" +) +), @Parameter( + in = ParameterIn.QUERY, + name = "refresh_token", + description = "刷新token", + schema = @Schema( + type = "string" +) +), @Parameter( + in = ParameterIn.QUERY, + name = "scope", + description = "权限范围", + schema = @Schema( + type = "string" +) +)} + ) + @ApiLog("用户账号登录") + public ResponseEntity token() { + OAuth2Request request = OAuth2Request.create().buildArgs(); + OAuth2Validation preValidation = this.authorizationHandler.preValidation(request); + if (!preValidation.isSuccess()) { + this.authorizationHandler.preFailure(request, preValidation); + return ResponseEntity.ok(OAuth2Response.create().ofFailure(preValidation.getCode(), preValidation.getMessage())); + } else { + TokenGranter tokenGranter = this.granterFactory.create(request.getGrantType()); + + OAuth2User user; + try { + user = tokenGranter.user(request); + } catch (OAuth2Exception var8) { + OAuth2LogUtil.logOAuth2Exception(var8, request, this.bladeProperties.isProd()); + this.authorizationHandler.preFailure(request, OAuth2Validation.create().setSuccess(false).setCode(var8.getExceptionCode().getCode()).setMessage(var8.getMessage())); + return ResponseEntity.ok(OAuth2Response.create().ofFailure(var8.getExceptionCode().getCode(), var8.getMessage())); + } + + OAuth2Validation authValidation = this.authorizationHandler.authValidation(user, request); + if (!authValidation.isSuccess()) { + this.authorizationHandler.authFailure(user, request, authValidation); + OAuth2ExceptionUtil.throwFromCode(authValidation.getCode()); + } + + OAuth2Token token = tokenGranter.token(user, request); + OAuth2Token enhanceToken = this.tokenHandler.enhance(user, token, request); + this.authorizationHandler.authSuccessful(user, request); + return ResponseEntity.ok(enhanceToken.getArgs()); + } + } + + @GetMapping({"/oauth/logout"}) + @Operation( + summary = "退出登录" + ) + @ApiLog("用户登出") + public ResponseEntity logout() { + BladeUser user = AuthUtil.getUser(); + if (user != null && this.jwtProperties.getState()) { + OAuth2Request request = OAuth2Request.create().buildHeaderArgs(); + String token = JwtUtil.getToken(request.getToken()); + JwtUtil.removeAccessToken(user.getTenantId(), user.getClientId(), String.valueOf(user.getUserId()), token); + JwtUtil.removeRefreshToken(user.getTenantId(), user.getClientId(), String.valueOf(user.getUserId()), token); + } + + return ResponseEntity.ok(OAuth2Response.create().ofSuccessful("退出登录成功")); + } + + @GetMapping({"/oauth/captcha"}) + @Operation( + summary = "获取验证码" + ) + public ResponseEntity captcha() { + SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 5); + String verCode = specCaptcha.text().toLowerCase(); + String key = UUID.randomUUID().toString(); + this.bladeRedis.setEx("blade:auth::blade:captcha:" + key, verCode, Duration.ofMinutes(30L)); + return ResponseEntity.ok(OAuth2Response.create().ofSuccessful("获取验证码成功").set("key", key).set("image", specCaptcha.toBase64())); + } + + @GetMapping({"/oauth/user-info"}) + @Operation( + summary = "获取用户信息" + ) + public ResponseEntity userInfo(BladeUser user) { + return ResponseEntity.ok(user); + } + + @GetMapping({"/oauth/clear-cache"}) + @Operation( + summary = "清除缓存" + ) + public ResponseEntity clearCache() { + CacheUtil.clear("blade:biz"); + CacheUtil.clear("blade:user"); + CacheUtil.clear("blade:dict"); + CacheUtil.clear("blade:flow"); + CacheUtil.clear("blade:sys"); + CacheUtil.clear("blade:param"); + CacheUtil.clear("blade:resource"); + CacheUtil.clear("blade:menu"); + CacheUtil.clear("blade:dict", Boolean.FALSE); + CacheUtil.clear("blade:menu", Boolean.FALSE); + CacheUtil.clear("blade:sys", Boolean.FALSE); + CacheUtil.clear("blade:param", Boolean.FALSE); + return ResponseEntity.ok(OAuth2Response.create().ofSuccessful("清除缓存成功")); + } + + @Generated + public OAuth2TokenEndPoint(final BladeRedis bladeRedis, final JwtProperties jwtProperties, final BladeProperties bladeProperties, final TokenGranterFactory granterFactory, final AuthorizationHandler authorizationHandler, final TokenHandler tokenHandler) { + this.bladeRedis = bladeRedis; + this.jwtProperties = jwtProperties; + this.bladeProperties = bladeProperties; + this.granterFactory = granterFactory; + this.authorizationHandler = authorizationHandler; + this.tokenHandler = tokenHandler; + } +} diff --git a/blade-ops/blade-log/src/main/java/org/springblade/core/log/controller/LogApiController.java b/blade-ops/blade-log/src/main/java/org/springblade/core/log/controller/LogApiController.java index 0e09ccb6..6b84f631 100644 --- a/blade-ops/blade-log/src/main/java/org/springblade/core/log/controller/LogApiController.java +++ b/blade-ops/blade-log/src/main/java/org/springblade/core/log/controller/LogApiController.java @@ -66,7 +66,7 @@ public class LogApiController { @IsAdmin @GetMapping("/detail") public R detail(LogApi log) { - return R.data(logService.getOne(Condition.getQueryWrapper(log))); + return R.data(LogApiWrapper.build().entityVO(logService.getOne(Condition.getQueryWrapper(log)))); } /** diff --git a/blade-ops/blade-log/src/main/java/org/springblade/core/log/wrapper/LogApiWrapper.java b/blade-ops/blade-log/src/main/java/org/springblade/core/log/wrapper/LogApiWrapper.java index a891e0da..f727b1d0 100644 --- a/blade-ops/blade-log/src/main/java/org/springblade/core/log/wrapper/LogApiWrapper.java +++ b/blade-ops/blade-log/src/main/java/org/springblade/core/log/wrapper/LogApiWrapper.java @@ -25,11 +25,14 @@ */ package org.springblade.core.log.wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.springblade.core.log.model.LogApi; import org.springblade.core.log.pojo.vo.LogApiVO; import org.springblade.core.mp.support.BaseEntityWrapper; import org.springblade.core.tool.utils.BeanUtil; +import java.util.List; import java.util.Objects; /** @@ -45,7 +48,39 @@ public class LogApiWrapper extends BaseEntityWrapper { @Override public LogApiVO entityVO(LogApi logApi) { - return Objects.requireNonNull(BeanUtil.copyProperties(logApi, LogApiVO.class)); + LogApiVO logApiVO = Objects.requireNonNull(BeanUtil.copyProperties(logApi, LogApiVO.class)); + if ("用户账号登录".equals(logApiVO.getTitle())){ + String[] split = logApiVO.getParams().split("&"); + for (String s : split) { + if (s.contains("username")) { + logApiVO.setCreateBy(s.split("=")[1]); + } + } + } + return logApiVO; } + @Override + public List listVO(List list) { + return super.listVO(list); + } + + @Override + public IPage pageVO(IPage pages) { + List records = this.listVO(pages.getRecords()); + IPage pageVo = new Page<>(pages.getCurrent(), pages.getSize(), pages.getTotal()); + records.forEach(record -> { + // 处理用户登录逻辑 + if ("用户账号登录".equals(record.getTitle())){ + String[] split = record.getParams().split("&"); + for (String s : split) { + if (s.contains("username")) { + record.setCreateBy(s.split("=")[1]); + } + } + } + }); + pageVo.setRecords(records); + return pageVo; + } } diff --git a/blade-service/blade-system/src/main/java/org/springblade/system/feign/UserClient.java b/blade-service/blade-system/src/main/java/org/springblade/system/feign/UserClient.java index 17fed81a..3d2cd7fb 100644 --- a/blade-service/blade-system/src/main/java/org/springblade/system/feign/UserClient.java +++ b/blade-service/blade-system/src/main/java/org/springblade/system/feign/UserClient.java @@ -27,6 +27,7 @@ package org.springblade.system.feign; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import io.swagger.v3.oas.annotations.Hidden; import lombok.AllArgsConstructor; import org.springblade.core.tenant.annotation.NonDS; import org.springblade.core.tool.api.R; @@ -40,7 +41,6 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; -import io.swagger.v3.oas.annotations.Hidden; import java.util.List;