From af576650c19723c4732d80327ed4961e270de3ff Mon Sep 17 00:00:00 2001
From: wanggeng <450292408@qq.com>
Date: Wed, 15 Sep 2021 23:41:29 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BA=86OAuth2=E6=9C=8D?=
=?UTF-8?q?=E5=8A=A1=E7=AB=AF=E6=A8=A1=E5=9D=97=EF=BC=8C=E7=AE=80=E5=8C=96?=
=?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=BA=A4=E4=BA=92=E7=9A=84=E9=95=BF=E5=BA=A6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
{login-oauth => login-oauth2-server}/pom.xml | 17 +-
.../OAuth2AuthorizationServerConfig.java | 156 +++++++++
.../apis/OAuth2ClientController.java | 164 +++++++++
.../route/OAuth2ClientRouteController.java | 37 ++
.../converter/UserAccessTokenConverter.java | 22 ++
.../server/converter/UserAuthConverter.java | 104 ++++++
.../oauth2/server/dao/IOAuth2ClientDao.java | 36 +-
...h2ClientBadClientCredentialsException.java | 31 ++
.../OAuth2ClientExpireException.java | 25 ++
.../OAuth2ClientStateException.java | 24 ++
.../server/pojo/dtos/OAuth2ClientDTO.java | 96 +++---
.../pojo/dtos/OAuth2ClientSimpleDTO.java | 77 +++++
.../server/pojo/pos/OAuth2ClientPO.java | 207 +++++++++++
.../server/pojo/vos/OAuth2ClientVO.java | 208 ++++++++++++
.../server/service/IOAuth2ClientService.java | 172 ++++++++++
.../service/impl/OAuth2ClientServiceImpl.java | 174 ++++++++++
.../impl/OauthClientDetailsServiceImpl.java | 106 ++++++
.../impl/OauthClientTokenServiceImpl.java | 320 ++++++++++++++++++
.../mybatis/mapper/IOAuth2ClientDao.xml | 94 +++--
.../templates/oauth2client}/list.html | 170 +++++-----
.../templates/oauth2client}/save.html | 8 +-
.../templates/oauth2client}/update.html | 8 +-
pom.xml | 24 +-
service-oauth-client/pom.xml | 23 --
.../controller/api/OauthClientController.java | 239 -------------
.../client/service/IOauthClientService.java | 130 -------
.../service/impl/OauthClientServiceImpl.java | 149 --------
27 files changed, 2097 insertions(+), 724 deletions(-)
rename {login-oauth => login-oauth2-server}/pom.xml (51%)
create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/config/OAuth2AuthorizationServerConfig.java
create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/controller/apis/OAuth2ClientController.java
create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/controller/route/OAuth2ClientRouteController.java
create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/converter/UserAccessTokenConverter.java
create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/converter/UserAuthConverter.java
rename service-oauth-client/src/main/java/ink/wgink/module/oauth/client/dao/IOauthClientDao.java => login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/dao/IOAuth2ClientDao.java (68%)
create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/exceptions/OAuth2ClientBadClientCredentialsException.java
create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/exceptions/OAuth2ClientExpireException.java
create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/exceptions/OAuth2ClientStateException.java
rename service-oauth-client/src/main/java/ink/wgink/module/oauth/client/pojo/vos/OauthClientVO.java => login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/pojo/dtos/OAuth2ClientDTO.java (76%)
create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/pojo/dtos/OAuth2ClientSimpleDTO.java
create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/pojo/pos/OAuth2ClientPO.java
create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/pojo/vos/OAuth2ClientVO.java
create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/IOAuth2ClientService.java
create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/OAuth2ClientServiceImpl.java
create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/OauthClientDetailsServiceImpl.java
create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/OauthClientTokenServiceImpl.java
rename service-oauth-client/src/main/resources/mybatis/mapper/oauthclient-mapper.xml => login-oauth2-server/src/main/resources/mybatis/mapper/IOAuth2ClientDao.xml (70%)
rename {service-oauth-client/src/main/resources/templates/oauth/client => login-oauth2-server/src/main/resources/templates/oauth2client}/list.html (72%)
rename {service-oauth-client/src/main/resources/templates/oauth/client => login-oauth2-server/src/main/resources/templates/oauth2client}/save.html (98%)
rename {service-oauth-client/src/main/resources/templates/oauth/client => login-oauth2-server/src/main/resources/templates/oauth2client}/update.html (98%)
delete mode 100644 service-oauth-client/pom.xml
delete mode 100644 service-oauth-client/src/main/java/ink/wgink/module/oauth/client/controller/api/OauthClientController.java
delete mode 100644 service-oauth-client/src/main/java/ink/wgink/module/oauth/client/service/IOauthClientService.java
delete mode 100644 service-oauth-client/src/main/java/ink/wgink/module/oauth/client/service/impl/OauthClientServiceImpl.java
diff --git a/login-oauth/pom.xml b/login-oauth2-server/pom.xml
similarity index 51%
rename from login-oauth/pom.xml
rename to login-oauth2-server/pom.xml
index 4e09ca4b..b317be53 100644
--- a/login-oauth/pom.xml
+++ b/login-oauth2-server/pom.xml
@@ -9,7 +9,7 @@
4.0.0
- login-oauth
+ login-oauth2-server
单点登录
@@ -18,6 +18,21 @@
login-base
1.0-SNAPSHOT
+
+ ink.wgink
+ service-menu
+ 1.0-SNAPSHOT
+
+
+ org.springframework.security
+ spring-security-jwt
+ 1.0.9.RELEASE
+
+
+ org.springframework.security.oauth.boot
+ spring-security-oauth2-autoconfigure
+ 2.0.0.RELEASE
+
\ No newline at end of file
diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/config/OAuth2AuthorizationServerConfig.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/config/OAuth2AuthorizationServerConfig.java
new file mode 100644
index 00000000..aca933c9
--- /dev/null
+++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/config/OAuth2AuthorizationServerConfig.java
@@ -0,0 +1,156 @@
+package ink.wgink.login.oauth2.server.config;
+
+import ink.wgink.login.base.service.user.UserDetailServiceImpl;
+import ink.wgink.login.oauth2.server.converter.UserAccessTokenConverter;
+import ink.wgink.login.oauth2.server.service.impl.OauthClientDetailsServiceImpl;
+import ink.wgink.login.oauth2.server.service.impl.OauthClientTokenServiceImpl;
+import ink.wgink.service.user.service.IUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.oauth2.common.OAuth2AccessToken;
+import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
+import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
+import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
+import org.springframework.security.oauth2.provider.CompositeTokenGranter;
+import org.springframework.security.oauth2.provider.OAuth2RequestFactory;
+import org.springframework.security.oauth2.provider.TokenGranter;
+import org.springframework.security.oauth2.provider.TokenRequest;
+import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler;
+import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
+import org.springframework.security.oauth2.provider.client.ClientCredentialsTokenGranter;
+import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
+import org.springframework.security.oauth2.provider.code.AuthorizationCodeTokenGranter;
+import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices;
+import org.springframework.security.oauth2.provider.implicit.ImplicitTokenGranter;
+import org.springframework.security.oauth2.provider.password.ResourceOwnerPasswordTokenGranter;
+import org.springframework.security.oauth2.provider.refresh.RefreshTokenGranter;
+import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
+import org.springframework.security.oauth2.provider.token.TokenStore;
+import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
+import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ClassName: OAuth2AuthorizationServerConfig
+ * @Description: OAuth2认证服务器配置
+ * @Author: wanggeng
+ * @Date: 2021/9/15 4:54 下午
+ * @Version: 1.0
+ */
+@Configuration
+@EnableAuthorizationServer
+public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
+
+ @Autowired
+ private AuthenticationManager authenticationManager;
+ @Autowired
+ private UserDetailServiceImpl userDetailService;
+ @Autowired
+ private IUserService userService;
+ @Autowired
+ private OauthClientDetailsServiceImpl oAuth2ClientDetailsService;
+ @Autowired
+ private OauthClientTokenServiceImpl oAuth2ClientTokenService;
+
+ @Override
+ public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
+ // 通过内存的方式来完成认证服务
+ clients.withClientDetails(oAuth2ClientDetailsService);
+ }
+
+ @Override
+ public void configure(AuthorizationServerSecurityConfigurer security) {
+ // 标识可以全部操作
+ security
+ .tokenKeyAccess("permitAll()")
+ .checkTokenAccess("permitAll()")
+ .allowFormAuthenticationForClients();
+ }
+
+ @Override
+ public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
+ // 添加JWT授权机制
+ endpoints
+ .pathMapping("/oauth/authorize", "/oauth_client/authorize")
+ .pathMapping("/oauth/token", "/oauth_client/token")
+ .pathMapping("/oauth/token_key", "/oauth_client/token_key")
+ .pathMapping("/oauth/check_token", "/oauth_client/check_token")
+ .pathMapping("/oauth/confirm_access", "/oauth_client/confirm_access")
+ .pathMapping("/oauth/error", "/oauth_client/error")
+ .authenticationManager(authenticationManager)
+ .tokenStore(jwtTokenStore())
+ .accessTokenConverter(jwtAccessTokenConverter())
+ .userDetailsService(userDetailService);
+ }
+
+ @Bean(name = "jwtTokenStore")
+ public TokenStore jwtTokenStore() {
+ return new JwtTokenStore(jwtAccessTokenConverter());
+ }
+
+ @Bean(name = "jwtAccessTokenConverter")
+ public JwtAccessTokenConverter jwtAccessTokenConverter() {
+ // 添加自定义的认证机制,用来将自定义登陆后客户端拿到的信息
+ JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
+ jwtAccessTokenConverter.setAccessTokenConverter(new UserAccessTokenConverter(userService));
+ jwtAccessTokenConverter.setSigningKey("wgink");
+ return jwtAccessTokenConverter;
+ }
+
+ @Bean
+ public TokenGranter tokenGranter() {
+ return new TokenGranter() {
+ private CompositeTokenGranter delegate;
+
+ @Override
+ public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) {
+ if (delegate == null) {
+ delegate = new CompositeTokenGranter(getDefaultTokenGranters());
+ }
+ return delegate.grant(grantType, tokenRequest);
+ }
+ };
+ }
+
+ @Bean
+ public AuthorizationCodeServices authorizationCodeServices() {
+ return new InMemoryAuthorizationCodeServices();
+ }
+
+ private List getDefaultTokenGranters() {
+ AuthorizationCodeServices authorizationCodeServices = authorizationCodeServices();
+ OAuth2RequestFactory requestFactory = new DefaultOAuth2RequestFactory(oAuth2ClientDetailsService);
+ List tokenGranters = new ArrayList<>();
+ tokenGranters.add(new AuthorizationCodeTokenGranter(oAuth2ClientTokenService, authorizationCodeServices, oAuth2ClientDetailsService, requestFactory));
+ tokenGranters.add(new RefreshTokenGranter(oAuth2ClientTokenService, oAuth2ClientDetailsService, requestFactory));
+ ImplicitTokenGranter implicit = new ImplicitTokenGranter(oAuth2ClientTokenService, oAuth2ClientDetailsService, requestFactory);
+ tokenGranters.add(implicit);
+ tokenGranters.add(new ClientCredentialsTokenGranter(oAuth2ClientTokenService, oAuth2ClientDetailsService, requestFactory));
+ if (authenticationManager != null) {
+ tokenGranters.add(new ResourceOwnerPasswordTokenGranter(authenticationManager, oAuth2ClientTokenService, oAuth2ClientDetailsService, requestFactory));
+ }
+ return tokenGranters;
+ }
+
+ @Bean
+ public OAuth2RequestFactory oAuth2RequestFactory() {
+ OAuth2RequestFactory oAuth2RequestFactory = new DefaultOAuth2RequestFactory(oAuth2ClientDetailsService);
+ return oAuth2RequestFactory;
+ }
+
+ @Bean
+ public UserApprovalHandler userApprovalHandler() {
+ TokenStoreUserApprovalHandler tokenStoreUserApprovalHandler = new TokenStoreUserApprovalHandler();
+ tokenStoreUserApprovalHandler.setClientDetailsService(oAuth2ClientDetailsService);
+ tokenStoreUserApprovalHandler.setTokenStore(jwtTokenStore());
+ tokenStoreUserApprovalHandler.setRequestFactory(oAuth2RequestFactory());
+ return tokenStoreUserApprovalHandler;
+ }
+
+}
diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/controller/apis/OAuth2ClientController.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/controller/apis/OAuth2ClientController.java
new file mode 100644
index 00000000..3dc226cf
--- /dev/null
+++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/controller/apis/OAuth2ClientController.java
@@ -0,0 +1,164 @@
+package ink.wgink.login.oauth2.server.controller.apis;
+
+import ink.wgink.annotation.CheckRequestBodyAnnotation;
+import ink.wgink.common.base.DefaultBaseController;
+import ink.wgink.exceptions.*;
+import ink.wgink.interfaces.consts.ISystemConstant;
+import ink.wgink.login.oauth2.server.pojo.dtos.OAuth2ClientDTO;
+import ink.wgink.login.oauth2.server.pojo.vos.OAuth2ClientVO;
+import ink.wgink.login.oauth2.server.service.IOAuth2ClientService;
+import ink.wgink.pojo.ListPage;
+import ink.wgink.pojo.result.ErrorResult;
+import ink.wgink.pojo.result.SuccessResult;
+import ink.wgink.pojo.result.SuccessResultList;
+import ink.wgink.util.AesUtil;
+import io.swagger.annotations.*;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName: OauthClientController
+ * @Description: Oauth客户端
+ * @Author: WangGeng
+ * @Date: 2019/3/12 11:15 AM
+ * @Version: 1.0
+ **/
+@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "Oauth客户端")
+@RestController
+@RequestMapping(ISystemConstant.API_PREFIX + "/oauth2client")
+public class OAuth2ClientController extends DefaultBaseController {
+
+ @Autowired
+ private IOAuth2ClientService oAuth2ClientService;
+
+ @ApiOperation(value = "Oauth客户端新增", notes = "Oauth客户端新增接口")
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @PostMapping("save")
+ @CheckRequestBodyAnnotation
+ public SuccessResult saveOauthClient(@RequestBody OAuth2ClientVO oAuth2ClientVO) throws Exception {
+ if (!StringUtils.equals(oAuth2ClientVO.getClientSecret(),
+ Base64.encodeBase64String(
+ AesUtil.aesEncoder(
+ IOAuth2ClientService.OAUTH_CLIENT_RULE, oAuth2ClientVO.getClientId()
+ ).getBytes("UTF-8")
+ ))) {
+ throw new ParamsException("clientId与clientSecret不匹配");
+ }
+ checkParams(oAuth2ClientVO);
+ oAuth2ClientService.save(oAuth2ClientVO);
+ return new SuccessResult();
+ }
+
+ @ApiOperation(value = "Oauth客户端删除", notes = "Oauth客户端删除接口")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "ids", value = "Oauth客户端ID列表,用下划线分隔", paramType = "path", example = "1_2_3")
+ })
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @DeleteMapping("remove/{ids}")
+ public SuccessResult remove(@PathVariable("ids") String ids) throws RemoveException {
+ oAuth2ClientService.remove(Arrays.asList(ids.split("\\_")));
+ return new SuccessResult();
+ }
+
+ @ApiOperation(value = "Oauth客户端修改", notes = "Oauth客户端修改接口")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "clientId", value = "Oauth客户端ID", paramType = "path")
+ })
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @PutMapping("update/{clientId}")
+ public SuccessResult updateOauthClient(@PathVariable("clientId") String clientId,
+ @RequestBody OAuth2ClientVO oAuth2ClientVO) throws Exception {
+ checkParams(oAuth2ClientVO);
+ oAuth2ClientService.update(clientId, oAuth2ClientVO);
+ return new SuccessResult();
+ }
+
+ /**
+ * 校验参数
+ *
+ * @param oAuth2ClientVO
+ * @throws ParamsException
+ */
+ private void checkParams(OAuth2ClientVO oAuth2ClientVO) throws ParamsException {
+ if (StringUtils.equals(oAuth2ClientVO.getSystemType(), IOAuth2ClientService.OAUTH_CLIENT_SYSTEM_TYPE_THIRD)) {
+ if (StringUtils.isBlank(oAuth2ClientVO.getSystemState())) {
+ throw new ParamsException("系统状态不能为空");
+ }
+ if (StringUtils.isBlank(oAuth2ClientVO.getExpireTime())) {
+ throw new ParamsException("系统到期时间不能为空");
+ }
+ }
+ }
+
+ @ApiOperation(value = "easyui Oauth客户端列表", notes = "easyui Oauth客户端列表列表接口")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "page", value = "当前页码", paramType = "query", dataType = "int", defaultValue = "1"),
+ @ApiImplicitParam(name = "rows", value = "显示数量", paramType = "query", dataType = "int", defaultValue = "20"),
+ @ApiImplicitParam(name = "keywords", value = "关键字", paramType = "query", dataType = "String"),
+ @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "String"),
+ @ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", dataType = "String")
+ })
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @GetMapping("listpage")
+ public SuccessResultList> listPage(ListPage page) throws SearchException {
+ Map params = requestParams();
+ page.setParams(params);
+ return oAuth2ClientService.listPage(page);
+ }
+
+ @ApiOperation(value = "Oauth客户端列表", notes = "Oauth客户端列表列表接口")
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @GetMapping("list")
+ public List listOauthClient() throws SearchException {
+ Map params = requestParams();
+ return oAuth2ClientService.list(params);
+ }
+
+ @ApiOperation(value = "Oauth客户端详情", notes = "Oauth客户端详情接口")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "clientId", value = "Oauth客户端ID", paramType = "path")
+ })
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @GetMapping("get/{clientId}")
+ public OAuth2ClientDTO getOauthClient(@PathVariable("clientId") String clientId) throws Exception {
+ return oAuth2ClientService.get(clientId);
+ }
+
+ @ApiOperation(value = "Oauth客户端绑定菜单", notes = "Oauth客户端绑定菜单接口,自动创建根节点菜单")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "clientId", value = "Oauth客户端ID", paramType = "path"),
+ @ApiImplicitParam(name = "menuId", value = "菜单ID", paramType = "query")
+ })
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @PutMapping("update-menu-init/{clientId}")
+ public SuccessResult updateMenuInit(@PathVariable("clientId") String clientId, @RequestParam(name = "menuId", required = false) String menuId) {
+ oAuth2ClientService.updateMenuInit(clientId, menuId);
+ return new SuccessResult();
+ }
+
+ @ApiOperation(value = "清除客户端菜单", notes = "清除客户端菜单菜单")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "clientId", value = "Oauth客户端ID", paramType = "path")
+ })
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @PutMapping("update-menu-empty/{clientId}")
+ public SuccessResult updateMenuEmpty(@PathVariable("clientId") String clientId) {
+ oAuth2ClientService.updateMenuEmpty(clientId);
+ return new SuccessResult();
+ }
+
+ @ApiOperation(value = "Oauth客户端初始化数据", notes = "Oauth客户端初始化数据接口")
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @GetMapping("get-init")
+ public OAuth2ClientDTO getInitClient() throws Exception {
+ return oAuth2ClientService.getInit();
+ }
+
+
+}
diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/controller/route/OAuth2ClientRouteController.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/controller/route/OAuth2ClientRouteController.java
new file mode 100644
index 00000000..57930177
--- /dev/null
+++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/controller/route/OAuth2ClientRouteController.java
@@ -0,0 +1,37 @@
+package ink.wgink.login.oauth2.server.controller.route;
+
+import ink.wgink.interfaces.consts.ISystemConstant;
+import io.swagger.annotations.Api;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.servlet.ModelAndView;
+
+/**
+ * @ClassName: OAuth2ClientRouteController
+ * @Description: oAuth2客户端
+ * @Author: wanggeng
+ * @Date: 2021/9/15 9:36 下午
+ * @Version: 1.0
+ */
+@Api(tags = ISystemConstant.API_TAGS_APP_ROUTE_PREFIX + "Oauth客户端")
+@RestController
+@RequestMapping(ISystemConstant.ROUTE_PREFIX + "/oauth2client")
+public class OAuth2ClientRouteController {
+
+ @GetMapping("list")
+ public ModelAndView list() {
+ return new ModelAndView("oauth2client/list");
+ }
+
+ @GetMapping("save")
+ public ModelAndView save() {
+ return new ModelAndView("oauth2client/save");
+ }
+
+ @GetMapping("update")
+ public ModelAndView update() {
+ return new ModelAndView("oauth2client/update");
+ }
+
+}
diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/converter/UserAccessTokenConverter.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/converter/UserAccessTokenConverter.java
new file mode 100644
index 00000000..2844927e
--- /dev/null
+++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/converter/UserAccessTokenConverter.java
@@ -0,0 +1,22 @@
+package ink.wgink.login.oauth2.server.converter;
+
+import ink.wgink.service.user.service.IUserService;
+import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
+
+/**
+ * @ClassName: UserAccessTokenConverter
+ * @Description: 用户jwt token
+ * @Author: WangGeng
+ * @Date: 2019/2/28 3:26 PM
+ * @Version: 1.0
+ **/
+public class UserAccessTokenConverter extends DefaultAccessTokenConverter {
+
+ public UserAccessTokenConverter(IUserService userService) {
+ super();
+ UserAuthConverter userAuthConverter = new UserAuthConverter();
+ userAuthConverter.setUserService(userService);
+ super.setUserTokenConverter(userAuthConverter);
+ }
+
+}
diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/converter/UserAuthConverter.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/converter/UserAuthConverter.java
new file mode 100644
index 00000000..e6e5d14f
--- /dev/null
+++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/converter/UserAuthConverter.java
@@ -0,0 +1,104 @@
+package ink.wgink.login.oauth2.server.converter;
+
+import ink.wgink.interfaces.consts.ISystemConstant;
+import ink.wgink.interfaces.role.IRoleBaseService;
+import ink.wgink.pojo.bos.LoginUser;
+import ink.wgink.pojo.bos.UserInfoBO;
+import ink.wgink.pojo.dtos.user.UserAttrInfoDTO;
+import ink.wgink.service.user.service.IUserService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.oauth2.provider.token.UserAuthenticationConverter;
+
+import java.util.*;
+
+/**
+ * @ClassName: UserAuthConverter
+ * @Description: 重写用户认证
+ * @Author: WangGeng
+ * @Date: 2019/2/27 4:57 PM
+ * @Version: 1.0
+ **/
+public class UserAuthConverter implements UserAuthenticationConverter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(UserAuthConverter.class);
+ private IUserService userService;
+
+ public UserAuthConverter() {
+ }
+
+ @Override
+ public Map convertUserAuthentication(Authentication authentication) {
+ Map response = new LinkedHashMap<>();
+ response.put("user_name", authentication.getName());
+ // 删除token中的权限信息,通过客户端请求获取,减少accessToken长度
+ LoginUser loginUser = (LoginUser) authentication.getPrincipal();
+ // 传递登录用户
+ Map userInfo = new HashMap<>(4);
+ userInfo.put("userId", loginUser.getUserId());
+ userInfo.put("username", loginUser.getUsername());
+ userInfo.put("userName", loginUser.getUserName());
+ userInfo.put("userPhone", loginUser.getUserPhone());
+ userInfo.put("userAvatar", loginUser.getUserAvatar());
+ userInfo.put("userEmail", loginUser.getUserEmail());
+ userInfo.put("roles", loginUser.getRoles());
+ userInfo.put("departments", loginUser.getDepartments());
+ userInfo.put("groups", loginUser.getGroups());
+ userInfo.put("getPositions", loginUser.getPositions());
+ userInfo.put("expandData", loginUser.getExpandData());
+ response.put("user_info", userInfo);
+ return response;
+ }
+
+ @Override
+ public Authentication extractAuthentication(Map map) {
+ // 解析客户端的权限请求
+ Object principal = map.get("user_name");
+ if (!Objects.isNull(principal)) {
+ Collection authorities;
+ String userName = principal.toString();
+ // 包含用户信息,则直接抽取其中的用户信息
+ Map, ?> userInfo = (Map) map.get("user_info");
+
+ UserInfoBO userInfoBO = new UserInfoBO();
+ userInfoBO.setUserId(userInfo.get("userId").toString());
+ userInfoBO.setUserUsername(userInfo.get("username").toString());
+ userInfoBO.setUserName(userInfo.get("userName").toString());
+ userInfoBO.setUserPhone(userInfo.get("userPhone") == null ? "" : userInfo.get("userPhone").toString());
+ userInfoBO.setUserAvatar(userInfo.get("userAvatar") == null ? "" : userInfo.get("userAvatar").toString());
+ userInfoBO.setUserEmail(userInfo.get("userEmail") == null ? "" : userInfo.get("userEmail").toString());
+ userInfoBO.
+ if (ISystemConstant.ADMIN.equals(userName)) {
+ } else {
+ UserAttrInfoDTO userAttrInfoDTO = userService.getUserAttrInfoByUserId(userInfoBO.getUserId());
+ userInfoBO.setDepartments(userAttrInfoDTO.getDepartments());
+ userInfoBO.setRoles(userAttrInfoDTO.getRoles());
+ userInfoBO.setGroups(userAttrInfoDTO.getGroups());
+ userInfoBO.setPositions(userAttrInfoDTO.getPositions());
+ userInfoBO.setDataAuthority(userAttrInfoDTO.getDataAuthority());
+ userInfoBO.setDataAuthorityUserIds(userAttrInfoDTO.getDataAuthorityUserIds());
+ userInfoBO.setBaseDepartmentIds(userAttrInfoDTO.getBaseDepartmentIds());
+
+
+ // 设置权限
+ authorities = getAuthorities(userAttrInfoDTO.getRoles());
+ }
+ principal = userInfoBO;
+ LOG.debug("获取用户权限");
+ return new UsernamePasswordAuthenticationToken(principal, "N/A", authorities);
+ } else {
+ return null;
+ }
+ }
+
+ public IUserService getUserService() {
+ return userService;
+ }
+
+ public void setUserService(IUserService userService) {
+ this.userService = userService;
+ }
+}
diff --git a/service-oauth-client/src/main/java/ink/wgink/module/oauth/client/dao/IOauthClientDao.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/dao/IOAuth2ClientDao.java
similarity index 68%
rename from service-oauth-client/src/main/java/ink/wgink/module/oauth/client/dao/IOauthClientDao.java
rename to login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/dao/IOAuth2ClientDao.java
index 656555a1..cb7b811b 100644
--- a/service-oauth-client/src/main/java/ink/wgink/module/oauth/client/dao/IOauthClientDao.java
+++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/dao/IOAuth2ClientDao.java
@@ -1,11 +1,13 @@
-package ink.wgink.module.oauth.client.dao;
+package ink.wgink.login.oauth2.server.dao;
import ink.wgink.exceptions.RemoveException;
import ink.wgink.exceptions.SaveException;
import ink.wgink.exceptions.SearchException;
import ink.wgink.exceptions.UpdateException;
-import ink.wgink.pojo.dtos.oauth.client.OauthClientDTO;
-import ink.wgink.pojo.dtos.oauth.client.OauthClientSimpleDTO;
+import ink.wgink.interfaces.init.IInitBaseTable;
+import ink.wgink.login.oauth2.server.pojo.dtos.OAuth2ClientDTO;
+import ink.wgink.login.oauth2.server.pojo.dtos.OAuth2ClientSimpleDTO;
+import ink.wgink.login.oauth2.server.pojo.pos.OAuth2ClientPO;
import org.springframework.stereotype.Repository;
import java.util.List;
@@ -19,7 +21,7 @@ import java.util.Map;
* @Version: 1.0
**/
@Repository
-public interface IOauthClientDao {
+public interface IOAuth2ClientDao extends IInitBaseTable {
/**
* Oauth客户端新增
@@ -52,7 +54,7 @@ public interface IOauthClientDao {
* @return
* @throws SearchException
*/
- List list(Map params) throws SearchException;
+ List list(Map params) throws SearchException;
/**
* Oauth客户端列表(简单)
@@ -61,7 +63,7 @@ public interface IOauthClientDao {
* @return
* @throws SearchException
*/
- List listSimple(Map params) throws SearchException;
+ List listSimple(Map params) throws SearchException;
/**
* OauthClient详情
@@ -70,7 +72,16 @@ public interface IOauthClientDao {
* @return
* @throws SearchException
*/
- OauthClientDTO get(Map params) throws SearchException;
+ OAuth2ClientDTO get(Map params) throws SearchException;
+
+ /**
+ * 获取Oauth客户端(单表)
+ *
+ * @param params
+ * @return
+ * @throws SearchException
+ */
+ OAuth2ClientPO getPO(Map params) throws SearchException;
/**
* Oauth客户端统计
@@ -82,18 +93,11 @@ public interface IOauthClientDao {
Integer count(Map params) throws SearchException;
/**
- * 清除Oauth客户端菜单
+ * 更新菜单
*
* @param params
* @throws UpdateException
*/
- void updateMenuEmpty(Map params) throws UpdateException;
+ void updateMenu(Map params) throws UpdateException;
- /**
- * 获取Oauth客户端(单表)
- * @param params
- * @return
- * @throws SearchException
- */
- OauthClientDTO getSimple(Map params) throws SearchException;
}
diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/exceptions/OAuth2ClientBadClientCredentialsException.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/exceptions/OAuth2ClientBadClientCredentialsException.java
new file mode 100644
index 00000000..4cf6fb3c
--- /dev/null
+++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/exceptions/OAuth2ClientBadClientCredentialsException.java
@@ -0,0 +1,31 @@
+package ink.wgink.login.oauth2.server.exceptions;
+
+import org.springframework.security.oauth2.common.exceptions.ClientAuthenticationException;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: ClientBadClientCredentialsException
+ * @Description: 认证失败异常
+ * @Author: WangGeng
+ * @Date: 2020/7/23 11:11 下午
+ * @Version: 1.0
+ **/
+public class OAuth2ClientBadClientCredentialsException extends ClientAuthenticationException {
+
+ public OAuth2ClientBadClientCredentialsException(String msg) {
+ super(msg);
+ }
+
+ @Override
+ public int getHttpErrorCode() {
+ return 401;
+ }
+
+ @Override
+ public String getOAuth2ErrorCode() {
+ return "invalid_client";
+ }
+
+}
diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/exceptions/OAuth2ClientExpireException.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/exceptions/OAuth2ClientExpireException.java
new file mode 100644
index 00000000..20d8d4c6
--- /dev/null
+++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/exceptions/OAuth2ClientExpireException.java
@@ -0,0 +1,25 @@
+package ink.wgink.login.oauth2.server.exceptions;
+
+import org.springframework.security.oauth2.provider.ClientRegistrationException;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: ClientExpireException
+ * @Description: 客户端超时异常
+ * @Author: WangGeng
+ * @Date: 2020/7/22 8:08 下午
+ * @Version: 1.0
+ **/
+public class OAuth2ClientExpireException extends ClientRegistrationException {
+
+ public OAuth2ClientExpireException(String msg) {
+ super(msg);
+ }
+
+ public OAuth2ClientExpireException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+
+}
diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/exceptions/OAuth2ClientStateException.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/exceptions/OAuth2ClientStateException.java
new file mode 100644
index 00000000..04eff58a
--- /dev/null
+++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/exceptions/OAuth2ClientStateException.java
@@ -0,0 +1,24 @@
+package ink.wgink.login.oauth2.server.exceptions;
+
+import org.springframework.security.oauth2.provider.ClientRegistrationException;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: ClientStateException
+ * @Description: 客户端状态异常
+ * @Author: WangGeng
+ * @Date: 2020/7/22 10:31 下午
+ * @Version: 1.0
+ **/
+public class OAuth2ClientStateException extends ClientRegistrationException {
+
+ public OAuth2ClientStateException(String msg) {
+ super(msg);
+ }
+
+ public OAuth2ClientStateException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+}
diff --git a/service-oauth-client/src/main/java/ink/wgink/module/oauth/client/pojo/vos/OauthClientVO.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/pojo/dtos/OAuth2ClientDTO.java
similarity index 76%
rename from service-oauth-client/src/main/java/ink/wgink/module/oauth/client/pojo/vos/OauthClientVO.java
rename to login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/pojo/dtos/OAuth2ClientDTO.java
index 4cd680a3..26d9efcb 100644
--- a/service-oauth-client/src/main/java/ink/wgink/module/oauth/client/pojo/vos/OauthClientVO.java
+++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/pojo/dtos/OAuth2ClientDTO.java
@@ -1,22 +1,18 @@
-package ink.wgink.module.oauth.client.pojo.vos;
+package ink.wgink.login.oauth2.server.pojo.dtos;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
- * @ClassName: OauthClientVO
+ * @ClassName: OauthClientDTO
* @Description: 授权认证客户端
* @Author: wenc
* @Date: 2019/1/8 7:43 PM
* @Version: 1.0
**/
@ApiModel
-public class OauthClientVO {
+public class OAuth2ClientDTO extends OAuth2ClientSimpleDTO {
- @ApiModelProperty(name = "clientId", value = "客户端ID")
- private String clientId;
- @ApiModelProperty(name = "clientName", value = "客户端名称")
- private String clientName;
@ApiModelProperty(name = "resourceIds", value = "资源ID列表")
private String resourceIds;
@ApiModelProperty(name = "clientSecret", value = "客户端密码")
@@ -25,8 +21,6 @@ public class OauthClientVO {
private String scope;
@ApiModelProperty(name = "authorizedGrantTypes", value = "授权类型")
private String authorizedGrantTypes;
- @ApiModelProperty(name = "webServerRedirectUri", value = "重定向链接")
- private String webServerRedirectUri;
@ApiModelProperty(name = "authorities", value = "权限")
private String authorities;
@ApiModelProperty(name = "accessTokenValidity", value = "访问令牌时效")
@@ -37,6 +31,10 @@ public class OauthClientVO {
private String additionalInformation;
@ApiModelProperty(name = "autoapprove", value = "自动授权")
private String autoapprove;
+ @ApiModelProperty(name = "menuId", value = "菜单ID")
+ private String menuId;
+ @ApiModelProperty(name = "menuName", value = "菜单名称")
+ private String menuName;
@ApiModelProperty(name = "environment", value = "系统环境")
private String environment;
@ApiModelProperty(name = "systemType", value = "系统类型")
@@ -49,25 +47,11 @@ public class OauthClientVO {
private String systemSummary;
@ApiModelProperty(name = "systemIcon", value = "系统图标")
private String systemIcon;
-
- public String getClientId() {
- return clientId == null ? null : clientId.trim();
- }
-
- public void setClientId(String clientId) {
- this.clientId = clientId;
- }
-
- public String getClientName() {
- return clientName == null ? null : clientName.trim();
- }
-
- public void setClientName(String clientName) {
- this.clientName = clientName;
- }
+ @ApiModelProperty(name = "gmtCreate", value = "创建时间")
+ private String gmtCreate;
public String getResourceIds() {
- return resourceIds == null ? null : resourceIds.trim();
+ return resourceIds == null ? "" : resourceIds.trim();
}
public void setResourceIds(String resourceIds) {
@@ -75,7 +59,7 @@ public class OauthClientVO {
}
public String getClientSecret() {
- return clientSecret == null ? null : clientSecret.trim();
+ return clientSecret == null ? "" : clientSecret.trim();
}
public void setClientSecret(String clientSecret) {
@@ -83,7 +67,7 @@ public class OauthClientVO {
}
public String getScope() {
- return scope == null ? null : scope.trim();
+ return scope == null ? "" : scope.trim();
}
public void setScope(String scope) {
@@ -91,23 +75,15 @@ public class OauthClientVO {
}
public String getAuthorizedGrantTypes() {
- return authorizedGrantTypes == null ? null : authorizedGrantTypes.trim();
+ return authorizedGrantTypes == null ? "" : authorizedGrantTypes.trim();
}
public void setAuthorizedGrantTypes(String authorizedGrantTypes) {
this.authorizedGrantTypes = authorizedGrantTypes;
}
- public String getWebServerRedirectUri() {
- return webServerRedirectUri == null ? null : webServerRedirectUri.trim();
- }
-
- public void setWebServerRedirectUri(String webServerRedirectUri) {
- this.webServerRedirectUri = webServerRedirectUri;
- }
-
public String getAuthorities() {
- return authorities == null ? null : authorities.trim();
+ return authorities == null ? "" : authorities.trim();
}
public void setAuthorities(String authorities) {
@@ -131,7 +107,7 @@ public class OauthClientVO {
}
public String getAdditionalInformation() {
- return additionalInformation == null ? null : additionalInformation.trim();
+ return additionalInformation == null ? "" : additionalInformation.trim();
}
public void setAdditionalInformation(String additionalInformation) {
@@ -139,13 +115,29 @@ public class OauthClientVO {
}
public String getAutoapprove() {
- return autoapprove == null ? null : autoapprove.trim();
+ return autoapprove == null ? "" : autoapprove.trim();
}
public void setAutoapprove(String autoapprove) {
this.autoapprove = autoapprove;
}
+ public String getMenuId() {
+ return menuId == null ? "" : menuId.trim();
+ }
+
+ public void setMenuId(String menuId) {
+ this.menuId = menuId;
+ }
+
+ public String getMenuName() {
+ return menuName == null ? "" : menuName.trim();
+ }
+
+ public void setMenuName(String menuName) {
+ this.menuName = menuName;
+ }
+
public String getEnvironment() {
return environment == null ? "" : environment.trim();
}
@@ -194,14 +186,20 @@ public class OauthClientVO {
this.systemIcon = systemIcon;
}
+ @Override
+ public String getGmtCreate() {
+ return gmtCreate == null ? "" : gmtCreate.trim();
+ }
+
+ @Override
+ public void setGmtCreate(String gmtCreate) {
+ this.gmtCreate = gmtCreate;
+ }
+
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
- sb.append("\"clientId\":")
- .append("\"").append(clientId).append("\"");
- sb.append(",\"clientName\":")
- .append("\"").append(clientName).append("\"");
- sb.append(",\"resourceIds\":")
+ sb.append("\"resourceIds\":")
.append("\"").append(resourceIds).append("\"");
sb.append(",\"clientSecret\":")
.append("\"").append(clientSecret).append("\"");
@@ -209,8 +207,6 @@ public class OauthClientVO {
.append("\"").append(scope).append("\"");
sb.append(",\"authorizedGrantTypes\":")
.append("\"").append(authorizedGrantTypes).append("\"");
- sb.append(",\"webServerRedirectUri\":")
- .append("\"").append(webServerRedirectUri).append("\"");
sb.append(",\"authorities\":")
.append("\"").append(authorities).append("\"");
sb.append(",\"accessTokenValidity\":")
@@ -221,6 +217,10 @@ public class OauthClientVO {
.append("\"").append(additionalInformation).append("\"");
sb.append(",\"autoapprove\":")
.append("\"").append(autoapprove).append("\"");
+ sb.append(",\"menuId\":")
+ .append("\"").append(menuId).append("\"");
+ sb.append(",\"menuName\":")
+ .append("\"").append(menuName).append("\"");
sb.append(",\"environment\":")
.append("\"").append(environment).append("\"");
sb.append(",\"systemType\":")
@@ -233,6 +233,8 @@ public class OauthClientVO {
.append("\"").append(systemSummary).append("\"");
sb.append(",\"systemIcon\":")
.append("\"").append(systemIcon).append("\"");
+ sb.append(",\"gmtCreate\":")
+ .append("\"").append(gmtCreate).append("\"");
sb.append('}');
return sb.toString();
}
diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/pojo/dtos/OAuth2ClientSimpleDTO.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/pojo/dtos/OAuth2ClientSimpleDTO.java
new file mode 100644
index 00000000..5732f8a1
--- /dev/null
+++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/pojo/dtos/OAuth2ClientSimpleDTO.java
@@ -0,0 +1,77 @@
+package ink.wgink.login.oauth2.server.pojo.dtos;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: OauthClientSimpleDTO
+ * @Description: 客户端简单信息
+ * @Author: WangGeng
+ * @Date: 2020/7/17 18:18
+ * @Version: 1.0
+ **/
+@ApiModel
+public class OAuth2ClientSimpleDTO implements Serializable {
+
+ private static final long serialVersionUID = -1552124710719004198L;
+ @ApiModelProperty(name = "clientId", value = "客户端ID")
+ private String clientId;
+ @ApiModelProperty(name = "clientName", value = "客户端名称")
+ private String clientName;
+ @ApiModelProperty(name = "webServerRedirectUri", value = "重定向链接")
+ private String webServerRedirectUri;
+ @ApiModelProperty(name = "gmtCreate", value = "创建时间")
+ private String gmtCreate;
+
+ public String getClientId() {
+ return clientId == null ? "" : clientId.trim();
+ }
+
+ public void setClientId(String clientId) {
+ this.clientId = clientId;
+ }
+
+ public String getClientName() {
+ return clientName == null ? "" : clientName.trim();
+ }
+
+ public void setClientName(String clientName) {
+ this.clientName = clientName;
+ }
+
+ public String getWebServerRedirectUri() {
+ return webServerRedirectUri == null ? "" : webServerRedirectUri.trim();
+ }
+
+ public void setWebServerRedirectUri(String webServerRedirectUri) {
+ this.webServerRedirectUri = webServerRedirectUri;
+ }
+
+ public String getGmtCreate() {
+ return gmtCreate == null ? "" : gmtCreate.trim();
+ }
+
+ public void setGmtCreate(String gmtCreate) {
+ this.gmtCreate = gmtCreate;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("{");
+ sb.append("\"clientId\":\"")
+ .append(clientId).append('\"');
+ sb.append(",\"clientName\":\"")
+ .append(clientName).append('\"');
+ sb.append(",\"webServerRedirectUri\":\"")
+ .append(webServerRedirectUri).append('\"');
+ sb.append(",\"gmtCreate\":\"")
+ .append(gmtCreate).append('\"');
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/pojo/pos/OAuth2ClientPO.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/pojo/pos/OAuth2ClientPO.java
new file mode 100644
index 00000000..3876bd08
--- /dev/null
+++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/pojo/pos/OAuth2ClientPO.java
@@ -0,0 +1,207 @@
+package ink.wgink.login.oauth2.server.pojo.pos;
+
+import ink.wgink.login.oauth2.server.pojo.dtos.OAuth2ClientSimpleDTO;
+import io.swagger.annotations.ApiModel;
+
+/**
+ * @ClassName: OauthClientDTO
+ * @Description: 授权认证客户端
+ * @Author: wenc
+ * @Date: 2019/1/8 7:43 PM
+ * @Version: 1.0
+ **/
+@ApiModel
+public class OAuth2ClientPO extends OAuth2ClientSimpleDTO {
+
+ private String resourceIds;
+ private String clientSecret;
+ private String scope;
+ private String authorizedGrantTypes;
+ private String authorities;
+ private Integer accessTokenValidity;
+ private Integer refreshTokenValidity;
+ private String additionalInformation;
+ private String autoapprove;
+ private String menuId;
+ private String environment;
+ private String systemType;
+ private String systemState;
+ private String expireTime;
+ private String systemSummary;
+ private String systemIcon;
+ private String gmtCreate;
+ private String creator;
+ private String gmtModified;
+ private String modifier;
+ private Integer isDelete;
+
+ public String getResourceIds() {
+ return resourceIds == null ? "" : resourceIds.trim();
+ }
+
+ public void setResourceIds(String resourceIds) {
+ this.resourceIds = resourceIds;
+ }
+
+ public String getClientSecret() {
+ return clientSecret == null ? "" : clientSecret.trim();
+ }
+
+ public void setClientSecret(String clientSecret) {
+ this.clientSecret = clientSecret;
+ }
+
+ public String getScope() {
+ return scope == null ? "" : scope.trim();
+ }
+
+ public void setScope(String scope) {
+ this.scope = scope;
+ }
+
+ public String getAuthorizedGrantTypes() {
+ return authorizedGrantTypes == null ? "" : authorizedGrantTypes.trim();
+ }
+
+ public void setAuthorizedGrantTypes(String authorizedGrantTypes) {
+ this.authorizedGrantTypes = authorizedGrantTypes;
+ }
+
+ public String getAuthorities() {
+ return authorities == null ? "" : authorities.trim();
+ }
+
+ public void setAuthorities(String authorities) {
+ this.authorities = authorities;
+ }
+
+ public Integer getAccessTokenValidity() {
+ return accessTokenValidity == null ? 0 : accessTokenValidity;
+ }
+
+ public void setAccessTokenValidity(Integer accessTokenValidity) {
+ this.accessTokenValidity = accessTokenValidity;
+ }
+
+ public Integer getRefreshTokenValidity() {
+ return refreshTokenValidity == null ? 0 : refreshTokenValidity;
+ }
+
+ public void setRefreshTokenValidity(Integer refreshTokenValidity) {
+ this.refreshTokenValidity = refreshTokenValidity;
+ }
+
+ public String getAdditionalInformation() {
+ return additionalInformation == null ? "" : additionalInformation.trim();
+ }
+
+ public void setAdditionalInformation(String additionalInformation) {
+ this.additionalInformation = additionalInformation;
+ }
+
+ public String getAutoapprove() {
+ return autoapprove == null ? "" : autoapprove.trim();
+ }
+
+ public void setAutoapprove(String autoapprove) {
+ this.autoapprove = autoapprove;
+ }
+
+ public String getMenuId() {
+ return menuId == null ? "" : menuId.trim();
+ }
+
+ public void setMenuId(String menuId) {
+ this.menuId = menuId;
+ }
+
+ public String getEnvironment() {
+ return environment == null ? "" : environment.trim();
+ }
+
+ public void setEnvironment(String environment) {
+ this.environment = environment;
+ }
+
+ public String getSystemType() {
+ return systemType == null ? "" : systemType.trim();
+ }
+
+ public void setSystemType(String systemType) {
+ this.systemType = systemType;
+ }
+
+ public String getSystemState() {
+ return systemState == null ? "" : systemState.trim();
+ }
+
+ public void setSystemState(String systemState) {
+ this.systemState = systemState;
+ }
+
+ public String getExpireTime() {
+ return expireTime == null ? "" : expireTime.trim();
+ }
+
+ public void setExpireTime(String expireTime) {
+ this.expireTime = expireTime;
+ }
+
+ public String getSystemSummary() {
+ return systemSummary == null ? "" : systemSummary.trim();
+ }
+
+ public void setSystemSummary(String systemSummary) {
+ this.systemSummary = systemSummary;
+ }
+
+ public String getSystemIcon() {
+ return systemIcon == null ? "" : systemIcon.trim();
+ }
+
+ public void setSystemIcon(String systemIcon) {
+ this.systemIcon = systemIcon;
+ }
+
+ @Override
+ public String getGmtCreate() {
+ return gmtCreate == null ? "" : gmtCreate.trim();
+ }
+
+ @Override
+ public void setGmtCreate(String gmtCreate) {
+ this.gmtCreate = gmtCreate;
+ }
+
+ public String getCreator() {
+ return creator == null ? "" : creator.trim();
+ }
+
+ public void setCreator(String creator) {
+ this.creator = creator;
+ }
+
+ public String getGmtModified() {
+ return gmtModified == null ? "" : gmtModified.trim();
+ }
+
+ public void setGmtModified(String gmtModified) {
+ this.gmtModified = gmtModified;
+ }
+
+ public String getModifier() {
+ return modifier == null ? "" : modifier.trim();
+ }
+
+ public void setModifier(String modifier) {
+ this.modifier = modifier;
+ }
+
+ public Integer getIsDelete() {
+ return isDelete == null ? 0 : isDelete;
+ }
+
+ public void setIsDelete(Integer isDelete) {
+ this.isDelete = isDelete;
+ }
+}
diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/pojo/vos/OAuth2ClientVO.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/pojo/vos/OAuth2ClientVO.java
new file mode 100644
index 00000000..5d1e0968
--- /dev/null
+++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/pojo/vos/OAuth2ClientVO.java
@@ -0,0 +1,208 @@
+package ink.wgink.login.oauth2.server.pojo.vos;
+
+import ink.wgink.annotation.CheckEmptyAnnotation;
+import ink.wgink.annotation.CheckNumberAnnotation;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @ClassName: OauthClientVO
+ * @Description: 授权认证客户端
+ * @Author: wenc
+ * @Date: 2019/1/8 7:43 PM
+ * @Version: 1.0
+ **/
+@ApiModel
+public class OAuth2ClientVO {
+
+ @ApiModelProperty(name = "clientId", value = "客户端ID")
+ @CheckEmptyAnnotation(name = "客户端ID")
+ private String clientId;
+ @ApiModelProperty(name = "clientName", value = "客户端名称")
+ @CheckEmptyAnnotation(name = "客户端名称")
+ private String clientName;
+ @ApiModelProperty(name = "resourceIds", value = "资源ID列表")
+ private String resourceIds;
+ @ApiModelProperty(name = "clientSecret", value = "客户端密码")
+ @CheckEmptyAnnotation(name = "客户端密码")
+ private String clientSecret;
+ @ApiModelProperty(name = "scope", value = "范围")
+ @CheckEmptyAnnotation(name = "范围")
+ private String scope;
+ @ApiModelProperty(name = "authorizedGrantTypes", value = "授权类型")
+ @CheckEmptyAnnotation(name = "授权类型")
+ private String authorizedGrantTypes;
+ @ApiModelProperty(name = "webServerRedirectUri", value = "重定向链接")
+ @CheckEmptyAnnotation(name = "重定向链接")
+ private String webServerRedirectUri;
+ @ApiModelProperty(name = "authorities", value = "权限")
+ @CheckEmptyAnnotation(name = "权限")
+ private String authorities;
+ @ApiModelProperty(name = "accessTokenValidity", value = "访问令牌时效")
+ @CheckNumberAnnotation(name = "访问令牌时效", min = 0)
+ private Integer accessTokenValidity;
+ @ApiModelProperty(name = "refreshTokenValidity", value = "刷新令牌时效")
+ @CheckNumberAnnotation(name = "刷新令牌时效", min = 0)
+ private Integer refreshTokenValidity;
+ @ApiModelProperty(name = "additionalInformation", value = "附加信息")
+ private String additionalInformation;
+ @ApiModelProperty(name = "autoapprove", value = "自动授权")
+ private String autoapprove;
+ @ApiModelProperty(name = "environment", value = "系统环境")
+ @CheckEmptyAnnotation(name = "系统环境")
+ private String environment;
+ @ApiModelProperty(name = "systemType", value = "系统类型")
+ private String systemType;
+ @ApiModelProperty(name = "systemState", value = "系统状态")
+ private String systemState;
+ @ApiModelProperty(name = "expireTime", value = "系统到期时间")
+ private String expireTime;
+ @ApiModelProperty(name = "systemSummary", value = "系统介绍")
+ private String systemSummary;
+ @ApiModelProperty(name = "systemIcon", value = "系统图标")
+ private String systemIcon;
+
+ public String getClientId() {
+ return clientId == null ? "" : clientId.trim();
+ }
+
+ public void setClientId(String clientId) {
+ this.clientId = clientId;
+ }
+
+ public String getClientName() {
+ return clientName == null ? "" : clientName.trim();
+ }
+
+ public void setClientName(String clientName) {
+ this.clientName = clientName;
+ }
+
+ public String getResourceIds() {
+ return resourceIds == null ? "" : resourceIds.trim();
+ }
+
+ public void setResourceIds(String resourceIds) {
+ this.resourceIds = resourceIds;
+ }
+
+ public String getClientSecret() {
+ return clientSecret == null ? "" : clientSecret.trim();
+ }
+
+ public void setClientSecret(String clientSecret) {
+ this.clientSecret = clientSecret;
+ }
+
+ public String getScope() {
+ return scope == null ? "" : scope.trim();
+ }
+
+ public void setScope(String scope) {
+ this.scope = scope;
+ }
+
+ public String getAuthorizedGrantTypes() {
+ return authorizedGrantTypes == null ? "" : authorizedGrantTypes.trim();
+ }
+
+ public void setAuthorizedGrantTypes(String authorizedGrantTypes) {
+ this.authorizedGrantTypes = authorizedGrantTypes;
+ }
+
+ public String getWebServerRedirectUri() {
+ return webServerRedirectUri == null ? "" : webServerRedirectUri.trim();
+ }
+
+ public void setWebServerRedirectUri(String webServerRedirectUri) {
+ this.webServerRedirectUri = webServerRedirectUri;
+ }
+
+ public String getAuthorities() {
+ return authorities == null ? "" : authorities.trim();
+ }
+
+ public void setAuthorities(String authorities) {
+ this.authorities = authorities;
+ }
+
+ public Integer getAccessTokenValidity() {
+ return accessTokenValidity == null ? 0 : accessTokenValidity;
+ }
+
+ public void setAccessTokenValidity(Integer accessTokenValidity) {
+ this.accessTokenValidity = accessTokenValidity;
+ }
+
+ public Integer getRefreshTokenValidity() {
+ return refreshTokenValidity == null ? 0 : refreshTokenValidity;
+ }
+
+ public void setRefreshTokenValidity(Integer refreshTokenValidity) {
+ this.refreshTokenValidity = refreshTokenValidity;
+ }
+
+ public String getAdditionalInformation() {
+ return additionalInformation == null ? "" : additionalInformation.trim();
+ }
+
+ public void setAdditionalInformation(String additionalInformation) {
+ this.additionalInformation = additionalInformation;
+ }
+
+ public String getAutoapprove() {
+ return autoapprove == null ? "true" : autoapprove.trim();
+ }
+
+ public void setAutoapprove(String autoapprove) {
+ this.autoapprove = autoapprove;
+ }
+
+ public String getEnvironment() {
+ return environment == null ? "" : environment.trim();
+ }
+
+ public void setEnvironment(String environment) {
+ this.environment = environment;
+ }
+
+ public String getSystemType() {
+ return systemType == null ? "" : systemType.trim();
+ }
+
+ public void setSystemType(String systemType) {
+ this.systemType = systemType;
+ }
+
+ public String getSystemState() {
+ return systemState == null ? "" : systemState.trim();
+ }
+
+ public void setSystemState(String systemState) {
+ this.systemState = systemState;
+ }
+
+ public String getExpireTime() {
+ return expireTime == null ? "" : expireTime.trim();
+ }
+
+ public void setExpireTime(String expireTime) {
+ this.expireTime = expireTime;
+ }
+
+ public String getSystemSummary() {
+ return systemSummary == null ? "" : systemSummary.trim();
+ }
+
+ public void setSystemSummary(String systemSummary) {
+ this.systemSummary = systemSummary;
+ }
+
+ public String getSystemIcon() {
+ return systemIcon == null ? "" : systemIcon.trim();
+ }
+
+ public void setSystemIcon(String systemIcon) {
+ this.systemIcon = systemIcon;
+ }
+}
diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/IOAuth2ClientService.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/IOAuth2ClientService.java
new file mode 100644
index 00000000..fdc50612
--- /dev/null
+++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/IOAuth2ClientService.java
@@ -0,0 +1,172 @@
+package ink.wgink.login.oauth2.server.service;
+
+import ink.wgink.login.oauth2.server.pojo.dtos.OAuth2ClientDTO;
+import ink.wgink.login.oauth2.server.pojo.dtos.OAuth2ClientSimpleDTO;
+import ink.wgink.login.oauth2.server.pojo.pos.OAuth2ClientPO;
+import ink.wgink.login.oauth2.server.pojo.vos.OAuth2ClientVO;
+import ink.wgink.pojo.ListPage;
+import ink.wgink.pojo.result.SuccessResultList;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName: IOauthClientService
+ * @Description: Oauth客户端
+ * @Author: WangGeng
+ * @Date: 2019/3/12 11:40 AM
+ * @Version: 1.0
+ **/
+public interface IOAuth2ClientService {
+
+ /**
+ * 客户端加密规则
+ */
+ String OAUTH_CLIENT_RULE = "WGINK_OAUTH2_CLIENT";
+ /**
+ * 正常环境
+ */
+ String OAUTH_CLIENT_ENVIRONMENT_FORMAL = "formal";
+ /**
+ * 测试环境
+ */
+ String OAUTH_CLIENT_ENVIRONMENT_TEST = "test";
+ /**
+ * 内部系统
+ */
+ String OAUTH_CLIENT_SYSTEM_TYPE_WITHIN = "within";
+ /**
+ * 三方系统
+ */
+ String OAUTH_CLIENT_SYSTEM_TYPE_THIRD = "third";
+ /**
+ * 状态正常
+ */
+ String OAUTH_CLIENT_SYSTEM_STATE_NORMAL = "normal";
+ /**
+ * 状态锁定
+ */
+ String OAUTH_CLIENT_SYSTEM_STATE_LOCKING = "locking";
+
+ /**
+ * Oauth客户端新增
+ *
+ * @param params
+ * @return
+ * @throws Exception
+ */
+ void save(OAuth2ClientVO oauth2ClientVO) throws Exception;
+
+ /**
+ * Oauth客户端修改
+ *
+ * @param ids
+ * @return
+ */
+ void remove(List ids);
+
+ /**
+ * Oauth客户端修改
+ *
+ * @param clientId
+ * @param oauth2ClientVO
+ * @return
+ * @throws Exception
+ */
+ void update(String clientId, OAuth2ClientVO oauth2ClientVO) throws Exception;
+
+ /**
+ * Oauth 更新初始化菜单
+ *
+ * @param clientId
+ * @param menuId
+ * @return
+ */
+ void updateMenuInit(String clientId, String menuId);
+
+ /**
+ * 清空Oauth客户端菜单
+ *
+ * @param clientId
+ * @return
+ */
+ void updateMenuEmpty(String clientId);
+
+ /**
+ * Oauth客户端列表
+ *
+ * @param params
+ * @return
+ */
+ List list(Map params);
+
+
+ /**
+ * Oauth客户端列表(简单)
+ *
+ * @param params
+ * @return
+ */
+ List listSimple(Map params);
+
+ /**
+ * easyUI Oauth客户端列表
+ *
+ * @param page
+ * @return
+ */
+ SuccessResultList> listPage(ListPage page);
+
+
+ /**
+ * Oauth客户端详情
+ *
+ * @param params
+ * @return
+ * @throws Exception
+ */
+ OAuth2ClientDTO get(Map params) throws Exception;
+
+ /**
+ * 获取Oauth
+ *
+ * @param clientId
+ * @return
+ * @throws Exception
+ */
+ OAuth2ClientDTO get(String clientId) throws Exception;
+
+ /**
+ * OAuth2详情
+ *
+ * @param params
+ * @return
+ */
+ OAuth2ClientPO getPO(Map params);
+
+ /**
+ * OAuth2详情
+ *
+ * @param clientId
+ * @return
+ */
+ OAuth2ClientPO getPO(String clientId);
+
+ /**
+ * Oauth客户端初始化信息
+ *
+ * @return
+ * @throws Exception
+ */
+ OAuth2ClientDTO getInit() throws Exception;
+
+ /**
+ * Oauth客户端统计
+ *
+ * @param params
+ * @return
+ */
+ Integer count(Map params);
+
+
+}
diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/OAuth2ClientServiceImpl.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/OAuth2ClientServiceImpl.java
new file mode 100644
index 00000000..a90d4c6f
--- /dev/null
+++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/OAuth2ClientServiceImpl.java
@@ -0,0 +1,174 @@
+package ink.wgink.login.oauth2.server.service.impl;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import ink.wgink.common.base.DefaultBaseService;
+import ink.wgink.exceptions.RemoveException;
+import ink.wgink.exceptions.SaveException;
+import ink.wgink.exceptions.SearchException;
+import ink.wgink.exceptions.UpdateException;
+import ink.wgink.login.oauth2.server.dao.IOAuth2ClientDao;
+import ink.wgink.login.oauth2.server.pojo.dtos.OAuth2ClientDTO;
+import ink.wgink.login.oauth2.server.pojo.dtos.OAuth2ClientSimpleDTO;
+import ink.wgink.login.oauth2.server.pojo.pos.OAuth2ClientPO;
+import ink.wgink.login.oauth2.server.pojo.vos.OAuth2ClientVO;
+import ink.wgink.login.oauth2.server.service.IOAuth2ClientService;
+import ink.wgink.module.menu.pojo.vos.MenuVO;
+import ink.wgink.module.menu.service.IMenuService;
+import ink.wgink.pojo.ListPage;
+import ink.wgink.pojo.result.SuccessResultList;
+import ink.wgink.util.AesUtil;
+import ink.wgink.util.UUIDUtil;
+import ink.wgink.util.map.HashMapUtil;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName: OauthClientServiceImpl
+ * @Description: Oauth客户端
+ * @Author: WangGeng
+ * @Date: 2019/3/12 11:40 AM
+ * @Version: 1.0
+ **/
+@Service
+public class OAuth2ClientServiceImpl extends DefaultBaseService implements IOAuth2ClientService {
+
+ @Autowired
+ private IOAuth2ClientDao oauth2ClientDao;
+ @Autowired
+ private IMenuService menuService;
+ @Autowired
+ private PasswordEncoder passwordEncoder;
+
+ @Override
+ public void save(OAuth2ClientVO oauth2ClientVO) throws SaveException {
+ oauth2ClientVO.setClientSecret(passwordEncoder.encode(oauth2ClientVO.getClientSecret()));
+ Map params = HashMapUtil.beanToMap(oauth2ClientVO);
+ setSaveInfo(params);
+ oauth2ClientDao.save(params);
+ }
+
+ @Override
+ public void remove(List ids) throws RemoveException {
+ Map params = getHashMap(6);
+ params.put("clientIds", ids);
+ setUpdateInfo(params);
+ oauth2ClientDao.remove(params);
+ }
+
+ @Override
+ public void update(String clientId, OAuth2ClientVO oauth2ClientVO) throws UpdateException {
+ Map params = HashMapUtil.beanToMap(oauth2ClientVO);
+ params.put("clientId", clientId);
+ setUpdateInfo(params);
+ oauth2ClientDao.update(params);
+ }
+
+
+ @Override
+ public void updateMenuInit(String clientId, String menuId) throws UpdateException, SaveException, SearchException {
+ OAuth2ClientPO oauth2ClientPO = getPO(clientId);
+ if (!StringUtils.isBlank(oauth2ClientPO.getMenuId())) {
+ throw new UpdateException("菜单已经绑定", true);
+ }
+ Map params = getHashMap(2);
+ if (StringUtils.isBlank(menuId)) {
+ LOG.debug("菜单为空,创建菜单:{}", oauth2ClientPO.getClientName());
+ MenuVO menuVO = new MenuVO();
+ menuVO.setMenuParentId("0");
+ menuVO.setMenuName(oauth2ClientPO.getClientName());
+ menuVO.setMenuSummary(oauth2ClientPO.getClientName() + "根节点菜单");
+ menuVO.setMenuUrl("javascript:void(0);");
+ menuVO.setMenuIcon("fa-icon-color-white fa fa-list");
+ menuVO.setMenuStatus(0);
+ menuVO.setMenuType(1);
+ menuVO.setOpenType(1);
+ menuVO.setMenuOrder("1");
+ String newMenuId = menuService.saveAndReturnId(menuVO);
+ LOG.debug("绑定菜单:{}", oauth2ClientPO.getClientName());
+ params.put("menuId", newMenuId);
+ } else {
+ params.put("menuId", menuId);
+ }
+ params.put("clientId", clientId);
+ oauth2ClientDao.updateMenu(params);
+ }
+
+ @Override
+ public void updateMenuEmpty(String clientId) throws UpdateException {
+ Map params = getHashMap(2);
+ params.put("clientId", clientId);
+ oauth2ClientDao.updateMenu(params);
+ }
+
+ @Override
+ public List list(Map params) throws SearchException {
+ return oauth2ClientDao.list(params);
+ }
+
+ @Override
+ public List listSimple(Map params) throws SearchException {
+ return oauth2ClientDao.listSimple(params);
+ }
+
+ @Override
+ public SuccessResultList> listPage(ListPage page) throws SearchException {
+ PageHelper.startPage(page.getPage(), page.getRows());
+ List oauthClientDTOs = list(page.getParams());
+ PageInfo pageInfo = new PageInfo<>(oauthClientDTOs);
+ return new SuccessResultList<>(oauthClientDTOs, pageInfo.getPageNum(), pageInfo.getTotal());
+ }
+
+ @Override
+ public OAuth2ClientDTO get(Map params) throws Exception {
+ OAuth2ClientDTO oauthClientDTO = oauth2ClientDao.get(params);
+ oauthClientDTO.setClientSecret(Base64.encodeBase64String(AesUtil.aesEncoder(OAUTH_CLIENT_RULE, oauthClientDTO.getClientId()).getBytes("UTF-8")));
+ return oauthClientDTO;
+ }
+
+ @Override
+ public OAuth2ClientDTO get(String clientId) throws Exception {
+ Map params = getHashMap(2);
+ params.put("clientId", clientId);
+ return get(params);
+ }
+
+ @Override
+ public OAuth2ClientPO getPO(Map params) {
+ return oauth2ClientDao.getPO(params);
+ }
+
+ @Override
+ public OAuth2ClientPO getPO(String clientId) throws SearchException {
+ Map params = getHashMap(2);
+ params.put("clientId", clientId);
+ return getPO(params);
+ }
+
+ @Override
+ public OAuth2ClientDTO getInit() throws Exception {
+ OAuth2ClientDTO oauthClientDTO = new OAuth2ClientDTO();
+ String clientId = UUIDUtil.get32UUID();
+ String clientSecret = Base64.encodeBase64String(AesUtil.aesEncoder(OAUTH_CLIENT_RULE, clientId).getBytes("UTF-8"));
+ oauthClientDTO.setClientId(clientId);
+ oauthClientDTO.setClientSecret(clientSecret);
+ oauthClientDTO.setAccessTokenValidity(7200);
+ oauthClientDTO.setRefreshTokenValidity(7200);
+ return oauthClientDTO;
+ }
+
+
+ @Override
+ public Integer count(Map params) throws SearchException {
+ Integer oauthClientCount = oauth2ClientDao.count(params);
+ return oauthClientCount == null ? 0 : oauthClientCount;
+ }
+
+
+}
diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/OauthClientDetailsServiceImpl.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/OauthClientDetailsServiceImpl.java
new file mode 100644
index 00000000..277ddc1e
--- /dev/null
+++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/OauthClientDetailsServiceImpl.java
@@ -0,0 +1,106 @@
+package ink.wgink.login.oauth2.server.service.impl;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import ink.wgink.login.oauth2.server.exceptions.OAuth2ClientExpireException;
+import ink.wgink.login.oauth2.server.exceptions.OAuth2ClientStateException;
+import ink.wgink.login.oauth2.server.pojo.pos.OAuth2ClientPO;
+import ink.wgink.login.oauth2.server.service.IOAuth2ClientService;
+import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Primary;
+import org.springframework.security.oauth2.provider.ClientDetails;
+import org.springframework.security.oauth2.provider.ClientDetailsService;
+import org.springframework.security.oauth2.provider.ClientRegistrationException;
+import org.springframework.security.oauth2.provider.client.BaseClientDetails;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: OauthClientDetailsService
+ * @Description: Oauth客户端业务
+ * @Author: WangGeng
+ * @Date: 2020/7/22 8:03 下午
+ * @Version: 1.0
+ **/
+@Primary
+@Component
+public class OauthClientDetailsServiceImpl implements ClientDetailsService {
+ private static final Logger LOG = LoggerFactory.getLogger(OauthClientDetailsServiceImpl.class);
+ @Autowired
+ private IOAuth2ClientService oAuth2ClientService;
+
+ @Override
+ public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
+ if (StringUtils.isBlank(clientId)) {
+ throw new OAuth2ClientExpireException("客户端ID不能为空");
+ }
+ OAuth2ClientPO oAuth2ClientPO = oAuth2ClientService.getPO(clientId);
+ if (oAuth2ClientPO == null) {
+ throw new OAuth2ClientStateException("客户端不存在");
+ }
+ // 如果是第三方系统,判断到期时间
+ if (StringUtils.equals(oAuth2ClientPO.getSystemType(), IOAuth2ClientService.OAUTH_CLIENT_SYSTEM_TYPE_THIRD)) {
+ String expireTime = oAuth2ClientPO.getExpireTime();
+ if (StringUtils.isBlank(oAuth2ClientPO.getSystemState())) {
+ throw new OAuth2ClientStateException("客户端状态异常");
+ }
+ if (StringUtils.equals(oAuth2ClientPO.getSystemState(), IOAuth2ClientService.OAUTH_CLIENT_SYSTEM_STATE_LOCKING)) {
+ throw new OAuth2ClientStateException("客户端锁定");
+ }
+ if (StringUtils.isBlank(oAuth2ClientPO.getExpireTime())) {
+ throw new OAuth2ClientExpireException("客户端到期时间异常");
+ }
+ DateTime now = DateTime.now();
+ DateTime expireTimeDateTime = DateTime.parse(expireTime, DateTimeFormat.forPattern("yyyy-MM-dd"));
+ if (now.isAfter(expireTimeDateTime)) {
+ throw new OAuth2ClientExpireException("客户端已过期");
+ }
+ }
+ BaseClientDetails clientDetails = new BaseClientDetails(oAuth2ClientPO.getClientId(),
+ oAuth2ClientPO.getResourceIds(),
+ oAuth2ClientPO.getScope(),
+ oAuth2ClientPO.getAuthorizedGrantTypes(),
+ oAuth2ClientPO.getAuthorities());
+
+ clientDetails.setClientSecret(oAuth2ClientPO.getClientSecret());
+ clientDetails.setAccessTokenValiditySeconds(oAuth2ClientPO.getAccessTokenValidity());
+ clientDetails.setRefreshTokenValiditySeconds(oAuth2ClientPO.getRefreshTokenValidity());
+ // 设置附加信息,json格式
+ String additionalInformation = oAuth2ClientPO.getAdditionalInformation();
+ if (!StringUtils.isBlank(additionalInformation)) {
+ ObjectMapper objectMapper = new ObjectMapper();
+ try {
+ Map additionalInformationMap = objectMapper.readValue(additionalInformation, Map.class);
+ clientDetails.setAdditionalInformation(additionalInformationMap);
+ } catch (IOException e) {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+ // 设置scope
+ if (!StringUtils.isBlank(oAuth2ClientPO.getScope())) {
+ clientDetails.setScope(org.springframework.util.StringUtils.commaDelimitedListToSet(oAuth2ClientPO.getScope()));
+ }
+
+ if (clientDetails.isAutoApprove(oAuth2ClientPO.getAutoapprove())) {
+ Set autoApproveScopesSet = new HashSet<>();
+ autoApproveScopesSet.add("true");
+ clientDetails.setAutoApproveScopes(autoApproveScopesSet);
+ } else {
+ clientDetails.setAutoApproveScopes(clientDetails.getScope());
+ }
+ return clientDetails;
+ }
+
+
+}
diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/OauthClientTokenServiceImpl.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/OauthClientTokenServiceImpl.java
new file mode 100644
index 00000000..86e6ad4b
--- /dev/null
+++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/OauthClientTokenServiceImpl.java
@@ -0,0 +1,320 @@
+package ink.wgink.login.oauth2.server.service.impl;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.oauth2.common.*;
+import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
+import org.springframework.security.oauth2.common.exceptions.InvalidScopeException;
+import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
+import org.springframework.security.oauth2.provider.*;
+import org.springframework.security.oauth2.provider.token.*;
+import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.Assert;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: OauthClientTokenService
+ * @Description: Oauth客户端Token
+ * @Author: WangGeng
+ * @Date: 2020/7/26 9:33 上午
+ * @Version: 1.0
+ **/
+@Component
+public class OauthClientTokenServiceImpl implements AuthorizationServerTokenServices, ResourceServerTokenServices, ConsumerTokenServices, InitializingBean {
+
+ private int refreshTokenValiditySeconds = 7200;
+ private int accessTokenValiditySeconds = 7200;
+ private boolean supportRefreshToken = true;
+ private boolean reuseRefreshToken = true;
+ @Resource(name = "jwtTokenStore")
+ private TokenStore tokenStore;
+ @Autowired
+ private ClientDetailsService clientDetailsService;
+ @Resource(name = "jwtAccessTokenConverter")
+ private TokenEnhancer accessTokenEnhancer;
+ @Autowired
+ private AuthenticationManager authenticationManager;
+
+ public OauthClientTokenServiceImpl() {
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ Assert.notNull(this.tokenStore, "tokenStore must be set");
+ }
+
+ @Override
+ @Transactional
+ public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) throws AuthenticationException {
+ OAuth2AccessToken existingAccessToken = this.tokenStore.getAccessToken(authentication);
+ OAuth2RefreshToken refreshToken = null;
+ if (existingAccessToken != null) {
+ if (!existingAccessToken.isExpired()) {
+ this.tokenStore.storeAccessToken(existingAccessToken, authentication);
+ return existingAccessToken;
+ }
+ if (existingAccessToken.getRefreshToken() != null) {
+ refreshToken = existingAccessToken.getRefreshToken();
+ this.tokenStore.removeRefreshToken(refreshToken);
+ }
+ this.tokenStore.removeAccessToken(existingAccessToken);
+ }
+
+ if (refreshToken == null) {
+ refreshToken = this.createRefreshToken(authentication);
+ } else if (refreshToken instanceof ExpiringOAuth2RefreshToken) {
+ ExpiringOAuth2RefreshToken expiring = (ExpiringOAuth2RefreshToken) refreshToken;
+ if (System.currentTimeMillis() > expiring.getExpiration().getTime()) {
+ refreshToken = this.createRefreshToken(authentication);
+ }
+ }
+
+ OAuth2AccessToken accessToken = this.createAccessToken(authentication, refreshToken);
+ this.tokenStore.storeAccessToken(accessToken, authentication);
+ refreshToken = accessToken.getRefreshToken();
+ if (refreshToken != null) {
+ this.tokenStore.storeRefreshToken(refreshToken, authentication);
+ }
+
+ return accessToken;
+ }
+
+ @Override
+ @Transactional(noRollbackFor = {InvalidTokenException.class, InvalidGrantException.class})
+ public OAuth2AccessToken refreshAccessToken(String refreshTokenValue, TokenRequest tokenRequest) throws AuthenticationException {
+ if (!this.supportRefreshToken) {
+ throw new InvalidGrantException("无效的刷新令牌: " + refreshTokenValue);
+ } else {
+ OAuth2RefreshToken refreshToken = this.tokenStore.readRefreshToken(refreshTokenValue);
+ if (refreshToken == null) {
+ throw new InvalidGrantException("无效的刷新令牌: " + refreshTokenValue);
+ } else {
+ OAuth2Authentication authentication = this.tokenStore.readAuthenticationForRefreshToken(refreshToken);
+ if (this.authenticationManager != null && !authentication.isClientOnly()) {
+ Authentication user = new PreAuthenticatedAuthenticationToken(authentication.getUserAuthentication(), "", authentication.getAuthorities());
+ user = this.authenticationManager.authenticate(user);
+ Object details = authentication.getDetails();
+ authentication = new OAuth2Authentication(authentication.getOAuth2Request(), user);
+ authentication.setDetails(details);
+ }
+
+ String clientId = authentication.getOAuth2Request().getClientId();
+ if (clientId != null && clientId.equals(tokenRequest.getClientId())) {
+ this.tokenStore.removeAccessTokenUsingRefreshToken(refreshToken);
+ if (this.isExpired(refreshToken)) {
+ this.tokenStore.removeRefreshToken(refreshToken);
+ throw new InvalidTokenException("无效的刷新令牌 (超时): " + refreshToken);
+ } else {
+ authentication = this.createRefreshedAuthentication(authentication, tokenRequest);
+ if (!this.reuseRefreshToken) {
+ this.tokenStore.removeRefreshToken(refreshToken);
+ refreshToken = this.createRefreshToken(authentication);
+ }
+
+ OAuth2AccessToken accessToken = this.createAccessToken(authentication, refreshToken);
+ this.tokenStore.storeAccessToken(accessToken, authentication);
+ if (!this.reuseRefreshToken) {
+ this.tokenStore.storeRefreshToken(accessToken.getRefreshToken(), authentication);
+ }
+
+ return accessToken;
+ }
+ } else {
+ throw new InvalidGrantException("Wrong client for this refresh token: " + refreshTokenValue);
+ }
+ }
+ }
+ }
+
+ @Override
+ public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) {
+ return this.tokenStore.getAccessToken(authentication);
+ }
+
+ private OAuth2Authentication createRefreshedAuthentication(OAuth2Authentication authentication, TokenRequest request) {
+ Set scope = request.getScope();
+ OAuth2Request clientAuth = authentication.getOAuth2Request().refresh(request);
+ if (scope != null && !scope.isEmpty()) {
+ Set originalScope = clientAuth.getScope();
+ if (originalScope == null || !originalScope.containsAll(scope)) {
+ throw new InvalidScopeException("无法将客户端身份验证的范围缩小到 " + scope + ".", originalScope);
+ }
+
+ clientAuth = clientAuth.narrowScope(scope);
+ }
+
+ OAuth2Authentication narrowed = new OAuth2Authentication(clientAuth, authentication.getUserAuthentication());
+ return narrowed;
+ }
+
+ protected boolean isExpired(OAuth2RefreshToken refreshToken) {
+ if (!(refreshToken instanceof ExpiringOAuth2RefreshToken)) {
+ return false;
+ } else {
+ ExpiringOAuth2RefreshToken expiringToken = (ExpiringOAuth2RefreshToken) refreshToken;
+ return expiringToken.getExpiration() == null || System.currentTimeMillis() > expiringToken.getExpiration().getTime();
+ }
+ }
+
+ @Override
+ public OAuth2AccessToken readAccessToken(String accessToken) {
+ return this.tokenStore.readAccessToken(accessToken);
+ }
+
+ @Override
+ public OAuth2Authentication loadAuthentication(String accessTokenValue) throws AuthenticationException, InvalidTokenException {
+ OAuth2AccessToken accessToken = this.tokenStore.readAccessToken(accessTokenValue);
+ if (accessToken == null) {
+ throw new InvalidTokenException("无效的访问令牌: " + accessTokenValue);
+ } else if (accessToken.isExpired()) {
+ this.tokenStore.removeAccessToken(accessToken);
+ throw new InvalidTokenException("访问令牌超时: " + accessTokenValue);
+ } else {
+ OAuth2Authentication result = this.tokenStore.readAuthentication(accessToken);
+ if (result == null) {
+ throw new InvalidTokenException("无效的访问令牌: " + accessTokenValue);
+ } else {
+ if (this.clientDetailsService != null) {
+ String clientId = result.getOAuth2Request().getClientId();
+
+ try {
+ this.clientDetailsService.loadClientByClientId(clientId);
+ } catch (ClientRegistrationException var6) {
+ throw new InvalidTokenException("客户端无效: " + clientId, var6);
+ }
+ }
+
+ return result;
+ }
+ }
+ }
+
+ public String getClientId(String tokenValue) {
+ OAuth2Authentication authentication = this.tokenStore.readAuthentication(tokenValue);
+ if (authentication == null) {
+ throw new InvalidTokenException("无效的访问令牌: " + tokenValue);
+ } else {
+ OAuth2Request clientAuth = authentication.getOAuth2Request();
+ if (clientAuth == null) {
+ throw new InvalidTokenException("无效的访问令牌 (不存在clientId): " + tokenValue);
+ } else {
+ return clientAuth.getClientId();
+ }
+ }
+ }
+
+ @Override
+ public boolean revokeToken(String tokenValue) {
+ OAuth2AccessToken accessToken = this.tokenStore.readAccessToken(tokenValue);
+ if (accessToken == null) {
+ return false;
+ } else {
+ if (accessToken.getRefreshToken() != null) {
+ this.tokenStore.removeRefreshToken(accessToken.getRefreshToken());
+ }
+
+ this.tokenStore.removeAccessToken(accessToken);
+ return true;
+ }
+ }
+
+ private OAuth2RefreshToken createRefreshToken(OAuth2Authentication authentication) {
+ if (!this.isSupportRefreshToken(authentication.getOAuth2Request())) {
+ return null;
+ } else {
+ int validitySeconds = this.getRefreshTokenValiditySeconds(authentication.getOAuth2Request());
+ String value = UUID.randomUUID().toString();
+ return (OAuth2RefreshToken) (validitySeconds > 0 ? new DefaultExpiringOAuth2RefreshToken(value, new Date(System.currentTimeMillis() + (long) validitySeconds * 1000L)) : new DefaultOAuth2RefreshToken(value));
+ }
+ }
+
+ private OAuth2AccessToken createAccessToken(OAuth2Authentication authentication, OAuth2RefreshToken refreshToken) {
+ DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(UUID.randomUUID().toString());
+ int validitySeconds = this.getAccessTokenValiditySeconds(authentication.getOAuth2Request());
+ if (validitySeconds > 0) {
+ token.setExpiration(new Date(System.currentTimeMillis() + (long) validitySeconds * 1000L));
+ }
+
+ token.setRefreshToken(refreshToken);
+ token.setScope(authentication.getOAuth2Request().getScope());
+ return (OAuth2AccessToken) (this.accessTokenEnhancer != null ? this.accessTokenEnhancer.enhance(token, authentication) : token);
+ }
+
+ protected int getAccessTokenValiditySeconds(OAuth2Request clientAuth) {
+ if (this.clientDetailsService != null) {
+ ClientDetails client = this.clientDetailsService.loadClientByClientId(clientAuth.getClientId());
+ Integer validity = client.getAccessTokenValiditySeconds();
+ if (validity != null) {
+ return validity;
+ }
+ }
+
+ return this.accessTokenValiditySeconds;
+ }
+
+ protected int getRefreshTokenValiditySeconds(OAuth2Request clientAuth) {
+ if (this.clientDetailsService != null) {
+ ClientDetails client = this.clientDetailsService.loadClientByClientId(clientAuth.getClientId());
+ Integer validity = client.getRefreshTokenValiditySeconds();
+ if (validity != null) {
+ return validity;
+ }
+ }
+
+ return this.refreshTokenValiditySeconds;
+ }
+
+ protected boolean isSupportRefreshToken(OAuth2Request clientAuth) {
+ if (this.clientDetailsService != null) {
+ ClientDetails client = this.clientDetailsService.loadClientByClientId(clientAuth.getClientId());
+ return client.getAuthorizedGrantTypes().contains("refresh_token");
+ } else {
+ return this.supportRefreshToken;
+ }
+ }
+
+ public void setTokenEnhancer(TokenEnhancer accessTokenEnhancer) {
+ this.accessTokenEnhancer = accessTokenEnhancer;
+ }
+
+ public void setRefreshTokenValiditySeconds(int refreshTokenValiditySeconds) {
+ this.refreshTokenValiditySeconds = refreshTokenValiditySeconds;
+ }
+
+ public void setAccessTokenValiditySeconds(int accessTokenValiditySeconds) {
+ this.accessTokenValiditySeconds = accessTokenValiditySeconds;
+ }
+
+ public void setSupportRefreshToken(boolean supportRefreshToken) {
+ this.supportRefreshToken = supportRefreshToken;
+ }
+
+ public void setReuseRefreshToken(boolean reuseRefreshToken) {
+ this.reuseRefreshToken = reuseRefreshToken;
+ }
+
+ public void setTokenStore(TokenStore tokenStore) {
+ this.tokenStore = tokenStore;
+ }
+
+ public void setAuthenticationManager(AuthenticationManager authenticationManager) {
+ this.authenticationManager = authenticationManager;
+ }
+
+ public void setClientDetailsService(ClientDetailsService clientDetailsService) {
+ this.clientDetailsService = clientDetailsService;
+ }
+
+}
diff --git a/service-oauth-client/src/main/resources/mybatis/mapper/oauthclient-mapper.xml b/login-oauth2-server/src/main/resources/mybatis/mapper/IOAuth2ClientDao.xml
similarity index 70%
rename from service-oauth-client/src/main/resources/mybatis/mapper/oauthclient-mapper.xml
rename to login-oauth2-server/src/main/resources/mybatis/mapper/IOAuth2ClientDao.xml
index 25f3c552..55c5b18f 100644
--- a/service-oauth-client/src/main/resources/mybatis/mapper/oauthclient-mapper.xml
+++ b/login-oauth2-server/src/main/resources/mybatis/mapper/IOAuth2ClientDao.xml
@@ -1,17 +1,17 @@
-
+
-
+
-
+
@@ -31,6 +31,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CREATE TABLE IF NOT EXISTS `oauth_client_details` (
+ `client_id` varchar(48) NOT NULL,
+ `resource_ids` varchar(255) DEFAULT NULL,
+ `client_secret` varchar(255) DEFAULT NULL,
+ `scope` varchar(255) DEFAULT NULL,
+ `authorized_grant_types` varchar(255) DEFAULT NULL,
+ `web_server_redirect_uri` varchar(255) DEFAULT NULL,
+ `authorities` varchar(255) DEFAULT NULL,
+ `access_token_validity` int(11) DEFAULT NULL,
+ `refresh_token_validity` int(11) DEFAULT NULL,
+ `additional_information` varchar(4096) DEFAULT NULL,
+ `autoapprove` varchar(256) DEFAULT NULL,
+ `client_name` varchar(255) DEFAULT NULL,
+ `menu_id` char(36) DEFAULT NULL COMMENT '菜单ID',
+ `environment` varchar(10) DEFAULT 'formal' COMMENT '系统环境',
+ `system_type` varchar(10) DEFAULT 'within' COMMENT '系统类型',
+ `system_state` varchar(10) DEFAULT NULL COMMENT '系统状态',
+ `expire_time` varchar(10) DEFAULT NULL COMMENT '系统到期时间',
+ `system_summary` text COMMENT '系统介绍',
+ `system_icon` varchar(255) DEFAULT NULL COMMENT '系统图标',
+ `gmt_create` datetime DEFAULT NULL,
+ `creator` bigint(20) DEFAULT NULL,
+ `gmt_modified` datetime DEFAULT NULL,
+ `modifier` bigint(20) DEFAULT NULL,
+ `is_delete` int(2) DEFAULT '0',
+ PRIMARY KEY (`client_id`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+
INSERT INTO oauth_client_details(
@@ -165,7 +224,7 @@
-