From 9a2cb4bad35d13e7369162c3105f64d52b0031f0 Mon Sep 17 00:00:00 2001 From: wanggeng <450292408@qq.com> Date: Sat, 18 Sep 2021 15:37:51 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E7=90=86=E4=BA=86=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E9=97=AE=E9=A2=98=EF=BC=8C=E5=AE=8C=E6=88=90?= =?UTF-8?q?OAuth2=E5=AE=A2=E6=88=B7=E7=AB=AF=E5=8D=95=E7=82=B9=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../oauth2/client/OAuth2ClientProperties.java | 20 +- .../common/config/TransactionConfig.java | 4 +- .../base/security/WebSecurityConfig.java | 2 +- .../base/security/WebSecurityConfig1.java | 113 ----- .../main/resources/templates/login-old.html | 335 -------------- login-oauth2-client/pom.xml | 15 + .../client/config/OAuth2ClientConfig.java | 4 +- .../route/IndexRouteController.java | 120 +++++ .../OAuth2ClientUserAuthConverter.java | 3 +- .../resources/templates/default-home.html | 35 ++ .../resources/templates/default-main.html | 248 ++++++++++ login-oauth2-server/pom.xml | 10 + .../OAuth2AuthorizationServerConfig.java | 36 +- .../server/config/OAuth2WebMvcConfigurer.java | 27 ++ .../OAuth2AccessTokenMessageConverter.java | 60 +++ .../server/converter/UserAuthConverter.java | 3 +- .../OAuth2ClientAuthorizationEndpoint.java | 427 ++++++++++++++++++ .../OAuth2ClientCheckTokenEndpoint.java | 91 ++++ .../endpoint/OAuth2ClientTokenEndpoint.java | 177 ++++++++ .../OAuth2ClientTokenKeyEndpoint.java | 55 +++ .../server/pojo/pos/OAuth2ClientPO.java | 36 +- .../server/service/IOAuth2ClientService.java | 2 +- ...va => OAuth2ClientDetailsServiceImpl.java} | 17 +- ...java => OAuth2ClientTokenServiceImpl.java} | 4 +- ...ClientDao.xml => oauth2-client-mapper.xml} | 12 +- .../templates/oauth2client/save.html | 6 +- .../templates/oauth2client/update.html | 6 +- pom.xml | 12 +- 28 files changed, 1359 insertions(+), 521 deletions(-) delete mode 100644 login-base/src/main/java/ink/wgink/login/base/security/WebSecurityConfig1.java delete mode 100644 login-base/src/main/resources/templates/login-old.html create mode 100644 login-oauth2-client/src/main/java/ink/wgink/login/oauth2/client/controller/route/IndexRouteController.java create mode 100644 login-oauth2-client/src/main/resources/templates/default-home.html create mode 100644 login-oauth2-client/src/main/resources/templates/default-main.html create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/config/OAuth2WebMvcConfigurer.java create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/converter/OAuth2AccessTokenMessageConverter.java create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/endpoint/OAuth2ClientAuthorizationEndpoint.java create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/endpoint/OAuth2ClientCheckTokenEndpoint.java create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/endpoint/OAuth2ClientTokenEndpoint.java create mode 100644 login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/endpoint/OAuth2ClientTokenKeyEndpoint.java rename login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/{Oauth2ClientDetailsServiceImpl.java => OAuth2ClientDetailsServiceImpl.java} (89%) rename login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/{Oauth2ClientTokenServiceImpl.java => OAuth2ClientTokenServiceImpl.java} (99%) rename login-oauth2-server/src/main/resources/mybatis/mapper/{IOAuth2ClientDao.xml => oauth2-client-mapper.xml} (97%) diff --git a/basic-properties/src/main/java/ink/wgink/properties/oauth2/client/OAuth2ClientProperties.java b/basic-properties/src/main/java/ink/wgink/properties/oauth2/client/OAuth2ClientProperties.java index 5369c3e1..17488a92 100644 --- a/basic-properties/src/main/java/ink/wgink/properties/oauth2/client/OAuth2ClientProperties.java +++ b/basic-properties/src/main/java/ink/wgink/properties/oauth2/client/OAuth2ClientProperties.java @@ -14,24 +14,24 @@ import org.springframework.stereotype.Component; @ConfigurationProperties(prefix = "security.oauth2") public class OAuth2ClientProperties { - private String oauth2Server; - private String oauth2Logout; + private String oauthServer; + private String oauthLogout; private ClientProperties client; - public String getOauth2Server() { - return oauth2Server == null ? "" : oauth2Server.trim(); + public String getOauthServer() { + return oauthServer == null ? "" : oauthServer.trim(); } - public void setOauth2Server(String oauth2Server) { - this.oauth2Server = oauth2Server; + public void setOauthServer(String oauthServer) { + this.oauthServer = oauthServer; } - public String getOauth2Logout() { - return oauth2Logout == null ? "" : oauth2Logout.trim(); + public String getOauthLogout() { + return oauthLogout == null ? "" : oauthLogout.trim(); } - public void setOauth2Logout(String oauth2Logout) { - this.oauth2Logout = oauth2Logout; + public void setOauthLogout(String oauthLogout) { + this.oauthLogout = oauthLogout; } public ClientProperties getClient() { diff --git a/common/src/main/java/ink/wgink/common/config/TransactionConfig.java b/common/src/main/java/ink/wgink/common/config/TransactionConfig.java index 808c56fb..fdf159ac 100644 --- a/common/src/main/java/ink/wgink/common/config/TransactionConfig.java +++ b/common/src/main/java/ink/wgink/common/config/TransactionConfig.java @@ -8,8 +8,8 @@ import org.springframework.aop.support.DefaultPointcutAdvisor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionManager; import org.springframework.transaction.interceptor.DefaultTransactionAttribute; import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource; import org.springframework.transaction.interceptor.TransactionInterceptor; @@ -52,7 +52,7 @@ public class TransactionConfig { @Autowired private TransactionProperties transactionProperties; @Autowired - private TransactionManager transactionManager; + private PlatformTransactionManager transactionManager; /** * 事务拦截器 diff --git a/login-base/src/main/java/ink/wgink/login/base/security/WebSecurityConfig.java b/login-base/src/main/java/ink/wgink/login/base/security/WebSecurityConfig.java index 26a0cf12..c44c0365 100644 --- a/login-base/src/main/java/ink/wgink/login/base/security/WebSecurityConfig.java +++ b/login-base/src/main/java/ink/wgink/login/base/security/WebSecurityConfig.java @@ -47,7 +47,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { baseProperties.getLoginProcess(), baseProperties.getLoginFailure(), "/oauth/**", - "/oauth_client/**", + "/oauth2_client/**", "/app/**", "/approute/**", "/wechat/**", diff --git a/login-base/src/main/java/ink/wgink/login/base/security/WebSecurityConfig1.java b/login-base/src/main/java/ink/wgink/login/base/security/WebSecurityConfig1.java deleted file mode 100644 index bdffb545..00000000 --- a/login-base/src/main/java/ink/wgink/login/base/security/WebSecurityConfig1.java +++ /dev/null @@ -1,113 +0,0 @@ -package ink.wgink.login.base.security; - -import ink.wgink.common.handler.AccessDenyHandler; -import ink.wgink.login.base.handler.LoginFailureHandler; -import ink.wgink.login.base.handler.LogoutHandler; -import ink.wgink.login.base.security.user.UserSecurityConfig; -import ink.wgink.login.base.service.user.UserDetailServiceImpl; -import ink.wgink.login.base.service.user.UserLoginService; -import ink.wgink.properties.BaseProperties; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.SecurityFilterChain; - -/** - * @ClassName: WebSecurityConfig - * @Description: security配置 - * @Author: WangGeng - * @Date: 2019/2/15 10:05 AM - * @Version: 1.0 - **/ -//@EnableWebSecurity -public class WebSecurityConfig1 { - - @Autowired - private BaseProperties baseProperties; - @Autowired - private UserDetailServiceImpl userDetailService; - @Autowired - private UserLoginService userLoginService; - @Autowired - private PasswordEncoder passwordEncoder; - - @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - /** - * 默认放行配置 - */ - String[] defaultAntMatchers = { - baseProperties.getLoginUrl(), - baseProperties.getLoginProcess(), - baseProperties.getLoginFailure(), - "/oauth/**", - "/oauth_client/**", - "/app/**", - "/approute/**", - "/wechat/**", - "/wechat-miniapp/**", - "/route/file/**", - "/api/sms/getverificationcode/*", - "/api/user/getsignintype/**" - }; - String assetsMatchers = baseProperties.getAssetsMatchers(); - String[] fullAntMatchers; - if (!StringUtils.isBlank(assetsMatchers)) { - String[] assetsMatchersArray = baseProperties.getAssetsMatchers().split(","); - fullAntMatchers = ArrayUtils.addAll(defaultAntMatchers, assetsMatchersArray); - } else { - fullAntMatchers = defaultAntMatchers; - } - - LoginFailureHandler loginFailureHandler = new LoginFailureHandler(baseProperties.getLoginFailure()); - http - .formLogin() - .loginPage(baseProperties.getLoginUrl()) - .loginProcessingUrl(baseProperties.getLoginProcess()) - .failureForwardUrl(baseProperties.getLoginUrl()) - .failureHandler(loginFailureHandler) - .and() - .logout() - .addLogoutHandler(new LogoutHandler()) - .and() - .headers() - .frameOptions() - .disable() - .and() - .authorizeRequests() - .antMatchers(fullAntMatchers) - .permitAll() - .and() - .authorizeRequests() - .anyRequest().access("@rbacService.hasPermission(request, authentication)") - .and() - .exceptionHandling().accessDeniedHandler(new AccessDenyHandler()) - .and() - .cors() - .and() - .csrf() - .disable(); - addUserAuthenticationFilter(http, loginFailureHandler); - return http.build(); - } - - /** - * 创建用户认证过滤器链,替换原有UsernamePasswordAuthenticationFilter - * - * @param http - * @param loginFailureHandler - */ - private void addUserAuthenticationFilter(HttpSecurity http, LoginFailureHandler loginFailureHandler) throws Exception { - UserSecurityConfig userSecurityConfig = new UserSecurityConfig(); - userSecurityConfig.setUserDetailService(userDetailService); - userSecurityConfig.setPasswordEncoder(passwordEncoder); - userSecurityConfig.setLoginProcessUrl(baseProperties.getLoginProcess()); - userSecurityConfig.setLoginFailureHandler(loginFailureHandler); - userSecurityConfig.setUserLoginService(userLoginService); - http.apply(userSecurityConfig); - } - -} diff --git a/login-base/src/main/resources/templates/login-old.html b/login-base/src/main/resources/templates/login-old.html deleted file mode 100644 index 2d122686..00000000 --- a/login-base/src/main/resources/templates/login-old.html +++ /dev/null @@ -1,335 +0,0 @@ - - - - - - - - - - - - - - - - - - -
-
- - -
- -
-
- 取消扫码 -
-
- -
- -
-
- -
- - - - - - - - \ No newline at end of file diff --git a/login-oauth2-client/pom.xml b/login-oauth2-client/pom.xml index 672557a4..ca911fec 100644 --- a/login-oauth2-client/pom.xml +++ b/login-oauth2-client/pom.xml @@ -21,12 +21,27 @@ org.springframework.security spring-security-core + + + org.springframework + spring-core + + + + + org.springframework.security + spring-security-jwt + 1.0.9.RELEASE org.springframework.security.oauth.boot spring-security-oauth2-autoconfigure 2.0.0.RELEASE + + com.fasterxml.jackson.core + jackson-annotations + org.springframework spring-core diff --git a/login-oauth2-client/src/main/java/ink/wgink/login/oauth2/client/config/OAuth2ClientConfig.java b/login-oauth2-client/src/main/java/ink/wgink/login/oauth2/client/config/OAuth2ClientConfig.java index f67ac33d..dfb51cec 100755 --- a/login-oauth2-client/src/main/java/ink/wgink/login/oauth2/client/config/OAuth2ClientConfig.java +++ b/login-oauth2-client/src/main/java/ink/wgink/login/oauth2/client/config/OAuth2ClientConfig.java @@ -35,13 +35,13 @@ public class OAuth2ClientConfig extends WebSecurityConfigurerAdapter { .formLogin() .defaultSuccessUrl("/authorize", true) .and() - .logout().logoutSuccessUrl(oAuth2ClientProperties.getOauth2Logout()) + .logout().logoutSuccessUrl(oAuth2ClientProperties.getOauthLogout()) .and() .authorizeRequests().antMatchers("/app/**","/resource/**", "/route/file/**").permitAll() .and() .authorizeRequests() .anyRequest() - .access("@rbacService.hasPermission(request, authentication)") + .access("@clientRbacService.hasPermission(request, authentication)") .and() .headers().frameOptions().sameOrigin() .and() diff --git a/login-oauth2-client/src/main/java/ink/wgink/login/oauth2/client/controller/route/IndexRouteController.java b/login-oauth2-client/src/main/java/ink/wgink/login/oauth2/client/controller/route/IndexRouteController.java new file mode 100644 index 00000000..4292f0be --- /dev/null +++ b/login-oauth2-client/src/main/java/ink/wgink/login/oauth2/client/controller/route/IndexRouteController.java @@ -0,0 +1,120 @@ +package ink.wgink.login.oauth2.client.controller.route; + +import ink.wgink.common.component.SecurityComponent; +import ink.wgink.interfaces.menu.IMenuBaseService; +import ink.wgink.interfaces.role.IRoleMenuBaseService; +import ink.wgink.pojo.bos.UserInfoBO; +import ink.wgink.properties.ServerProperties; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.view.RedirectView; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: IndexRouteController + * @Description: index + * @Author: wanggeng + * @Date: 2021/2/27 3:38 下午 + * @Version: 1.0 + */ +@Controller +public class IndexRouteController { + + @Autowired + private SecurityComponent securityComponent; + @Autowired + private ServerProperties serverProperties; + @Autowired(required = false) + private IMenuBaseService menuBaseService; + @Autowired(required = false) + private IRoleMenuBaseService roleMenuBaseService; + + @GetMapping("index") + public ModelAndView goIndex() { + if (!StringUtils.isBlank(serverProperties.getDefaultIndexPage())) { + return new ModelAndView(new RedirectView(serverProperties.getDefaultIndexPage())); + } + return new ModelAndView("forward:/default-main"); + } + + /** + * 默认主页 + * + * @return + */ + @GetMapping("default-main") + public ModelAndView defaultMain() { + ModelAndView mv = new ModelAndView("default-main"); + UserInfoBO userInfoBO = securityComponent.getCurrentUser(); + mv.addObject("userUsername", userInfoBO.getUserUsername()); +// Map config = ConfigManager.getInstance().getConfig(); +// // 先加载系统短标题,没有加载主标题,没有加载配置文件系统标题 +// if (!Objects.isNull(config.get(IUserCenterConst.SYSTEM_SHORT_TITLE)) && !StringUtils.isBlank(config.get(IUserCenterConst.SYSTEM_SHORT_TITLE).toString())) { +// mv.addObject(IUserCenterConst.SYSTEM_SHORT_TITLE, config.get(IUserCenterConst.SYSTEM_SHORT_TITLE).toString()); +// } else if(!Objects.isNull(config.get(IUserCenterConst.SYSTEM_TITLE)) && !StringUtils.isBlank(config.get(IUserCenterConst.SYSTEM_TITLE).toString())) { +// mv.addObject(IUserCenterConst.SYSTEM_SHORT_TITLE, config.get(IUserCenterConst.SYSTEM_TITLE).toString()); +// } else { +// mv.addObject(IUserCenterConst.SYSTEM_SHORT_TITLE, serverProperties.getSystemTitle()); +// } +// // 系统短LOGO +// if (!Objects.isNull(config.get(IUserCenterConst.SYSTEM_SHORT_LOGO)) && !StringUtils.isBlank(config.get(IUserCenterConst.SYSTEM_SHORT_LOGO).toString())) { +// mv.addObject(IUserCenterConst.SYSTEM_SHORT_LOGO, config.get(IUserCenterConst.SYSTEM_SHORT_LOGO).toString()); +// } else { +// mv.addObject(IUserCenterConst.SYSTEM_SHORT_LOGO, ""); +// } +// mv.addObject("ws", serverProperties.getWs()); +// // 菜单模式 +// if (!Objects.isNull(config.get(IUserCenterConst.MENU_MODE)) && !StringUtils.isBlank(config.get(IUserCenterConst.MENU_MODE).toString())) { +// mv.addObject(IUserCenterConst.MENU_MODE, config.get(IUserCenterConst.MENU_MODE).toString()); +// } +// if (menuBaseService != null) { +// List menus; +// if (StringUtils.equalsIgnoreCase(ISystemConstant.ADMIN, userInfoBO.getUserUsername())) { +// // 管理员 +// List menuIds = roleMenuBaseService.listMenuId(ISystemConstant.ADMIN); +// if (menuIds.isEmpty()) { +// menus = menuBaseService.listAllByParentId(IMenuBaseService.MENU_UNIFIED_USER); +// } else { +// menus = menuBaseService.listAllByParentIdAndIds(IMenuBaseService.MENU_UNIFIED_USER, menuIds); +// } +// } else { +// // 普通用户 +// List roleSimpleDTOs = securityComponent.getCurrentUser().getRoles(); +// if (roleSimpleDTOs.isEmpty()) { +// menus = new ArrayList<>(); +// } else { +// List roleIds = new ArrayList<>(); +// for (RoleSimpleDTO roleSimpleDTO : roleSimpleDTOs) { +// roleIds.add(roleSimpleDTO.getRoleId()); +// } +// List menuIds = roleMenuBaseService.listMenuId(roleIds); +// menus = menuBaseService.listAllByParentIdAndIds(IMenuBaseService.MENU_UNIFIED_USER, menuIds); +// } +// } +// mv.addObject("menus", menus); +// } + return mv; + } + + /** + * 默认导航首页 + * + * @return + */ + @GetMapping("default-home") + public ModelAndView defaultHome() { + ModelAndView mv; + if (!StringUtils.isBlank(serverProperties.getDefaultHomePage())) { + mv = new ModelAndView(new RedirectView(serverProperties.getDefaultHomePage())); + } else { + mv = new ModelAndView("default-home"); + } + return mv; + } + +} diff --git a/login-oauth2-client/src/main/java/ink/wgink/login/oauth2/client/converter/OAuth2ClientUserAuthConverter.java b/login-oauth2-client/src/main/java/ink/wgink/login/oauth2/client/converter/OAuth2ClientUserAuthConverter.java index 99e909fa..25cf7a2f 100644 --- a/login-oauth2-client/src/main/java/ink/wgink/login/oauth2/client/converter/OAuth2ClientUserAuthConverter.java +++ b/login-oauth2-client/src/main/java/ink/wgink/login/oauth2/client/converter/OAuth2ClientUserAuthConverter.java @@ -1,5 +1,6 @@ package ink.wgink.login.oauth2.client.converter; +import com.alibaba.fastjson.JSONObject; import ink.wgink.pojo.bos.UserInfoBO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,7 +37,7 @@ public class OAuth2ClientUserAuthConverter implements UserAuthenticationConverte if (!Objects.isNull(principal)) { Collection authorities = new ArrayList<>(); // 包含用户信息,则直接抽取其中的用户信息 - UserInfoBO userInfoBO = (UserInfoBO) map.get("user_info"); + UserInfoBO userInfoBO = JSONObject.parseObject(map.get("user_info").toString(), UserInfoBO.class); principal = userInfoBO; LOG.debug("获取用户权限"); return new UsernamePasswordAuthenticationToken(principal, "N/A", authorities); diff --git a/login-oauth2-client/src/main/resources/templates/default-home.html b/login-oauth2-client/src/main/resources/templates/default-home.html new file mode 100644 index 00000000..26a91f75 --- /dev/null +++ b/login-oauth2-client/src/main/resources/templates/default-home.html @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + +
+
+

欢迎使用

+
+
+ + + + + + + \ No newline at end of file diff --git a/login-oauth2-client/src/main/resources/templates/default-main.html b/login-oauth2-client/src/main/resources/templates/default-main.html new file mode 100644 index 00000000..0e43b647 --- /dev/null +++ b/login-oauth2-client/src/main/resources/templates/default-main.html @@ -0,0 +1,248 @@ + + + + + + + + + + + + + + + + + +
+
+
+ + + +
+ + +
+
+ + + +
+
+ + +
+
+
+ +
+
    +
  • +
+
+
+ + +
+
+ +
+
+ + +
+
+
+ + + + + diff --git a/login-oauth2-server/pom.xml b/login-oauth2-server/pom.xml index 2dfd4c98..b83b047a 100644 --- a/login-oauth2-server/pom.xml +++ b/login-oauth2-server/pom.xml @@ -26,6 +26,12 @@ org.springframework.security spring-security-core + + + org.springframework + spring-core + + org.springframework.security @@ -37,6 +43,10 @@ spring-security-oauth2-autoconfigure 2.0.0.RELEASE + + com.fasterxml.jackson.core + jackson-annotations + org.springframework spring-core 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 index 28a859a6..fcb2abb8 100644 --- 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 @@ -2,13 +2,15 @@ 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.Oauth2ClientDetailsServiceImpl; -import ink.wgink.login.oauth2.server.service.impl.Oauth2ClientTokenServiceImpl; +import ink.wgink.login.oauth2.server.service.impl.OAuth2ClientDetailsServiceImpl; +import ink.wgink.login.oauth2.server.service.impl.OAuth2ClientTokenServiceImpl; 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.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; 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; @@ -52,14 +54,18 @@ public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigur @Autowired private IUserService userService; @Autowired - private Oauth2ClientDetailsServiceImpl oAuth2ClientDetailsService; + private OAuth2ClientDetailsServiceImpl oAuth2ClientDetailsService; + @Autowired + private OAuth2ClientTokenServiceImpl oAuth2ClientTokenService; @Autowired - private Oauth2ClientTokenServiceImpl oAuth2ClientTokenService; private AuthenticationManager authenticationManager; + @Autowired + private PasswordEncoder passwordEncoder; + @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { - // 通过内存的方式来完成认证服务 + // 通过业务代码完成认证 clients.withClientDetails(oAuth2ClientDetailsService); } @@ -76,12 +82,12 @@ public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigur 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") + .pathMapping("/oauth/authorize", "/oauth2_client/authorize") + .pathMapping("/oauth/token", "/oauth2_client/token") + .pathMapping("/oauth/token_key", "/oauth2_client/token_key") + .pathMapping("/oauth/check_token", "/oauth2_client/check_token") + .pathMapping("/oauth/confirm_access", "/oauth2_client/confirm_access") + .pathMapping("/oauth/error", "/oauth2_client/error") .authenticationManager(authenticationManager) .tokenStore(jwtTokenStore()) .accessTokenConverter(jwtAccessTokenConverter()) @@ -152,5 +158,13 @@ public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigur return tokenStoreUserApprovalHandler; } + public static void main(String[] args) { + PasswordEncoder pe = new BCryptPasswordEncoder(); + System.out.println(pe.encode("dGdIYVJvaEwvdFovRG01REtyYmVuMi9xMXVzR0lIYmxoNmdSZ3R6MWE4WGxIdG9KZmEyTjJIRnI0dG1McEdEVA==")); +// boolean matches = pe.matches("dGdIYVJvaEwvdFovRG01REtyYmVuMi9xMXVzR0lIYmxoNmdSZ3R6MWE4WGxIdG9KZmEyTjJIRnI0dG1McEdEVA==", "$2a$10$.IjNieJzGGpC0Vv3gjIWB.Zjj1pi9VZS8M96zbbv3qj8gDsYX./h6"); + boolean matches = pe.matches("dGdIYVJvaEwvdFovRG01REtyYmVuMi9xMXVzR0lIYmxoNmdSZ3R6MWE4WGxIdG9KZmEyTjJIRnI0dG1McEdEVA==", "$2a$10$nopzmRLR8HneFyw2uccG9u3XNnK4Cupzb4BR0m/WzSGucB2Rsxwxq"); + System.out.println(matches); + + } } diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/config/OAuth2WebMvcConfigurer.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/config/OAuth2WebMvcConfigurer.java new file mode 100644 index 00000000..37fcdbce --- /dev/null +++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/config/OAuth2WebMvcConfigurer.java @@ -0,0 +1,27 @@ +package ink.wgink.login.oauth2.server.config; + +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import ink.wgink.login.oauth2.server.converter.OAuth2AccessTokenMessageConverter; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.util.List; + +/** + * @ClassName: OAuth2WebMvcConfigurer + * @Description: OAuth2配置,该类是为了处理由于使用了Fastjson而不是原本的Jackson所导致的token格式变化 + * @Author: wanggeng + * @Date: 2021/9/18 1:10 下午 + * @Version: 1.0 + */ +@Configuration +public class OAuth2WebMvcConfigurer implements WebMvcConfigurer { + + @Override + public void configureMessageConverters(List> converters) { + converters.add(0, new FastJsonHttpMessageConverter()); + converters.add(0, new OAuth2AccessTokenMessageConverter()); + } + +} diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/converter/OAuth2AccessTokenMessageConverter.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/converter/OAuth2AccessTokenMessageConverter.java new file mode 100644 index 00000000..97f5bcd5 --- /dev/null +++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/converter/OAuth2AccessTokenMessageConverter.java @@ -0,0 +1,60 @@ +package ink.wgink.login.oauth2.server.converter; + +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import org.springframework.http.HttpInputMessage; +import org.springframework.http.HttpOutputMessage; +import org.springframework.http.MediaType; +import org.springframework.http.converter.AbstractHttpMessageConverter; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.http.converter.HttpMessageNotWritableException; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.OAuth2RefreshToken; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * @ClassName: OAuth2AccessTokenMessageConverter + * @Description: OAuth2的Token解析类 + * @Author: wanggeng + * @Date: 2021/9/18 1:11 下午 + * @Version: 1.0 + */ +public class OAuth2AccessTokenMessageConverter extends AbstractHttpMessageConverter { + + private final FastJsonHttpMessageConverter delegateMessageConverter; + + public OAuth2AccessTokenMessageConverter() { + super(MediaType.APPLICATION_JSON); + this.delegateMessageConverter = new FastJsonHttpMessageConverter(); + } + + @Override + protected boolean supports(Class clazz) { + return OAuth2AccessToken.class.isAssignableFrom(clazz); + } + + @Override + protected OAuth2AccessToken readInternal(Class clazz, HttpInputMessage inputMessage) + throws IOException, HttpMessageNotReadableException { + throw new UnsupportedOperationException("This converter is only used for converting from externally aqcuired form data"); + } + + @Override + protected void writeInternal(OAuth2AccessToken accessToken, HttpOutputMessage outputMessage) throws IOException, + HttpMessageNotWritableException { + Map data = new HashMap<>(8); + data.put(OAuth2AccessToken.ACCESS_TOKEN, accessToken.getValue()); + data.put(OAuth2AccessToken.TOKEN_TYPE, accessToken.getTokenType()); + data.put(OAuth2AccessToken.EXPIRES_IN, accessToken.getExpiresIn()); + data.put(OAuth2AccessToken.SCOPE, String.join(" ", accessToken.getScope())); + OAuth2RefreshToken refreshToken = accessToken.getRefreshToken(); + if (Objects.nonNull(refreshToken)) { + data.put(OAuth2AccessToken.REFRESH_TOKEN, refreshToken.getValue()); + } + delegateMessageConverter.write(data, MediaType.APPLICATION_JSON, outputMessage); + } + +} 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 index 7aa3b038..f1baa509 100644 --- 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 @@ -1,5 +1,6 @@ package ink.wgink.login.oauth2.server.converter; +import com.alibaba.fastjson.JSONObject; import ink.wgink.pojo.bos.LoginUser; import ink.wgink.pojo.bos.UserInfoBO; import ink.wgink.service.user.service.IUserService; @@ -46,7 +47,7 @@ public class UserAuthConverter implements UserAuthenticationConverter { userInfoBO.setGroups(loginUser.getGroups()); userInfoBO.setPositions(loginUser.getPositions()); userInfoBO.setExpandData(loginUser.getExpandData()); - response.put("user_info", userInfoBO); + response.put("user_info", JSONObject.toJSONString(userInfoBO)); return response; } diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/endpoint/OAuth2ClientAuthorizationEndpoint.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/endpoint/OAuth2ClientAuthorizationEndpoint.java new file mode 100644 index 00000000..0efc0d29 --- /dev/null +++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/endpoint/OAuth2ClientAuthorizationEndpoint.java @@ -0,0 +1,427 @@ +package ink.wgink.login.oauth2.server.endpoint; + +import ink.wgink.login.oauth2.server.exceptions.OAuth2ClientBadClientCredentialsException; +import ink.wgink.login.oauth2.server.service.impl.OAuth2ClientDetailsServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.authentication.InsufficientAuthenticationException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.exceptions.*; +import org.springframework.security.oauth2.common.util.OAuth2Utils; +import org.springframework.security.oauth2.provider.*; +import org.springframework.security.oauth2.provider.approval.UserApprovalHandler; +import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices; +import org.springframework.security.oauth2.provider.endpoint.AbstractEndpoint; +import org.springframework.security.oauth2.provider.endpoint.DefaultRedirectResolver; +import org.springframework.security.oauth2.provider.endpoint.RedirectResolver; +import org.springframework.security.oauth2.provider.implicit.ImplicitTokenRequest; +import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestValidator; +import org.springframework.stereotype.Controller; +import org.springframework.util.StringUtils; +import org.springframework.web.HttpSessionRequiredException; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.support.DefaultSessionAttributeStore; +import org.springframework.web.bind.support.SessionAttributeStore; +import org.springframework.web.bind.support.SessionStatus; +import org.springframework.web.context.request.ServletWebRequest; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.View; +import org.springframework.web.servlet.view.RedirectView; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; + +import java.net.URI; +import java.security.Principal; +import java.util.*; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: OauthClientAuthorizationEndpoint + * @Description: Oauth客户端认证端口 + * @Author: WangGeng + * @Date: 2020/7/23 8:25 下午 + * @Version: 1.0 + **/ +@Controller +@SessionAttributes("authorizationRequest") +public class OAuth2ClientAuthorizationEndpoint extends AbstractEndpoint { + + private RedirectResolver redirectResolver = new DefaultRedirectResolver(); + + private SessionAttributeStore sessionAttributeStore = new DefaultSessionAttributeStore(); + private OAuth2RequestValidator oauth2RequestValidator = new DefaultOAuth2RequestValidator(); + private String userApprovalPage = "error/oauth_confirm_access"; + private String errorPage = "error/oauth_error"; + private Object implicitLock = new Object(); + @Autowired + private UserApprovalHandler userApprovalHandler; + @Autowired + private AuthorizationCodeServices authorizationCodeServices; + @Autowired + private OAuth2ClientDetailsServiceImpl oauthClientDetailsService; + @Autowired + private TokenGranter tokenGranter; + + @Override + public void afterPropertiesSet() throws Exception { + setTokenGranter(tokenGranter); + setClientDetailsService(oauthClientDetailsService); + super.afterPropertiesSet(); + } + + @RequestMapping(value = "/oauth2_client/authorize") + public ModelAndView authorize(Map model, + @RequestParam Map parameters, + SessionStatus sessionStatus, + Principal principal) { + AuthorizationRequest authorizationRequest = getOAuth2RequestFactory().createAuthorizationRequest(parameters); + Set responseTypes = authorizationRequest.getResponseTypes(); + if (!responseTypes.contains("token") && !responseTypes.contains("code")) { + throw new UnsupportedResponseTypeException("响应类型不支持: " + responseTypes); + } + if (authorizationRequest.getClientId() == null) { + throw new InvalidClientException("客户端不存在。"); + } + try { + if (!(principal instanceof Authentication) || !((Authentication) principal).isAuthenticated()) { + throw new InsufficientAuthenticationException("系统认证完成后才能进行用户认证。"); + } + ClientDetails client = getClientDetailsService().loadClientByClientId(authorizationRequest.getClientId()); + + String redirectUriParameter = authorizationRequest.getRequestParameters().get(OAuth2Utils.REDIRECT_URI); + String resolvedRedirect = redirectResolver.resolveRedirect(redirectUriParameter, client); + if (!StringUtils.hasText(resolvedRedirect)) { + throw new RedirectMismatchException("客户端必须提供重定向URI。"); + } + authorizationRequest.setRedirectUri(resolvedRedirect); + oauth2RequestValidator.validateScope(authorizationRequest, client); + authorizationRequest = userApprovalHandler.checkForPreApproval(authorizationRequest, (Authentication) principal); + boolean approved = userApprovalHandler.isApproved(authorizationRequest, (Authentication) principal); + authorizationRequest.setApproved(approved); + if (authorizationRequest.isApproved()) { + if (responseTypes.contains("token")) { + return getImplicitGrantResponse(authorizationRequest); + } + if (responseTypes.contains("code")) { + return new ModelAndView(getAuthorizationCodeResponse(authorizationRequest, + (Authentication) principal)); + } + } + model.put("authorizationRequest", authorizationRequest); + return getUserApprovalPageResponse(model, authorizationRequest, (Authentication) principal); + } catch (RuntimeException e) { + sessionStatus.setComplete(); + throw e; + } + } + + @RequestMapping(value = "/oauth2_client/authorize", method = RequestMethod.POST, params = OAuth2Utils.USER_OAUTH_APPROVAL) + public View approveOrDeny(@RequestParam Map approvalParameters, + Map model, + SessionStatus sessionStatus, + Principal principal) { + if (!(principal instanceof Authentication)) { + sessionStatus.setComplete(); + throw new InsufficientAuthenticationException( + "在授权访问令牌之前,必须使系统对用户进行身份验证。"); + } + AuthorizationRequest authorizationRequest = (AuthorizationRequest) model.get("authorizationRequest"); + if (authorizationRequest == null) { + sessionStatus.setComplete(); + throw new InvalidRequestException("无法批准未初始化的授权请求。"); + } + + try { + Set responseTypes = authorizationRequest.getResponseTypes(); + authorizationRequest.setApprovalParameters(approvalParameters); + authorizationRequest = userApprovalHandler.updateAfterApproval(authorizationRequest, + (Authentication) principal); + boolean approved = userApprovalHandler.isApproved(authorizationRequest, (Authentication) principal); + authorizationRequest.setApproved(approved); + if (authorizationRequest.getRedirectUri() == null) { + sessionStatus.setComplete(); + throw new InvalidRequestException("未提供用于重定向的URI。"); + } + + if (!authorizationRequest.isApproved()) { + return new RedirectView(getUnsuccessfulRedirect(authorizationRequest, + new UserDeniedAuthorizationException("用户拒绝访问。"), responseTypes.contains("token")), + false, true, false); + } + if (responseTypes.contains("token")) { + return getImplicitGrantResponse(authorizationRequest).getView(); + } + return getAuthorizationCodeResponse(authorizationRequest, (Authentication) principal); + } finally { + sessionStatus.setComplete(); + } + } + + private ModelAndView getUserApprovalPageResponse(Map model, + AuthorizationRequest authorizationRequest, Authentication principal) { + logger.debug("Loading user approval page: " + userApprovalPage); + model.putAll(userApprovalHandler.getUserApprovalRequest(authorizationRequest, principal)); + return new ModelAndView(userApprovalPage, model); + } + + private ModelAndView getImplicitGrantResponse(AuthorizationRequest authorizationRequest) { + try { + TokenRequest tokenRequest = getOAuth2RequestFactory().createTokenRequest(authorizationRequest, "implicit"); + OAuth2Request storedOAuth2Request = getOAuth2RequestFactory().createOAuth2Request(authorizationRequest); + OAuth2AccessToken accessToken = getAccessTokenForImplicitGrant(tokenRequest, storedOAuth2Request); + if (accessToken == null) { + throw new UnsupportedResponseTypeException("不支持的响应类型: token"); + } + return new ModelAndView(new RedirectView(appendAccessToken(authorizationRequest, accessToken), false, true, + false)); + } catch (OAuth2Exception e) { + return new ModelAndView(new RedirectView(getUnsuccessfulRedirect(authorizationRequest, e, true), false, + true, false)); + } + } + + private OAuth2AccessToken getAccessTokenForImplicitGrant(TokenRequest tokenRequest, + OAuth2Request storedOAuth2Request) { + OAuth2AccessToken accessToken = null; + synchronized (this.implicitLock) { + accessToken = getTokenGranter().grant("implicit", + new ImplicitTokenRequest(tokenRequest, storedOAuth2Request)); + } + return accessToken; + } + + private View getAuthorizationCodeResponse(AuthorizationRequest authorizationRequest, Authentication authUser) { + try { + return new RedirectView(getSuccessfulRedirect(authorizationRequest, + generateCode(authorizationRequest, authUser)), false, true, false); + } catch (OAuth2Exception e) { + return new RedirectView(getUnsuccessfulRedirect(authorizationRequest, e, false), false, true, false); + } + } + + private String appendAccessToken(AuthorizationRequest authorizationRequest, OAuth2AccessToken accessToken) { + Map vars = new LinkedHashMap<>(); + Map keys = new HashMap<>(); + if (accessToken == null) { + throw new InvalidRequestException("无法完成implicit授权"); + } + vars.put("access_token", accessToken.getValue()); + vars.put("token_type", accessToken.getTokenType()); + String state = authorizationRequest.getState(); + if (state != null) { + vars.put("state", state); + } + Date expiration = accessToken.getExpiration(); + if (expiration != null) { + long expires_in = (expiration.getTime() - System.currentTimeMillis()) / 1000; + vars.put("expires_in", expires_in); + } + String originalScope = authorizationRequest.getRequestParameters().get(OAuth2Utils.SCOPE); + if (originalScope == null || !OAuth2Utils.parseParameterList(originalScope).equals(accessToken.getScope())) { + vars.put("scope", OAuth2Utils.formatParameterList(accessToken.getScope())); + } + Map additionalInformation = accessToken.getAdditionalInformation(); + for (String key : additionalInformation.keySet()) { + Object value = additionalInformation.get(key); + if (value != null) { + keys.put("extra_" + key, key); + vars.put("extra_" + key, value); + } + } + return append(authorizationRequest.getRedirectUri(), vars, keys, true); + } + + private String generateCode(AuthorizationRequest authorizationRequest, Authentication authentication) + throws AuthenticationException { + try { + OAuth2Request storedOAuth2Request = getOAuth2RequestFactory().createOAuth2Request(authorizationRequest); + OAuth2Authentication combinedAuth = new OAuth2Authentication(storedOAuth2Request, authentication); + String code = authorizationCodeServices.createAuthorizationCode(combinedAuth); + return code; + } catch (OAuth2Exception e) { + if (authorizationRequest.getState() != null) { + e.addAdditionalInformation("state", authorizationRequest.getState()); + } + throw e; + } + } + + private String getSuccessfulRedirect(AuthorizationRequest authorizationRequest, String authorizationCode) { + if (authorizationCode == null) { + throw new IllegalStateException("在当前请求范围中找不到授权码"); + } + Map query = new LinkedHashMap<>(); + query.put("code", authorizationCode); + String state = authorizationRequest.getState(); + if (state != null) { + query.put("state", state); + } + return append(authorizationRequest.getRedirectUri(), query, false); + } + + private String getUnsuccessfulRedirect(AuthorizationRequest authorizationRequest, OAuth2Exception failure, + boolean fragment) { + if (authorizationRequest == null || authorizationRequest.getRedirectUri() == null) { + throw new UnapprovedClientAuthenticationException("授权失败,并且没有重定向URI。", failure); + } + + Map query = new LinkedHashMap<>(); + query.put("error", failure.getOAuth2ErrorCode()); + query.put("error_description", failure.getMessage()); + if (authorizationRequest.getState() != null) { + query.put("state", authorizationRequest.getState()); + } + if (failure.getAdditionalInformation() != null) { + for (Map.Entry additionalInfo : failure.getAdditionalInformation().entrySet()) { + query.put(additionalInfo.getKey(), additionalInfo.getValue()); + } + } + return append(authorizationRequest.getRedirectUri(), query, fragment); + } + + private String append(String base, Map query, boolean fragment) { + return append(base, query, null, fragment); + } + + private String append(String base, Map query, Map keys, boolean fragment) { + UriComponentsBuilder template = UriComponentsBuilder.newInstance(); + UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(base); + URI redirectUri; + try { + redirectUri = builder.build(true).toUri(); + } catch (Exception e) { + redirectUri = builder.build().toUri(); + builder = UriComponentsBuilder.fromUri(redirectUri); + } + template.scheme(redirectUri.getScheme()).port(redirectUri.getPort()).host(redirectUri.getHost()) + .userInfo(redirectUri.getUserInfo()).path(redirectUri.getPath()); + if (fragment) { + StringBuilder values = new StringBuilder(); + if (redirectUri.getFragment() != null) { + String append = redirectUri.getFragment(); + values.append(append); + } + for (String key : query.keySet()) { + if (values.length() > 0) { + values.append("&"); + } + String name = key; + if (keys != null && keys.containsKey(key)) { + name = keys.get(key); + } + values.append(name + "={" + key + "}"); + } + if (values.length() > 0) { + template.fragment(values.toString()); + } + UriComponents encoded = template.build().expand(query).encode(); + builder.fragment(encoded.getFragment()); + } else { + for (String key : query.keySet()) { + String name = key; + if (keys != null && keys.containsKey(key)) { + name = keys.get(key); + } + template.queryParam(name, "{" + key + "}"); + } + template.fragment(redirectUri.getFragment()); + UriComponents encoded = template.build().expand(query).encode(); + builder.query(encoded.getQuery()); + } + return builder.build().toUriString(); + } + + public void setUserApprovalPage(String userApprovalPage) { + this.userApprovalPage = userApprovalPage; + } + + public void setAuthorizationCodeServices(AuthorizationCodeServices authorizationCodeServices) { + this.authorizationCodeServices = authorizationCodeServices; + } + + public void setRedirectResolver(RedirectResolver redirectResolver) { + this.redirectResolver = redirectResolver; + } + + public void setUserApprovalHandler(UserApprovalHandler userApprovalHandler) { + this.userApprovalHandler = userApprovalHandler; + } + + public void setOAuth2RequestValidator(OAuth2RequestValidator oauth2RequestValidator) { + this.oauth2RequestValidator = oauth2RequestValidator; + } + + @SuppressWarnings("deprecation") + public void setImplicitGrantService( + org.springframework.security.oauth2.provider.implicit.ImplicitGrantService implicitGrantService) { + } + + @ExceptionHandler(ClientRegistrationException.class) + public ModelAndView handleClientRegistrationException(Exception e, ServletWebRequest webRequest) throws Exception { + logger.info("Handling ClientRegistrationException error: " + e.getMessage()); + return handleException(new OAuth2ClientBadClientCredentialsException(e.getMessage()), webRequest); + } + + @ExceptionHandler(OAuth2Exception.class) + public ModelAndView handleOAuth2Exception(OAuth2Exception e, ServletWebRequest webRequest) throws Exception { + logger.info("Handling OAuth2 error: " + e.getSummary()); + return handleException(e, webRequest); + } + + @ExceptionHandler(HttpSessionRequiredException.class) + public ModelAndView handleHttpSessionRequiredException(HttpSessionRequiredException e, ServletWebRequest webRequest) + throws Exception { + logger.info("Handling Session required error: " + e.getMessage()); + return handleException(new AccessDeniedException("无法从会话获取授权请求。", e), + webRequest); + } + + private ModelAndView handleException(Exception e, ServletWebRequest webRequest) throws Exception { + ResponseEntity translate = getExceptionTranslator().translate(e); + webRequest.getResponse().setStatus(translate.getStatusCode().value()); + if (e instanceof ClientAuthenticationException || e instanceof RedirectMismatchException) { + return new ModelAndView(errorPage, Collections.singletonMap("error", translate.getBody().getMessage())); + } + AuthorizationRequest authorizationRequest = null; + try { + authorizationRequest = getAuthorizationRequestForError(webRequest); + String requestedRedirectParam = authorizationRequest.getRequestParameters().get(OAuth2Utils.REDIRECT_URI); + String requestedRedirect = redirectResolver.resolveRedirect(requestedRedirectParam, + getClientDetailsService().loadClientByClientId(authorizationRequest.getClientId())); + authorizationRequest.setRedirectUri(requestedRedirect); + String redirect = getUnsuccessfulRedirect(authorizationRequest, translate.getBody(), authorizationRequest + .getResponseTypes().contains("token")); + return new ModelAndView(new RedirectView(redirect, false, true, false)); + } catch (OAuth2Exception ex) { + return new ModelAndView(errorPage, Collections.singletonMap("error", translate.getBody().getMessage())); + } + + } + + private AuthorizationRequest getAuthorizationRequestForError(ServletWebRequest webRequest) { + AuthorizationRequest authorizationRequest = (AuthorizationRequest) sessionAttributeStore.retrieveAttribute( + webRequest, "authorizationRequest"); + if (authorizationRequest != null) { + return authorizationRequest; + } + Map parameters = new HashMap<>(); + Map map = webRequest.getParameterMap(); + for (String key : map.keySet()) { + String[] values = map.get(key); + if (values != null && values.length > 0) { + parameters.put(key, values[0]); + } + } + try { + return getOAuth2RequestFactory().createAuthorizationRequest(parameters); + } catch (Exception e) { + return getDefaultOAuth2RequestFactory().createAuthorizationRequest(parameters); + } + } + +} diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/endpoint/OAuth2ClientCheckTokenEndpoint.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/endpoint/OAuth2ClientCheckTokenEndpoint.java new file mode 100644 index 00000000..05297cbe --- /dev/null +++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/endpoint/OAuth2ClientCheckTokenEndpoint.java @@ -0,0 +1,91 @@ +package ink.wgink.login.oauth2.server.endpoint; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.http.ResponseEntity; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; +import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator; +import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator; +import org.springframework.security.oauth2.provider.token.AccessTokenConverter; +import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter; +import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.Map; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: OauthClientCheckTokenEndpoint + * @Description: Oauth客户端token校验 + * @Author: WangGeng + * @Date: 2020/7/24 11:10 上午 + * @Version: 1.0 + **/ +@Controller +public class OAuth2ClientCheckTokenEndpoint { + + private ResourceServerTokenServices resourceServerTokenServices; + + private AccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter(); + + protected final Log logger = LogFactory.getLog(getClass()); + + private WebResponseExceptionTranslator exceptionTranslator = new DefaultWebResponseExceptionTranslator(); + + public OAuth2ClientCheckTokenEndpoint(ResourceServerTokenServices resourceServerTokenServices) { + this.resourceServerTokenServices = resourceServerTokenServices; + } + + /** + * @param exceptionTranslator the exception translator to set + */ + public void setExceptionTranslator(WebResponseExceptionTranslator exceptionTranslator) { + this.exceptionTranslator = exceptionTranslator; + } + + /** + * @param accessTokenConverter the accessTokenConverter to set + */ + public void setAccessTokenConverter(AccessTokenConverter accessTokenConverter) { + this.accessTokenConverter = accessTokenConverter; + } + + @RequestMapping(value = "/oauth2_client/check_token") + @ResponseBody + public Map checkToken(@RequestParam("token") String value) { + OAuth2AccessToken token = resourceServerTokenServices.readAccessToken(value); + if (token == null) { + throw new InvalidTokenException("Token was not recognised"); + } + if (token.isExpired()) { + throw new InvalidTokenException("Token has expired"); + } + OAuth2Authentication authentication = resourceServerTokenServices.loadAuthentication(token.getValue()); + Map response = (Map) accessTokenConverter.convertAccessToken(token, authentication); + response.put("active", true); + return response; + } + + @ExceptionHandler(InvalidTokenException.class) + public ResponseEntity handleException(Exception e) throws Exception { + logger.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage()); + @SuppressWarnings("serial") + InvalidTokenException e400 = new InvalidTokenException(e.getMessage()) { + @Override + public int getHttpErrorCode() { + return 400; + } + }; + return exceptionTranslator.translate(e400); + } + +} diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/endpoint/OAuth2ClientTokenEndpoint.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/endpoint/OAuth2ClientTokenEndpoint.java new file mode 100644 index 00000000..6495403c --- /dev/null +++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/endpoint/OAuth2ClientTokenEndpoint.java @@ -0,0 +1,177 @@ +package ink.wgink.login.oauth2.server.endpoint; + +import ink.wgink.login.oauth2.server.exceptions.OAuth2ClientBadClientCredentialsException; +import ink.wgink.login.oauth2.server.service.impl.OAuth2ClientDetailsServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.InsufficientAuthenticationException; +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.exceptions.*; +import org.springframework.security.oauth2.common.util.OAuth2Utils; +import org.springframework.security.oauth2.provider.*; +import org.springframework.security.oauth2.provider.endpoint.AbstractEndpoint; +import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestValidator; +import org.springframework.stereotype.Controller; +import org.springframework.util.StringUtils; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +import java.security.Principal; +import java.util.*; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: OauthClientTokenEndpoint + * @Description: 客户端Token端口 + * @Author: WangGeng + * @Date: 2020/7/24 10:06 上午 + * @Version: 1.0 + **/ +@Controller +public class OAuth2ClientTokenEndpoint extends AbstractEndpoint { + + private OAuth2RequestValidator oAuth2RequestValidator = new DefaultOAuth2RequestValidator(); + private Set allowedRequestMethods = new HashSet(Arrays.asList(HttpMethod.POST)); + @Autowired + private TokenGranter tokenGranter; + @Autowired + private OAuth2ClientDetailsServiceImpl oauthClientDetailsService; + + @Override + public void afterPropertiesSet() throws Exception { + setTokenGranter(tokenGranter); + setClientDetailsService(oauthClientDetailsService); + super.afterPropertiesSet(); + } + + @RequestMapping(value = "/oauth2_client/token", method = RequestMethod.GET) + public ResponseEntity getAccessToken(Principal principal, + @RequestParam Map parameters) throws HttpRequestMethodNotSupportedException { + if (!allowedRequestMethods.contains(HttpMethod.GET)) { + throw new HttpRequestMethodNotSupportedException("GET"); + } + return postAccessToken(principal, parameters); + } + + @RequestMapping(value = "/oauth2_client/token", method = RequestMethod.POST) + public ResponseEntity postAccessToken(Principal principal, + @RequestParam Map parameters) throws HttpRequestMethodNotSupportedException { + if (!(principal instanceof Authentication)) { + throw new InsufficientAuthenticationException("无客户端身份验证。尝试添加适当的身份验证筛选器。"); + } + String clientId = getClientId(principal); + ClientDetails authenticatedClient = getClientDetailsService().loadClientByClientId(clientId); + TokenRequest tokenRequest = getOAuth2RequestFactory().createTokenRequest(parameters, authenticatedClient); + if (clientId != null && !clientId.equals("")) { + if (!clientId.equals(tokenRequest.getClientId())) { + throw new InvalidClientException("给定的客户端ID与经过身份验证的客户端不匹配。"); + } + } + if (authenticatedClient != null) { + oAuth2RequestValidator.validateScope(tokenRequest, authenticatedClient); + } + if (!StringUtils.hasText(tokenRequest.getGrantType())) { + throw new InvalidRequestException("缺少授权类型。"); + } + if (tokenRequest.getGrantType().equals("implicit")) { + throw new InvalidGrantException("令牌终结点不支持Implicit授予类型"); + } + if (isAuthCodeRequest(parameters)) { + if (!tokenRequest.getScope().isEmpty()) { + logger.debug("Clearing scope of incoming token request"); + tokenRequest.setScope(Collections.emptySet()); + } + } + if (isRefreshTokenRequest(parameters)) { + tokenRequest.setScope(OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.SCOPE))); + } + OAuth2AccessToken token = getTokenGranter().grant(tokenRequest.getGrantType(), tokenRequest); + if (token == null) { + throw new UnsupportedGrantTypeException("不支持的授权类型: " + tokenRequest.getGrantType()); + } + + return getResponse(token); + + } + + /** + * @param principal the currently authentication principal + * @return a client id if there is one in the principal + */ + protected String getClientId(Principal principal) { + Authentication client = (Authentication) principal; + if (!client.isAuthenticated()) { + throw new InsufficientAuthenticationException("客户端未经过身份验证。"); + } + String clientId = client.getName(); + if (client instanceof OAuth2Authentication) { + clientId = ((OAuth2Authentication) client).getOAuth2Request().getClientId(); + } + return clientId; + } + + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + public ResponseEntity handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) throws Exception { + if (logger.isErrorEnabled()) { + logger.error("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage(), e); + } + return getExceptionTranslator().translate(e); + } + + @ExceptionHandler(Exception.class) + public ResponseEntity handleException(Exception e) throws Exception { + if (logger.isErrorEnabled()) { + logger.error("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage(), e); + } + return getExceptionTranslator().translate(e); + } + + @ExceptionHandler(ClientRegistrationException.class) + public ResponseEntity handleClientRegistrationException(Exception e) throws Exception { + if (logger.isErrorEnabled()) { + logger.error("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage(), e); + } + return getExceptionTranslator().translate(new OAuth2ClientBadClientCredentialsException(e.getMessage())); + } + + @ExceptionHandler(OAuth2Exception.class) + public ResponseEntity handleException(OAuth2Exception e) throws Exception { + if (logger.isErrorEnabled()) { + logger.error("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage(), e); + } + return getExceptionTranslator().translate(e); + } + + private ResponseEntity getResponse(OAuth2AccessToken accessToken) { + HttpHeaders headers = new HttpHeaders(); + headers.set("Cache-Control", "no-store"); + headers.set("Pragma", "no-cache"); + return new ResponseEntity(accessToken, headers, HttpStatus.OK); + } + + private boolean isRefreshTokenRequest(Map parameters) { + return "refresh_token".equals(parameters.get("grant_type")) && parameters.get("refresh_token") != null; + } + + private boolean isAuthCodeRequest(Map parameters) { + return "authorization_code".equals(parameters.get("grant_type")) && parameters.get("code") != null; + } + + public void setOAuth2RequestValidator(OAuth2RequestValidator oAuth2RequestValidator) { + this.oAuth2RequestValidator = oAuth2RequestValidator; + } + + public void setAllowedRequestMethods(Set allowedRequestMethods) { + this.allowedRequestMethods = allowedRequestMethods; + } + +} diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/endpoint/OAuth2ClientTokenKeyEndpoint.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/endpoint/OAuth2ClientTokenKeyEndpoint.java new file mode 100644 index 00000000..a91e70d0 --- /dev/null +++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/endpoint/OAuth2ClientTokenKeyEndpoint.java @@ -0,0 +1,55 @@ +package ink.wgink.login.oauth2.server.endpoint; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.annotation.Resource; +import java.security.Principal; +import java.util.Map; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: OauthClientTokenKeyEndpoint + * @Description: Oauth客户端TokenKey端口 + * @Author: WangGeng + * @Date: 2020/7/26 9:59 上午 + * @Version: 1.0 + **/ +@Controller +public class OAuth2ClientTokenKeyEndpoint { + + protected final Log logger = LogFactory.getLog(getClass()); + + @Resource(name = "jwtAccessTokenConverter") + private JwtAccessTokenConverter converter; + + /** + * Get the verification key for the token signatures. The principal has to + * be provided only if the key is secret + * (shared not public). + * + * @param principal the currently authenticated user if there is one + * @return the key used to verify tokens + */ + @RequestMapping(value = "/oauth2_client/token_key", method = RequestMethod.GET) + @ResponseBody + public Map getKey(Principal principal) { + boolean flag = (principal == null || principal instanceof AnonymousAuthenticationToken) && !converter.isPublic(); + if (flag) { + throw new AccessDeniedException("您需要进行身份验证才能查看共享密钥"); + } + Map result = converter.getKey(); + return result; + } + + +} 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 index 3876bd08..00400749 100644 --- 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 @@ -1,7 +1,6 @@ package ink.wgink.login.oauth2.server.pojo.pos; -import ink.wgink.login.oauth2.server.pojo.dtos.OAuth2ClientSimpleDTO; -import io.swagger.annotations.ApiModel; +import java.io.Serializable; /** * @ClassName: OauthClientDTO @@ -10,9 +9,12 @@ import io.swagger.annotations.ApiModel; * @Date: 2019/1/8 7:43 PM * @Version: 1.0 **/ -@ApiModel -public class OAuth2ClientPO extends OAuth2ClientSimpleDTO { +public class OAuth2ClientPO implements Serializable{ + private static final long serialVersionUID = 2201386758342553263L; + private String clientId; + private String clientName; + private String webServerRedirectUri; private String resourceIds; private String clientSecret; private String scope; @@ -35,6 +37,30 @@ public class OAuth2ClientPO extends OAuth2ClientSimpleDTO { private String modifier; private Integer isDelete; + 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 getResourceIds() { return resourceIds == null ? "" : resourceIds.trim(); } @@ -163,12 +189,10 @@ public class OAuth2ClientPO extends OAuth2ClientSimpleDTO { this.systemIcon = systemIcon; } - @Override public String getGmtCreate() { return gmtCreate == null ? "" : gmtCreate.trim(); } - @Override public void setGmtCreate(String gmtCreate) { this.gmtCreate = gmtCreate; } 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 index fdc50612..cac08798 100644 --- 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 @@ -22,7 +22,7 @@ public interface IOAuth2ClientService { /** * 客户端加密规则 */ - String OAUTH_CLIENT_RULE = "WGINK_OAUTH2_CLIENT"; + String OAUTH_CLIENT_RULE = "WGINK_oauth2"; /** * 正常环境 */ diff --git a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/Oauth2ClientDetailsServiceImpl.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/OAuth2ClientDetailsServiceImpl.java similarity index 89% rename from login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/Oauth2ClientDetailsServiceImpl.java rename to login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/OAuth2ClientDetailsServiceImpl.java index 971ea237..f2566f76 100644 --- a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/Oauth2ClientDetailsServiceImpl.java +++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/OAuth2ClientDetailsServiceImpl.java @@ -19,9 +19,8 @@ import org.springframework.security.oauth2.provider.client.BaseClientDetails; import org.springframework.stereotype.Component; import java.io.IOException; -import java.util.HashSet; +import java.util.Arrays; import java.util.Map; -import java.util.Set; /** * When you feel like quitting. Think about why you started @@ -35,8 +34,8 @@ import java.util.Set; **/ @Primary @Component -public class Oauth2ClientDetailsServiceImpl implements ClientDetailsService { - private static final Logger LOG = LoggerFactory.getLogger(Oauth2ClientDetailsServiceImpl.class); +public class OAuth2ClientDetailsServiceImpl implements ClientDetailsService { + private static final Logger LOG = LoggerFactory.getLogger(OAuth2ClientDetailsServiceImpl.class); @Autowired private IOAuth2ClientService oAuth2ClientService; @@ -72,7 +71,7 @@ public class Oauth2ClientDetailsServiceImpl implements ClientDetailsService { oAuth2ClientPO.getScope(), oAuth2ClientPO.getAuthorizedGrantTypes(), oAuth2ClientPO.getAuthorities()); - + clientDetails.setAutoApproveScopes(Arrays.asList(oAuth2ClientPO.getAutoapprove().split(","))); clientDetails.setClientSecret(oAuth2ClientPO.getClientSecret()); clientDetails.setAccessTokenValiditySeconds(oAuth2ClientPO.getAccessTokenValidity()); clientDetails.setRefreshTokenValiditySeconds(oAuth2ClientPO.getRefreshTokenValidity()); @@ -91,14 +90,6 @@ public class Oauth2ClientDetailsServiceImpl implements ClientDetailsService { 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/Oauth2ClientTokenServiceImpl.java b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/OAuth2ClientTokenServiceImpl.java similarity index 99% rename from login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/Oauth2ClientTokenServiceImpl.java rename to login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/OAuth2ClientTokenServiceImpl.java index cf2c4479..84e76a92 100644 --- a/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/Oauth2ClientTokenServiceImpl.java +++ b/login-oauth2-server/src/main/java/ink/wgink/login/oauth2/server/service/impl/OAuth2ClientTokenServiceImpl.java @@ -32,7 +32,7 @@ import java.util.UUID; * @Version: 1.0 **/ @Component -public class Oauth2ClientTokenServiceImpl implements AuthorizationServerTokenServices, ResourceServerTokenServices, ConsumerTokenServices, InitializingBean { +public class OAuth2ClientTokenServiceImpl implements AuthorizationServerTokenServices, ResourceServerTokenServices, ConsumerTokenServices, InitializingBean { private int refreshTokenValiditySeconds = 7200; private int accessTokenValiditySeconds = 7200; @@ -46,7 +46,7 @@ public class Oauth2ClientTokenServiceImpl implements AuthorizationServerTokenSer private TokenEnhancer accessTokenEnhancer; private AuthenticationManager authenticationManager; - public Oauth2ClientTokenServiceImpl() { + public OAuth2ClientTokenServiceImpl() { } @Override diff --git a/login-oauth2-server/src/main/resources/mybatis/mapper/IOAuth2ClientDao.xml b/login-oauth2-server/src/main/resources/mybatis/mapper/oauth2-client-mapper.xml similarity index 97% rename from login-oauth2-server/src/main/resources/mybatis/mapper/IOAuth2ClientDao.xml rename to login-oauth2-server/src/main/resources/mybatis/mapper/oauth2-client-mapper.xml index 55c5b18f..04281dd3 100644 --- a/login-oauth2-server/src/main/resources/mybatis/mapper/IOAuth2ClientDao.xml +++ b/login-oauth2-server/src/main/resources/mybatis/mapper/oauth2-client-mapper.xml @@ -53,10 +53,10 @@ - + - - + + @@ -82,10 +82,10 @@ `system_summary` text COMMENT '系统介绍', `system_icon` varchar(255) DEFAULT NULL COMMENT '系统图标', `gmt_create` datetime DEFAULT NULL, - `creator` bigint(20) DEFAULT NULL, + `creator` char(36) DEFAULT NULL, `gmt_modified` datetime DEFAULT NULL, - `modifier` bigint(20) DEFAULT NULL, - `is_delete` int(2) DEFAULT '0', + `modifier` char(36) DEFAULT NULL, + `is_delete` int(1) DEFAULT '0', PRIMARY KEY (`client_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/login-oauth2-server/src/main/resources/templates/oauth2client/save.html b/login-oauth2-server/src/main/resources/templates/oauth2client/save.html index b5c7e703..acba2b12 100644 --- a/login-oauth2-server/src/main/resources/templates/oauth2client/save.html +++ b/login-oauth2-server/src/main/resources/templates/oauth2client/save.html @@ -204,7 +204,7 @@ return; } - top.restAjax.get(top.restAjax.path('api/file/listfilebyfileid', []), { + top.restAjax.get(top.restAjax.path('api/file/list', []), { ids: ids }, null, function(code, data) { refreshDownloadTemplet(fileName, data); @@ -285,7 +285,7 @@ // 初始化 function initData() { var loadLayerIndex; - top.restAjax.get(top.restAjax.path('api/oauthclient/getinitclient', []), {}, null, function(code, data) { + top.restAjax.get(top.restAjax.path('api/oauth2client/get-init', []), {}, null, function(code, data) { form.val('dataForm', { clientId: data.clientId, clientSecret: data.clientSecret, @@ -310,7 +310,7 @@ top.dialog.confirm(top.dataMessage.commit, function(index) { top.dialog.close(index); var loadLayerIndex; - top.restAjax.post(top.restAjax.path('api/oauthclient/saveoauthclient', []), formData.field, null, function(code, data) { + top.restAjax.post(top.restAjax.path('api/oauth2client/save', []), formData.field, null, function(code, data) { var layerIndex = top.dialog.msg(top.dataMessage.commitSuccess, { time: 0, btn: [top.dataMessage.button.yes, top.dataMessage.button.no], diff --git a/login-oauth2-server/src/main/resources/templates/oauth2client/update.html b/login-oauth2-server/src/main/resources/templates/oauth2client/update.html index b0b4c19d..470e8d8f 100644 --- a/login-oauth2-server/src/main/resources/templates/oauth2client/update.html +++ b/login-oauth2-server/src/main/resources/templates/oauth2client/update.html @@ -205,7 +205,7 @@ return; } - top.restAjax.get(top.restAjax.path('api/file/listfilebyfileid', []), { + top.restAjax.get(top.restAjax.path('api/file/list', []), { ids: ids }, null, function(code, data) { refreshDownloadTemplet(fileName, data); @@ -286,7 +286,7 @@ // 初始化 function initData() { var loadLayerIndex; - top.restAjax.get(top.restAjax.path('api/oauthclient/getoauthclient/{clientId}', [clientId]), {}, null, function(code, data) { + top.restAjax.get(top.restAjax.path('api/oauth2client/get/{clientId}', [clientId]), {}, null, function(code, data) { form.val('dataForm', { clientName: data.clientName, clientId: data.clientId, @@ -330,7 +330,7 @@ top.dialog.confirm(top.dataMessage.commit, function(index) { top.dialog.close(index); var loadLayerIndex; - top.restAjax.put(top.restAjax.path('api/oauthclient/updateoauthclient/{clientId}', [clientId]), formData.field, null, function(code, data) { + top.restAjax.put(top.restAjax.path('api/oauth2client/update/{clientId}', [clientId]), formData.field, null, function(code, data) { var layerIndex = top.dialog.msg(top.dataMessage.commitSuccess, { time: 0, btn: [top.dataMessage.button.yes, top.dataMessage.button.no], diff --git a/pom.xml b/pom.xml index 6fb8fd95..f869229b 100644 --- a/pom.xml +++ b/pom.xml @@ -44,7 +44,7 @@ 5.2.8.RELEASE - 5.5.2 + 5.1.3.RELEASE 2.3.3.RELEASE 1.2.24 20210307 @@ -153,16 +153,6 @@ spring-security-web ${spring-security.version} - - org.springframework.security - spring-security-oauth2-core - ${spring-security.version} - - - org.springframework.security - spring-security-oauth2-jose - ${spring-security.version} -