From b721d8e423076f869524b74c31befbda4f26f615 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B3=BD=E7=BF=B0?= <627617031@qq.com> Date: Tue, 9 Apr 2024 16:07:16 +0800 Subject: [PATCH 01/21] Add sso support for github oauth --- dinky-admin/pom.xml | 27 +++ .../java/org/dinky/configure/AppConfig.java | 15 +- .../org/dinky/controller/SsoCpntroller.java | 85 ++++++++ .../java/org/dinky/data/dto/LoginDTO.java | 11 ++ .../dinky/service/impl/UserServiceImpl.java | 45 ++++- .../sso/annotation/AnnotationConfig.java | 29 +++ .../dinky/sso/annotation/CommonAspect.java | 59 ++++++ .../sso/annotation/ui/RequireAllRoles.java | 19 ++ .../sso/annotation/ui/RequireAnyRole.java | 19 ++ .../sso/annotation/ui/UIAnnotationAspect.java | 25 +++ .../sso/annotation/ws/RequireAllRoles.java | 19 ++ .../sso/annotation/ws/RequireAnyRole.java | 19 ++ .../sso/annotation/ws/WSAnnotationAspect.java | 25 +++ .../dinky/sso/component/ComponentConfig.java | 53 +++++ .../org/dinky/sso/web/CallbackController.java | 125 ++++++++++++ .../org/dinky/sso/web/LogoutController.java | 66 +++++++ .../dinky/sso/web/SecurityInterceptor.java | 181 ++++++++++++++++++ .../java/org/dinky/data/enums/Status.java | 9 +- .../java/org/dinky/data/enums/UserType.java | 3 +- 19 files changed, 827 insertions(+), 7 deletions(-) create mode 100644 dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java create mode 100644 dinky-admin/src/main/java/org/dinky/sso/annotation/AnnotationConfig.java create mode 100644 dinky-admin/src/main/java/org/dinky/sso/annotation/CommonAspect.java create mode 100644 dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAllRoles.java create mode 100644 dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAnyRole.java create mode 100644 dinky-admin/src/main/java/org/dinky/sso/annotation/ui/UIAnnotationAspect.java create mode 100644 dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAllRoles.java create mode 100644 dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAnyRole.java create mode 100644 dinky-admin/src/main/java/org/dinky/sso/annotation/ws/WSAnnotationAspect.java create mode 100644 dinky-admin/src/main/java/org/dinky/sso/component/ComponentConfig.java create mode 100644 dinky-admin/src/main/java/org/dinky/sso/web/CallbackController.java create mode 100644 dinky-admin/src/main/java/org/dinky/sso/web/LogoutController.java create mode 100644 dinky-admin/src/main/java/org/dinky/sso/web/SecurityInterceptor.java diff --git a/dinky-admin/pom.xml b/dinky-admin/pom.xml index 5d64298fd4..3826d9a64d 100644 --- a/dinky-admin/pom.xml +++ b/dinky-admin/pom.xml @@ -33,9 +33,36 @@ provided 42.5.1 + + 4.2.0 + + + + + org.pac4j + pac4j-springboot + ${pac4jVersion} + + + org.apache.logging.log4j + log4j-to-slf4j + + + org.apache.logging.log4j + log4j-api + + + commons-collections + commons-collections + + + + + + org.mitre.dsmiley.httpproxy smiley-http-proxy-servlet diff --git a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java index 2f2bdb3a67..313a0e582a 100644 --- a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java +++ b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java @@ -25,6 +25,12 @@ import java.util.Locale; +import org.dinky.sso.web.SecurityInterceptor; +import org.pac4j.core.config.Config; + +import org.pac4j.core.http.adapter.JEEHttpActionAdapter; + +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; @@ -32,7 +38,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.i18n.CookieLocaleResolver; -import cn.dev33.satoken.exception.StopMatchException; + import cn.dev33.satoken.exception.StopMatchException; import cn.dev33.satoken.interceptor.SaInterceptor; import cn.dev33.satoken.router.SaRouter; import cn.dev33.satoken.stp.StpUtil; @@ -44,6 +50,8 @@ */ @Configuration public class AppConfig implements WebMvcConfigurer { + @Autowired + Config config; /** * Cookie * @@ -86,7 +94,7 @@ public void addInterceptors(InterceptorRegistry registry) { })) .addPathPatterns("/api/**", "/openapi/**") .excludePathPatterns("/api/login", "/api/ldap/ldapEnableStatus", "/download/**", "/druid/**"); - + registry.addInterceptor(buildInterceptor("GitHubClient")).addPathPatterns("/sso/*"); registry.addInterceptor(new TenantInterceptor()) .addPathPatterns("/api/**") .excludePathPatterns("/api/login", "/api/ldap/ldapEnableStatus") @@ -109,4 +117,7 @@ public void addInterceptors(InterceptorRegistry registry) { .addPathPatterns("/api/git/**") .addPathPatterns("/api/jar/*"); } + private SecurityInterceptor buildInterceptor(final String client) { + return new SecurityInterceptor(config, client, JEEHttpActionAdapter.INSTANCE); + } } diff --git a/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java b/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java new file mode 100644 index 0000000000..4a56db8497 --- /dev/null +++ b/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java @@ -0,0 +1,85 @@ +package org.dinky.controller; + +import lombok.NoArgsConstructor; +import org.dinky.data.dto.LoginDTO; +import org.dinky.data.dto.UserDTO; +import org.dinky.data.enums.Status; +import org.dinky.data.exception.AuthException; +import org.dinky.data.result.Result; +import org.dinky.service.UserService; +import org.dinky.sso.web.LogoutController; +import org.pac4j.core.config.Config; + + +import org.pac4j.core.context.JEEContext; +import org.pac4j.core.profile.CommonProfile; +import org.pac4j.core.profile.ProfileManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.PostConstruct; +import java.util.List; + + +/** + * @author 杨泽翰 + */ +@RestController +@NoArgsConstructor +@ConfigurationProperties(prefix = "pac4j") +public class SsoCpntroller { + + + + @Value("${sso.centralLogout.defaultUrl:#{null}}") + private String defaultUrl; + + @Value("${sso.centralLogout.logoutUrlPattern:#{null}}") + private String logoutUrlPattern; + @Value("${pac4j.properties.principalNameAttribute:#{null}}") + private String principalNameAttribute; + @Autowired + private Config config; + @Autowired + private JEEContext webContext; + @Autowired + private ProfileManager profileManager; + private LogoutController logoutController; + + @Autowired + private UserService userService; + + @PostConstruct + protected void afterPropertiesSet() { + logoutController = new LogoutController(); + logoutController.setDefaultUrl(defaultUrl); + logoutController.setLogoutUrlPattern(logoutUrlPattern); + logoutController.setLocalLogout(true); + logoutController.setCentralLogout(true); + logoutController.setConfig(config); + logoutController.setDestroySession(true); + } + + @GetMapping ("/sso/token") + public Result token() throws AuthException { + + System.out.println(config); + List all = profileManager.getAll(true); + String username = all.get(0).getAttribute(principalNameAttribute).toString(); + if (username == null){ + throw new AuthException(Status.NOT_MATCHED_PRINCIPAL_NAME_ATTRIBUTE); + } + LoginDTO loginDTO = new LoginDTO(); + loginDTO.setUsername(username); + loginDTO.setSsoLogin(true); + return userService.loginUser(loginDTO); + } + @GetMapping ("/sso/logout") + public void logout() { + logoutController.logout(webContext.getNativeRequest(), webContext.getNativeResponse()); + } + +} diff --git a/dinky-admin/src/main/java/org/dinky/data/dto/LoginDTO.java b/dinky-admin/src/main/java/org/dinky/data/dto/LoginDTO.java index 5794585d4a..b73820f117 100644 --- a/dinky-admin/src/main/java/org/dinky/data/dto/LoginDTO.java +++ b/dinky-admin/src/main/java/org/dinky/data/dto/LoginDTO.java @@ -23,6 +23,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; +import org.dinky.data.enums.UserType; /** * LoginUTO @@ -48,4 +49,14 @@ public class LoginDTO { @ApiModelProperty(value = "ldapLogin", required = true, example = "false", dataType = "Boolean") private boolean ldapLogin; + @ApiModelProperty(value = "ssoLogin", required = true, example = "false", dataType = "Boolean") + private boolean ssoLogin; + + + public UserType getLoginType() { + + + return isLdapLogin()? UserType.LDAP:UserType.SSO; + + } } diff --git a/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java b/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java index 11b867efad..06a61d78d5 100644 --- a/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java +++ b/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java @@ -177,9 +177,19 @@ public Boolean removeUser(Integer id) { @Override public Result loginUser(LoginDTO loginDTO) { User user = null; + try { - // Determine the login method (LDAP or local) based on the flag in loginDTO - user = loginDTO.isLdapLogin() ? ldapLogin(loginDTO) : localLogin(loginDTO); + + switch (loginDTO.getLoginType()){ + case LDAP: + user = ldapLogin(loginDTO); + break; + case SSO: + user = ssoLogin(loginDTO); + break; + default: + user = localLogin(loginDTO); + } } catch (AuthException e) { // Handle authentication exceptions and return the corresponding error status return Result.authorizeFailed(e.getStatus()); @@ -210,6 +220,37 @@ public Result loginUser(LoginDTO loginDTO) { return Result.succeed(userInfo, Status.LOGIN_SUCCESS); } + private User ssoLogin(LoginDTO loginDTO) throws AuthException { + // Get user from local database by username + User user = getUserByUsername(loginDTO.getUsername()); + if (Asserts.isNull(user)) { + // User doesn't exist,Create a user + // Get default tenant from system configuration + String defaultTeantCode = + SystemConfiguration.getInstances().getLdapDefaultTeant().getValue(); + Tenant tenant = tenantService.getTenantByTenantCode(defaultTeantCode); + User userForm = new User(); + userForm.setUsername(loginDTO.getUsername()); + userForm.setNickname(loginDTO.getUsername()); + userForm.setUserType(UserType.SSO.getCode()); + userForm.setEnabled(true); + userForm.setSuperAdminFlag(false); + userForm.setIsDelete(false); + this.getBaseMapper().insert(userForm); + // Assign the user to the default tenant + List userIds = getUserIdsByTenantId(tenant.getId()); + userIds.add(userForm.getId()); + tenantService.assignUserToTenant(new AssignUserToTenantDTO(tenant.getId(), userIds)); + return userForm; + } + else{ + if (user.getUserType() != UserType.SSO.getCode()) { + throw new AuthException(Status.USER_TYPE_ERROR); + } + } + return user; + } + private void upsertToken(UserDTO userInfo) { Integer userId = userInfo.getUser().getId(); SysToken sysToken = new SysToken(); diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/AnnotationConfig.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/AnnotationConfig.java new file mode 100644 index 0000000000..7920246080 --- /dev/null +++ b/dinky-admin/src/main/java/org/dinky/sso/annotation/AnnotationConfig.java @@ -0,0 +1,29 @@ +package org.dinky.sso.annotation; + + +import org.dinky.sso.annotation.ui.UIAnnotationAspect; +import org.dinky.sso.annotation.ws.WSAnnotationAspect; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; + +/** + * The configuration for aspects. + * + * @author Jerome Leleu + * @since 3.2.0 + */ +@Configuration +@EnableAspectJAutoProxy +public class AnnotationConfig { + + @Bean + public WSAnnotationAspect wsAnnotationAspect() { + return new WSAnnotationAspect(); + } + + @Bean + public UIAnnotationAspect uiAnnotationAspect() { + return new UIAnnotationAspect(); + } +} diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/CommonAspect.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/CommonAspect.java new file mode 100644 index 0000000000..5ce7a47d0b --- /dev/null +++ b/dinky-admin/src/main/java/org/dinky/sso/annotation/CommonAspect.java @@ -0,0 +1,59 @@ +package org.dinky.sso.annotation; + +import org.pac4j.core.authorization.authorizer.IsAuthenticatedAuthorizer; +import org.pac4j.core.authorization.authorizer.RequireAllRolesAuthorizer; +import org.pac4j.core.authorization.authorizer.RequireAnyRoleAuthorizer; +import org.pac4j.core.context.JEEContext; +import org.pac4j.core.exception.http.ForbiddenAction; +import org.pac4j.core.exception.http.UnauthorizedAction; +import org.pac4j.core.profile.CommonProfile; +import org.pac4j.core.profile.ProfileManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * Common aspect behaviors. + * + * @author Jerome Leleu + * @since 3.2.0 + */ +@Component +public class CommonAspect { + + private static final IsAuthenticatedAuthorizer IS_AUTHENTICATED_AUTHORIZER = new IsAuthenticatedAuthorizer(); + + @Autowired + private JEEContext webContext; + + @Autowired + private ProfileManager profileManager; + + protected List isAuthenticated(final boolean readFromSession) { + final List profiles = profileManager.getAll(readFromSession); + + if (!IS_AUTHENTICATED_AUTHORIZER.isAuthorized(webContext, profiles)) { + throw UnauthorizedAction.INSTANCE; + } + return profiles; + } + + protected void requireAnyRole(final boolean readFromSession, final String... roles) { + final List profiles = isAuthenticated(readFromSession); + + final RequireAnyRoleAuthorizer authorizer = new RequireAnyRoleAuthorizer<>(roles); + if (!authorizer.isAuthorized(webContext, profiles)) { + throw ForbiddenAction.INSTANCE; + } + } + + protected void requireAllRoles(final boolean readFromSession, final String... roles) { + final List profiles = isAuthenticated(readFromSession); + + final RequireAllRolesAuthorizer authorizer = new RequireAllRolesAuthorizer<>(roles); + if (!authorizer.isAuthorized(webContext, profiles)) { + throw ForbiddenAction.INSTANCE; + } + } +} diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAllRoles.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAllRoles.java new file mode 100644 index 0000000000..e91e688ae9 --- /dev/null +++ b/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAllRoles.java @@ -0,0 +1,19 @@ +package org.dinky.sso.annotation.ui; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The "require all roles" authorization check. + * + * @author Jerome Leleu + * @since 3.2.0 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface RequireAllRoles { + + String[] value() default {}; +} diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAnyRole.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAnyRole.java new file mode 100644 index 0000000000..2103bcc133 --- /dev/null +++ b/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAnyRole.java @@ -0,0 +1,19 @@ +package org.dinky.sso.annotation.ui; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The "require any role" authorization check. + * + * @author Jerome Leleu + * @since 3.2.0 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface RequireAnyRole { + + String[] value() default {}; +} diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/UIAnnotationAspect.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/UIAnnotationAspect.java new file mode 100644 index 0000000000..2024f06d3d --- /dev/null +++ b/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/UIAnnotationAspect.java @@ -0,0 +1,25 @@ +package org.dinky.sso.annotation.ui; + +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.dinky.sso.annotation.CommonAspect; + +/** + * The aspect to define the web applications annotations. + * + * @author Jerome Leleu + * @since 3.2.0 + */ +@Aspect +public class UIAnnotationAspect extends CommonAspect { + + @Before("@annotation(requireAnyRole)") + public void beforeRequireAnyRole(final RequireAnyRole requireAnyRole) { + requireAnyRole(true, requireAnyRole.value()); + } + + @Before("@annotation(requireAllRoles)") + public void beforeRequireAllRoles(final RequireAllRoles requireAllRoles) { + requireAllRoles(true, requireAllRoles.value()); + } +} diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAllRoles.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAllRoles.java new file mode 100644 index 0000000000..07ebfe693d --- /dev/null +++ b/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAllRoles.java @@ -0,0 +1,19 @@ +package org.dinky.sso.annotation.ws; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The "require all roles" authorization check. + * + * @author Jerome Leleu + * @since 3.2.0 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface RequireAllRoles { + + String[] value() default {}; +} diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAnyRole.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAnyRole.java new file mode 100644 index 0000000000..f67b8ac320 --- /dev/null +++ b/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAnyRole.java @@ -0,0 +1,19 @@ +package org.dinky.sso.annotation.ws; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The "require any role" authorization check. + * + * @author Jerome Leleu + * @since 3.2.0 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface RequireAnyRole { + + String[] value() default {}; +} diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/WSAnnotationAspect.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/WSAnnotationAspect.java new file mode 100644 index 0000000000..27d3d51b0b --- /dev/null +++ b/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/WSAnnotationAspect.java @@ -0,0 +1,25 @@ +package org.dinky.sso.annotation.ws; + +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.dinky.sso.annotation.CommonAspect; + +/** + * The aspect to define the web services annotations. + * + * @author Jerome Leleu + * @since 3.2.0 + */ +@Aspect +public class WSAnnotationAspect extends CommonAspect { + + @Before("@annotation(requireAnyRole)") + public void beforeRequireAnyRole(final RequireAnyRole requireAnyRole) { + requireAnyRole(false, requireAnyRole.value()); + } + + @Before("@annotation(requireAllRoles)") + public void beforeRequireAllRoles(final RequireAllRoles requireAllRoles) { + requireAllRoles(false, requireAllRoles.value()); + } +} diff --git a/dinky-admin/src/main/java/org/dinky/sso/component/ComponentConfig.java b/dinky-admin/src/main/java/org/dinky/sso/component/ComponentConfig.java new file mode 100644 index 0000000000..b4b7a89a3d --- /dev/null +++ b/dinky-admin/src/main/java/org/dinky/sso/component/ComponentConfig.java @@ -0,0 +1,53 @@ +package org.dinky.sso.component; + +import org.pac4j.core.config.Config; +import org.pac4j.core.context.JEEContext; +import org.pac4j.core.context.session.JEESessionStore; +import org.pac4j.core.context.session.SessionStore; +import org.pac4j.core.profile.ProfileManager; +import org.pac4j.core.util.FindBest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.context.annotation.RequestScope; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * The configuration of the pac4j components. + * + * @author Jerome Leleu + * @since 3.2.0 + */ +@Configuration +public class ComponentConfig { + + @Autowired + protected HttpServletRequest request; + + @Autowired + protected HttpServletResponse response; + + @Autowired(required = false) + protected Config config; + + @Autowired(required = false) + protected SessionStore sessionStore; + + protected SessionStore getSessionStore() { + return FindBest.sessionStore(sessionStore, config, JEESessionStore.INSTANCE); + } + + @Bean + @RequestScope + public JEEContext getWebContext() { + return new JEEContext(request, response, getSessionStore()); + } + + @Bean + @RequestScope + public ProfileManager getProfileManager() { + return new ProfileManager<>(getWebContext()); + } +} diff --git a/dinky-admin/src/main/java/org/dinky/sso/web/CallbackController.java b/dinky-admin/src/main/java/org/dinky/sso/web/CallbackController.java new file mode 100644 index 0000000000..40c134e4bd --- /dev/null +++ b/dinky-admin/src/main/java/org/dinky/sso/web/CallbackController.java @@ -0,0 +1,125 @@ +package org.dinky.sso.web; + +import org.pac4j.core.config.Config; +import org.pac4j.core.context.JEEContext; +import org.pac4j.core.context.JEEContextFactory; +import org.pac4j.core.context.session.JEESessionStore; +import org.pac4j.core.context.session.SessionStore; +import org.pac4j.core.engine.CallbackLogic; +import org.pac4j.core.engine.DefaultCallbackLogic; +import org.pac4j.core.http.adapter.HttpActionAdapter; +import org.pac4j.core.http.adapter.JEEHttpActionAdapter; +import org.pac4j.core.util.FindBest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + *

This controller finishes the login process for an indirect client.

+ * + * @author Jerome Leleu + * @since 1.0.0 + */ +@Controller +public class CallbackController { + + private CallbackLogic callbackLogic; + + @Value("${pac4j.callback.defaultUrl:#{null}}") + private String defaultUrl; + + @Value("${pac4j.callback.multiProfile:#{null}}") + private Boolean multiProfile; + + @Value("${pac4j.callback.saveInSession:#{null}}") + private Boolean saveInSession; + + @Value("${pac4j.callback.renewSession:#{null}}") + private Boolean renewSession; + + @Value("${pac4j.callback.defaultClient:#{null}}") + private String defaultClient; + + @Autowired + private Config config; + + @RequestMapping("${pac4j.callback.path:/callback}") + public void callback(final HttpServletRequest request, final HttpServletResponse response) { + + final SessionStore bestSessionStore = FindBest.sessionStore(null, config, JEESessionStore.INSTANCE); + final HttpActionAdapter bestAdapter = FindBest.httpActionAdapter(null, config, JEEHttpActionAdapter.INSTANCE); + final CallbackLogic bestLogic = FindBest.callbackLogic(callbackLogic, config, DefaultCallbackLogic.INSTANCE); + + final JEEContext context = (JEEContext) FindBest.webContextFactory(null, config, JEEContextFactory.INSTANCE) + .newContext(request, response, bestSessionStore); + bestLogic.perform(context, config, bestAdapter, this.defaultUrl, this.saveInSession, this.multiProfile, + this.renewSession, this.defaultClient); + } + + @RequestMapping("${pac4j.callback.path/{cn}:/callback/{cn}}") + public void callbackWithClientName(final HttpServletRequest request, final HttpServletResponse response, @PathVariable("cn") final String cn) { + + callback(request, response); + } + + public String getDefaultUrl() { + return defaultUrl; + } + + public void setDefaultUrl(final String defaultUrl) { + this.defaultUrl = defaultUrl; + } + + public CallbackLogic getCallbackLogic() { + return callbackLogic; + } + + public void setCallbackLogic(final CallbackLogic callbackLogic) { + this.callbackLogic = callbackLogic; + } + + public Boolean getMultiProfile() { + return multiProfile; + } + + public void setMultiProfile(final Boolean multiProfile) { + this.multiProfile = multiProfile; + } + + public Boolean getSaveInSession() { + return saveInSession; + } + + public void setSaveInSession(final Boolean saveInSession) { + this.saveInSession = saveInSession; + } + + public Boolean getRenewSession() { + return renewSession; + } + + public void setRenewSession(final Boolean renewSession) { + this.renewSession = renewSession; + } + + public String getDefaultClient() { + return defaultClient; + } + + public void setDefaultClient(final String client) { + this.defaultClient = client; + } + + public Config getConfig() { + return config; + } + + public void setConfig(final Config config) { + this.config = config; + } +} diff --git a/dinky-admin/src/main/java/org/dinky/sso/web/LogoutController.java b/dinky-admin/src/main/java/org/dinky/sso/web/LogoutController.java new file mode 100644 index 0000000000..09f0aa0a17 --- /dev/null +++ b/dinky-admin/src/main/java/org/dinky/sso/web/LogoutController.java @@ -0,0 +1,66 @@ +package org.dinky.sso.web; + +import lombok.Data; +import org.pac4j.core.config.Config; +import org.pac4j.core.context.JEEContext; +import org.pac4j.core.context.JEEContextFactory; +import org.pac4j.core.context.session.JEESessionStore; +import org.pac4j.core.context.session.SessionStore; +import org.pac4j.core.engine.DefaultLogoutLogic; +import org.pac4j.core.engine.LogoutLogic; +import org.pac4j.core.http.adapter.HttpActionAdapter; +import org.pac4j.core.http.adapter.JEEHttpActionAdapter; +import org.pac4j.core.util.FindBest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + *

This controller handles the (application + identity provider) logout process.

+ * + * @author Jerome Leleu + * @since 1.0.0 + */ +@Controller +@Data +public class LogoutController { + + private LogoutLogic logoutLogic; + + @Value("${sso.logout.defaultUrl:#{null}}") + private String defaultUrl; + + @Value("${sso.logout.logoutUrlPattern:#{null}}") + private String logoutUrlPattern; + + @Value("${sso.logout.localLogout:#{null}}") + private Boolean localLogout; + + @Value("${sso.logout.destroySession:#{null}}") + private Boolean destroySession; + + @Value("${sso.logout.centralLogout:#{null}}") + private Boolean centralLogout; + + @Autowired + private Config config; + + @RequestMapping("${sso.logout.path:/logout}") + public void logout(final HttpServletRequest request, final HttpServletResponse response) { + + final SessionStore bestSessionStore = FindBest.sessionStore(null, config, JEESessionStore.INSTANCE); + final HttpActionAdapter bestAdapter = FindBest.httpActionAdapter(null, config, JEEHttpActionAdapter.INSTANCE); + final LogoutLogic bestLogic = FindBest.logoutLogic(logoutLogic, config, DefaultLogoutLogic.INSTANCE); + + final JEEContext context = (JEEContext) FindBest.webContextFactory(null, config, JEEContextFactory.INSTANCE) + .newContext(request, response, bestSessionStore); + bestLogic.perform(context, config, bestAdapter, this.defaultUrl, this.logoutUrlPattern, + this.localLogout, this.destroySession, this.centralLogout); + } + + +} diff --git a/dinky-admin/src/main/java/org/dinky/sso/web/SecurityInterceptor.java b/dinky-admin/src/main/java/org/dinky/sso/web/SecurityInterceptor.java new file mode 100644 index 0000000000..933c96d8ab --- /dev/null +++ b/dinky-admin/src/main/java/org/dinky/sso/web/SecurityInterceptor.java @@ -0,0 +1,181 @@ +package org.dinky.sso.web; + +import org.pac4j.core.authorization.authorizer.Authorizer; +import org.pac4j.core.config.Config; +import org.pac4j.core.context.JEEContext; +import org.pac4j.core.context.JEEContextFactory; +import org.pac4j.core.context.session.JEESessionStore; +import org.pac4j.core.context.session.SessionStore; +import org.pac4j.core.engine.DefaultSecurityLogic; +import org.pac4j.core.engine.SecurityLogic; +import org.pac4j.core.http.adapter.HttpActionAdapter; +import org.pac4j.core.http.adapter.JEEHttpActionAdapter; +import org.pac4j.core.matching.matcher.Matcher; +import org.pac4j.core.util.FindBest; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.concurrent.atomic.AtomicInteger; + +/** + *

This interceptor protects an url.

+ * + * @author Jerome Leleu + * @since 1.0.0 + */ +public class SecurityInterceptor extends HandlerInterceptorAdapter { + + private static final AtomicInteger internalNumber = new AtomicInteger(1); + + private SecurityLogic securityLogic; + + private String clients; + + private String authorizers; + + private String matchers; + + private Boolean multiProfile; + + private Config config; + + private HttpActionAdapter httpActionAdapter; + + public SecurityInterceptor(final Config config) { + this.config = config; + } + + public SecurityInterceptor(final Config config, final String clients) { + this(config); + this.clients = clients; + } + + public SecurityInterceptor(final Config config, final String clients, final HttpActionAdapter httpActionAdapter) { + this.clients = clients; + this.config = config; + this.httpActionAdapter = httpActionAdapter; + } + + public SecurityInterceptor(final Config config, final String clients, final String authorizers) { + this(config, clients); + this.authorizers = authorizers; + } + + public SecurityInterceptor(final Config config, final String clients, final Authorizer[] authorizers) { + this(config, clients); + this.authorizers = addAuthorizers(config, authorizers); + } + + public SecurityInterceptor(final Config config, final String clients, final String authorizers, final String matchers) { + this(config, clients, authorizers); + this.matchers = matchers; + } + + public SecurityInterceptor(final Config config, final String clients, final Authorizer[] authorizers, final Matcher[] matchers) { + this(config, clients, addAuthorizers(config, authorizers)); + this.matchers = addMatchers(config, matchers); + } + + private static String addAuthorizers(final Config config, final Authorizer[] authorizers) { + final int n = internalNumber.getAndAdd(1); + final int nbAuthorizers = authorizers.length; + final StringBuilder names = new StringBuilder(""); + for (int i = 0; i < nbAuthorizers; i++) { + final String name = "$int_authorizer" + n + "." + i; + config.addAuthorizer(name, authorizers[i]); + if (i > 0) { + names.append(","); + } + names.append(name); + } + return names.toString(); + } + + private static String addMatchers(final Config config, final Matcher[] matchers) { + final int n = internalNumber.getAndAdd(1); + final int nbMatchers = matchers.length; + final StringBuilder names = new StringBuilder(""); + for (int i = 0; i < nbMatchers; i++) { + final String name = "$int_matcher" + n + "." + i; + config.addMatcher(name, matchers[i]); + if (i > 0) { + names.append(","); + } + names.append(name); + } + return names.toString(); + } + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + + final SessionStore bestSessionStore = FindBest.sessionStore(null, config, JEESessionStore.INSTANCE); + final HttpActionAdapter bestAdapter = FindBest.httpActionAdapter(httpActionAdapter, config, JEEHttpActionAdapter.INSTANCE); + final SecurityLogic bestLogic = FindBest.securityLogic(securityLogic, config, DefaultSecurityLogic.INSTANCE); + + final JEEContext context = (JEEContext) FindBest.webContextFactory(null, config, JEEContextFactory.INSTANCE) + .newContext(request, response, bestSessionStore); + final Object result = bestLogic.perform(context, config, (ctx, profiles, parameters) -> true, bestAdapter, clients, authorizers, matchers, multiProfile); + if (result == null) { + return false; + } + return Boolean.parseBoolean(result.toString()); + } + + public SecurityLogic getSecurityLogic() { + return securityLogic; + } + + public void setSecurityLogic(final SecurityLogic securityLogic) { + this.securityLogic = securityLogic; + } + + public String getClients() { + return clients; + } + + public void setClients(final String clients) { + this.clients = clients; + } + + public String getAuthorizers() { + return authorizers; + } + + public void setAuthorizers(final String authorizers) { + this.authorizers = authorizers; + } + + public String getMatchers() { + return matchers; + } + + public void setMatchers(final String matchers) { + this.matchers = matchers; + } + + public Boolean getMultiProfile() { + return multiProfile; + } + + public void setMultiProfile(final Boolean multiProfile) { + this.multiProfile = multiProfile; + } + + public Config getConfig() { + return config; + } + + public void setConfig(final Config config) { + this.config = config; + } + + public HttpActionAdapter getHttpActionAdapter() { + return httpActionAdapter; + } + + public void setHttpActionAdapter(final HttpActionAdapter httpActionAdapter) { + this.httpActionAdapter = httpActionAdapter; + } +} diff --git a/dinky-common/src/main/java/org/dinky/data/enums/Status.java b/dinky-common/src/main/java/org/dinky/data/enums/Status.java index 8616a5c292..13cf94bc53 100644 --- a/dinky-common/src/main/java/org/dinky/data/enums/Status.java +++ b/dinky-common/src/main/java/org/dinky/data/enums/Status.java @@ -251,6 +251,11 @@ public enum Status { DS_TASK_TYPE_NOT_SUPPORT(17008, "ds.task.type.not.support"), DS_WORK_FLOW_DEFINITION_NOT_EXIST(17009, "ds.work.flow.definition.not.exist"), DS_PROCESS_DEFINITION_UPDATE(17010, "ds.work.flow.definition.process.update"), + /** + * SSO About * + */ + USER_TYPE_ERROR(22001, "sso.user.type.error"), + NOT_MATCHED_PRINCIPAL_NAME_ATTRIBUTE(22002,"sso.user.type.error" ), /** * LDAP About * @@ -440,8 +445,8 @@ public enum Status { PROCESS_SUBMIT_BUILDCONFIG(193, "process.submit.buildConfig"), PROCESS_SUBMIT_EXECUTECOMMSQL(194, "process.submit.execute.commSql"), PROCESS_SUBMIT_EXECUTEFLINKSQL(195, "process.submit.execute.flinkSql"), - PROCESS_REGISTER_EXITS(196, "process.register.exits"), - ; + PROCESS_REGISTER_EXITS(196, "process.register.exits"); + private final int code; private final String key; diff --git a/dinky-common/src/main/java/org/dinky/data/enums/UserType.java b/dinky-common/src/main/java/org/dinky/data/enums/UserType.java index 68241c259c..865aeae52b 100644 --- a/dinky-common/src/main/java/org/dinky/data/enums/UserType.java +++ b/dinky-common/src/main/java/org/dinky/data/enums/UserType.java @@ -21,7 +21,8 @@ public enum UserType { LDAP(1, "LDAP"), - LOCAL(0, "LOCAL"); + LOCAL(0, "LOCAL"), + SSO(2, "LOCAL"); private final int code; private final String type; From ddc20d7142b5626d820052e15038790dc758285c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B3=BD=E7=BF=B0?= <627617031@qq.com> Date: Tue, 9 Apr 2024 16:28:01 +0800 Subject: [PATCH 02/21] Add sso support for github oauth --- .../src/main/java/org/dinky/configure/AppConfig.java | 9 +++++++-- .../main/java/org/dinky/controller/SsoCpntroller.java | 7 +++++-- .../src/main/java/org/dinky/data/enums/Status.java | 1 + 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java index 313a0e582a..1b018c4268 100644 --- a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java +++ b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java @@ -31,6 +31,7 @@ import org.pac4j.core.http.adapter.JEEHttpActionAdapter; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; @@ -51,7 +52,9 @@ @Configuration public class AppConfig implements WebMvcConfigurer { @Autowired - Config config; + private Config config; + @Value("${sso.enabled:false}") + private boolean ssoEnabled; /** * Cookie * @@ -94,7 +97,9 @@ public void addInterceptors(InterceptorRegistry registry) { })) .addPathPatterns("/api/**", "/openapi/**") .excludePathPatterns("/api/login", "/api/ldap/ldapEnableStatus", "/download/**", "/druid/**"); - registry.addInterceptor(buildInterceptor("GitHubClient")).addPathPatterns("/sso/*"); + if (ssoEnabled){ + registry.addInterceptor(buildInterceptor("GitHubClient")).addPathPatterns("/sso/*"); + } registry.addInterceptor(new TenantInterceptor()) .addPathPatterns("/api/**") .excludePathPatterns("/api/login", "/api/ldap/ldapEnableStatus") diff --git a/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java b/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java index 4a56db8497..d07a53a8f5 100644 --- a/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java +++ b/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java @@ -31,6 +31,8 @@ @NoArgsConstructor @ConfigurationProperties(prefix = "pac4j") public class SsoCpntroller { + @Value("${sso.enabled:false}") + private Boolean ssoEnabled; @@ -65,8 +67,9 @@ protected void afterPropertiesSet() { @GetMapping ("/sso/token") public Result token() throws AuthException { - - System.out.println(config); + if (!ssoEnabled){ + return Result.failed(Status.SINGLE_LOGIN_DISABLED); + } List all = profileManager.getAll(true); String username = all.get(0).getAttribute(principalNameAttribute).toString(); if (username == null){ diff --git a/dinky-common/src/main/java/org/dinky/data/enums/Status.java b/dinky-common/src/main/java/org/dinky/data/enums/Status.java index 13cf94bc53..d3cbfa91a0 100644 --- a/dinky-common/src/main/java/org/dinky/data/enums/Status.java +++ b/dinky-common/src/main/java/org/dinky/data/enums/Status.java @@ -256,6 +256,7 @@ public enum Status { */ USER_TYPE_ERROR(22001, "sso.user.type.error"), NOT_MATCHED_PRINCIPAL_NAME_ATTRIBUTE(22002,"sso.user.type.error" ), + SINGLE_LOGIN_DISABLED(22003, "sso.not.enabled"), /** * LDAP About * From e5bbc742c0dda679a65a75c3112d3064bded4b74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B3=BD=E7=BF=B0?= <627617031@qq.com> Date: Tue, 9 Apr 2024 16:36:35 +0800 Subject: [PATCH 03/21] Add sso support for github oauth --- .../src/main/resources/application.yml | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/dinky-admin/src/main/resources/application.yml b/dinky-admin/src/main/resources/application.yml index 1d1488222a..d97c22e383 100644 --- a/dinky-admin/src/main/resources/application.yml +++ b/dinky-admin/src/main/resources/application.yml @@ -142,3 +142,30 @@ knife4j: crypto: enabled: false encryption-password: + +################################################################################################################# +################################################# SSO Config #################################################### +################################################################################################################# +#see https://github.com/pac4j/spring-webmvc-pac4j-boot-demo/blob/master/src/main/resources/application.properties +sso: + enabled: false #enable sso + logout: + destroySession: true + defaultUrl: /?defaulturlafterlogout + centralLogout: + defaultUrl: http://localhost:8888/?defaulturlafterlogoutafteridp + logoutUrlPattern: http://localhost:8888/.* + +################################################################################################################# +################################################# pac4j Config #################################################### +################################################################################################################# +pac4j: + callbackUrl: http://localhost:8888/callback # The callback URL + # Put all parameters under `properties` + # Check supported sso config parameters for different authentication clients from the below link + # https://github.com/pac4j/pac4j/blob/master/documentation/docs/config-module.md + properties: + principalNameAttribute: login #Authenticate user principal + github.id: #Authentication client id + github.secret: #Authentication client secret + From 2b842850e5e0c859fa22295e6467a20fa015d131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B3=BD=E7=BF=B0?= <627617031@qq.com> Date: Tue, 9 Apr 2024 17:00:24 +0800 Subject: [PATCH 04/21] mvn -T 4C spotless:apply --- dinky-admin/pom.xml | 4 +- .../java/org/dinky/configure/AppConfig.java | 10 ++-- .../org/dinky/controller/SsoCpntroller.java | 48 +++++++++++++----- .../java/org/dinky/data/dto/LoginDTO.java | 9 ++-- .../dinky/service/impl/UserServiceImpl.java | 5 +- .../sso/annotation/AnnotationConfig.java | 21 +++++++- .../dinky/sso/annotation/CommonAspect.java | 23 ++++++++- .../sso/annotation/ui/RequireAllRoles.java | 19 +++++++ .../sso/annotation/ui/RequireAnyRole.java | 19 +++++++ .../sso/annotation/ui/UIAnnotationAspect.java | 22 +++++++- .../sso/annotation/ws/RequireAllRoles.java | 19 +++++++ .../sso/annotation/ws/RequireAnyRole.java | 19 +++++++ .../sso/annotation/ws/WSAnnotationAspect.java | 22 +++++++- .../dinky/sso/component/ComponentConfig.java | 25 ++++++++-- .../org/dinky/sso/web/CallbackController.java | 45 ++++++++++++++--- .../org/dinky/sso/web/LogoutController.java | 45 +++++++++++++---- .../dinky/sso/web/SecurityInterceptor.java | 50 +++++++++++++++---- .../src/main/resources/application-mysql.yml | 6 +-- .../src/main/resources/application.yml | 8 +-- .../java/org/dinky/data/enums/Status.java | 2 +- 20 files changed, 351 insertions(+), 70 deletions(-) diff --git a/dinky-admin/pom.xml b/dinky-admin/pom.xml index 3826d9a64d..d507a0d6bb 100644 --- a/dinky-admin/pom.xml +++ b/dinky-admin/pom.xml @@ -32,9 +32,9 @@ provided - 42.5.1 4.2.0 + 42.5.1 @@ -61,8 +61,6 @@
- - org.mitre.dsmiley.httpproxy smiley-http-proxy-servlet diff --git a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java index 1b018c4268..aad88ac830 100644 --- a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java +++ b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java @@ -22,14 +22,12 @@ import org.dinky.data.constant.BaseConstant; import org.dinky.interceptor.LocaleChangeInterceptor; import org.dinky.interceptor.TenantInterceptor; +import org.dinky.sso.web.SecurityInterceptor; import java.util.Locale; -import org.dinky.sso.web.SecurityInterceptor; import org.pac4j.core.config.Config; - import org.pac4j.core.http.adapter.JEEHttpActionAdapter; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; @@ -39,7 +37,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.i18n.CookieLocaleResolver; - import cn.dev33.satoken.exception.StopMatchException; +import cn.dev33.satoken.exception.StopMatchException; import cn.dev33.satoken.interceptor.SaInterceptor; import cn.dev33.satoken.router.SaRouter; import cn.dev33.satoken.stp.StpUtil; @@ -53,6 +51,7 @@ public class AppConfig implements WebMvcConfigurer { @Autowired private Config config; + @Value("${sso.enabled:false}") private boolean ssoEnabled; /** @@ -97,7 +96,7 @@ public void addInterceptors(InterceptorRegistry registry) { })) .addPathPatterns("/api/**", "/openapi/**") .excludePathPatterns("/api/login", "/api/ldap/ldapEnableStatus", "/download/**", "/druid/**"); - if (ssoEnabled){ + if (ssoEnabled) { registry.addInterceptor(buildInterceptor("GitHubClient")).addPathPatterns("/sso/*"); } registry.addInterceptor(new TenantInterceptor()) @@ -122,6 +121,7 @@ public void addInterceptors(InterceptorRegistry registry) { .addPathPatterns("/api/git/**") .addPathPatterns("/api/jar/*"); } + private SecurityInterceptor buildInterceptor(final String client) { return new SecurityInterceptor(config, client, JEEHttpActionAdapter.INSTANCE); } diff --git a/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java b/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java index d07a53a8f5..bbd15714e9 100644 --- a/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java +++ b/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java @@ -1,6 +1,24 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + package org.dinky.controller; -import lombok.NoArgsConstructor; import org.dinky.data.dto.LoginDTO; import org.dinky.data.dto.UserDTO; import org.dinky.data.enums.Status; @@ -8,9 +26,12 @@ import org.dinky.data.result.Result; import org.dinky.service.UserService; import org.dinky.sso.web.LogoutController; -import org.pac4j.core.config.Config; +import java.util.List; +import javax.annotation.PostConstruct; + +import org.pac4j.core.config.Config; import org.pac4j.core.context.JEEContext; import org.pac4j.core.profile.CommonProfile; import org.pac4j.core.profile.ProfileManager; @@ -20,9 +41,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; -import javax.annotation.PostConstruct; -import java.util.List; - +import lombok.NoArgsConstructor; /** * @author 杨泽翰 @@ -34,21 +53,24 @@ public class SsoCpntroller { @Value("${sso.enabled:false}") private Boolean ssoEnabled; - - @Value("${sso.centralLogout.defaultUrl:#{null}}") private String defaultUrl; @Value("${sso.centralLogout.logoutUrlPattern:#{null}}") private String logoutUrlPattern; + @Value("${pac4j.properties.principalNameAttribute:#{null}}") private String principalNameAttribute; + @Autowired private Config config; + @Autowired private JEEContext webContext; + @Autowired private ProfileManager profileManager; + private LogoutController logoutController; @Autowired @@ -65,24 +87,24 @@ protected void afterPropertiesSet() { logoutController.setDestroySession(true); } - @GetMapping ("/sso/token") + @GetMapping("/sso/token") public Result token() throws AuthException { - if (!ssoEnabled){ + if (!ssoEnabled) { return Result.failed(Status.SINGLE_LOGIN_DISABLED); } List all = profileManager.getAll(true); String username = all.get(0).getAttribute(principalNameAttribute).toString(); - if (username == null){ + if (username == null) { throw new AuthException(Status.NOT_MATCHED_PRINCIPAL_NAME_ATTRIBUTE); } LoginDTO loginDTO = new LoginDTO(); loginDTO.setUsername(username); loginDTO.setSsoLogin(true); - return userService.loginUser(loginDTO); + return userService.loginUser(loginDTO); } - @GetMapping ("/sso/logout") + + @GetMapping("/sso/logout") public void logout() { logoutController.logout(webContext.getNativeRequest(), webContext.getNativeResponse()); } - } diff --git a/dinky-admin/src/main/java/org/dinky/data/dto/LoginDTO.java b/dinky-admin/src/main/java/org/dinky/data/dto/LoginDTO.java index b73820f117..2470bb1ca9 100644 --- a/dinky-admin/src/main/java/org/dinky/data/dto/LoginDTO.java +++ b/dinky-admin/src/main/java/org/dinky/data/dto/LoginDTO.java @@ -19,11 +19,12 @@ package org.dinky.data.dto; +import org.dinky.data.enums.UserType; + import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; -import org.dinky.data.enums.UserType; /** * LoginUTO @@ -49,14 +50,12 @@ public class LoginDTO { @ApiModelProperty(value = "ldapLogin", required = true, example = "false", dataType = "Boolean") private boolean ldapLogin; + @ApiModelProperty(value = "ssoLogin", required = true, example = "false", dataType = "Boolean") private boolean ssoLogin; - public UserType getLoginType() { - - return isLdapLogin()? UserType.LDAP:UserType.SSO; - + return isLdapLogin() ? UserType.LDAP : UserType.SSO; } } diff --git a/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java b/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java index 06a61d78d5..46dc3e416c 100644 --- a/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java +++ b/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java @@ -180,7 +180,7 @@ public Result loginUser(LoginDTO loginDTO) { try { - switch (loginDTO.getLoginType()){ + switch (loginDTO.getLoginType()) { case LDAP: user = ldapLogin(loginDTO); break; @@ -242,8 +242,7 @@ private User ssoLogin(LoginDTO loginDTO) throws AuthException { userIds.add(userForm.getId()); tenantService.assignUserToTenant(new AssignUserToTenantDTO(tenant.getId(), userIds)); return userForm; - } - else{ + } else { if (user.getUserType() != UserType.SSO.getCode()) { throw new AuthException(Status.USER_TYPE_ERROR); } diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/AnnotationConfig.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/AnnotationConfig.java index 7920246080..ec4d2dafdf 100644 --- a/dinky-admin/src/main/java/org/dinky/sso/annotation/AnnotationConfig.java +++ b/dinky-admin/src/main/java/org/dinky/sso/annotation/AnnotationConfig.java @@ -1,8 +1,27 @@ -package org.dinky.sso.annotation; +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.dinky.sso.annotation; import org.dinky.sso.annotation.ui.UIAnnotationAspect; import org.dinky.sso.annotation.ws.WSAnnotationAspect; + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/CommonAspect.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/CommonAspect.java index 5ce7a47d0b..9a2021a937 100644 --- a/dinky-admin/src/main/java/org/dinky/sso/annotation/CommonAspect.java +++ b/dinky-admin/src/main/java/org/dinky/sso/annotation/CommonAspect.java @@ -1,5 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + package org.dinky.sso.annotation; +import java.util.List; + import org.pac4j.core.authorization.authorizer.IsAuthenticatedAuthorizer; import org.pac4j.core.authorization.authorizer.RequireAllRolesAuthorizer; import org.pac4j.core.authorization.authorizer.RequireAnyRoleAuthorizer; @@ -11,8 +32,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.util.List; - /** * Common aspect behaviors. * diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAllRoles.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAllRoles.java index e91e688ae9..66c0104cb8 100644 --- a/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAllRoles.java +++ b/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAllRoles.java @@ -1,3 +1,22 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + package org.dinky.sso.annotation.ui; import java.lang.annotation.ElementType; diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAnyRole.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAnyRole.java index 2103bcc133..9eb0119a22 100644 --- a/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAnyRole.java +++ b/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAnyRole.java @@ -1,3 +1,22 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + package org.dinky.sso.annotation.ui; import java.lang.annotation.ElementType; diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/UIAnnotationAspect.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/UIAnnotationAspect.java index 2024f06d3d..6278ea60be 100644 --- a/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/UIAnnotationAspect.java +++ b/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/UIAnnotationAspect.java @@ -1,8 +1,28 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + package org.dinky.sso.annotation.ui; +import org.dinky.sso.annotation.CommonAspect; + import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; -import org.dinky.sso.annotation.CommonAspect; /** * The aspect to define the web applications annotations. diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAllRoles.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAllRoles.java index 07ebfe693d..7b7c4c349b 100644 --- a/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAllRoles.java +++ b/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAllRoles.java @@ -1,3 +1,22 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + package org.dinky.sso.annotation.ws; import java.lang.annotation.ElementType; diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAnyRole.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAnyRole.java index f67b8ac320..2e2862714a 100644 --- a/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAnyRole.java +++ b/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAnyRole.java @@ -1,3 +1,22 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + package org.dinky.sso.annotation.ws; import java.lang.annotation.ElementType; diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/WSAnnotationAspect.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/WSAnnotationAspect.java index 27d3d51b0b..5112a82e8a 100644 --- a/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/WSAnnotationAspect.java +++ b/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/WSAnnotationAspect.java @@ -1,8 +1,28 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + package org.dinky.sso.annotation.ws; +import org.dinky.sso.annotation.CommonAspect; + import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; -import org.dinky.sso.annotation.CommonAspect; /** * The aspect to define the web services annotations. diff --git a/dinky-admin/src/main/java/org/dinky/sso/component/ComponentConfig.java b/dinky-admin/src/main/java/org/dinky/sso/component/ComponentConfig.java index b4b7a89a3d..2ce6477fe4 100644 --- a/dinky-admin/src/main/java/org/dinky/sso/component/ComponentConfig.java +++ b/dinky-admin/src/main/java/org/dinky/sso/component/ComponentConfig.java @@ -1,5 +1,27 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + package org.dinky.sso.component; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + import org.pac4j.core.config.Config; import org.pac4j.core.context.JEEContext; import org.pac4j.core.context.session.JEESessionStore; @@ -11,9 +33,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.web.context.annotation.RequestScope; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - /** * The configuration of the pac4j components. * diff --git a/dinky-admin/src/main/java/org/dinky/sso/web/CallbackController.java b/dinky-admin/src/main/java/org/dinky/sso/web/CallbackController.java index 40c134e4bd..2e15d3d813 100644 --- a/dinky-admin/src/main/java/org/dinky/sso/web/CallbackController.java +++ b/dinky-admin/src/main/java/org/dinky/sso/web/CallbackController.java @@ -1,5 +1,27 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + package org.dinky.sso.web; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + import org.pac4j.core.config.Config; import org.pac4j.core.context.JEEContext; import org.pac4j.core.context.JEEContextFactory; @@ -16,9 +38,6 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - /** *

This controller finishes the login process for an indirect client.

* @@ -52,17 +71,27 @@ public class CallbackController { public void callback(final HttpServletRequest request, final HttpServletResponse response) { final SessionStore bestSessionStore = FindBest.sessionStore(null, config, JEESessionStore.INSTANCE); - final HttpActionAdapter bestAdapter = FindBest.httpActionAdapter(null, config, JEEHttpActionAdapter.INSTANCE); - final CallbackLogic bestLogic = FindBest.callbackLogic(callbackLogic, config, DefaultCallbackLogic.INSTANCE); + final HttpActionAdapter bestAdapter = + FindBest.httpActionAdapter(null, config, JEEHttpActionAdapter.INSTANCE); + final CallbackLogic bestLogic = + FindBest.callbackLogic(callbackLogic, config, DefaultCallbackLogic.INSTANCE); final JEEContext context = (JEEContext) FindBest.webContextFactory(null, config, JEEContextFactory.INSTANCE) .newContext(request, response, bestSessionStore); - bestLogic.perform(context, config, bestAdapter, this.defaultUrl, this.saveInSession, this.multiProfile, - this.renewSession, this.defaultClient); + bestLogic.perform( + context, + config, + bestAdapter, + this.defaultUrl, + this.saveInSession, + this.multiProfile, + this.renewSession, + this.defaultClient); } @RequestMapping("${pac4j.callback.path/{cn}:/callback/{cn}}") - public void callbackWithClientName(final HttpServletRequest request, final HttpServletResponse response, @PathVariable("cn") final String cn) { + public void callbackWithClientName( + final HttpServletRequest request, final HttpServletResponse response, @PathVariable("cn") final String cn) { callback(request, response); } diff --git a/dinky-admin/src/main/java/org/dinky/sso/web/LogoutController.java b/dinky-admin/src/main/java/org/dinky/sso/web/LogoutController.java index 09f0aa0a17..93e69b7ca8 100644 --- a/dinky-admin/src/main/java/org/dinky/sso/web/LogoutController.java +++ b/dinky-admin/src/main/java/org/dinky/sso/web/LogoutController.java @@ -1,6 +1,27 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + package org.dinky.sso.web; -import lombok.Data; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + import org.pac4j.core.config.Config; import org.pac4j.core.context.JEEContext; import org.pac4j.core.context.JEEContextFactory; @@ -16,8 +37,7 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import lombok.Data; /** *

This controller handles the (application + identity provider) logout process.

@@ -53,14 +73,21 @@ public class LogoutController { public void logout(final HttpServletRequest request, final HttpServletResponse response) { final SessionStore bestSessionStore = FindBest.sessionStore(null, config, JEESessionStore.INSTANCE); - final HttpActionAdapter bestAdapter = FindBest.httpActionAdapter(null, config, JEEHttpActionAdapter.INSTANCE); - final LogoutLogic bestLogic = FindBest.logoutLogic(logoutLogic, config, DefaultLogoutLogic.INSTANCE); + final HttpActionAdapter bestAdapter = + FindBest.httpActionAdapter(null, config, JEEHttpActionAdapter.INSTANCE); + final LogoutLogic bestLogic = + FindBest.logoutLogic(logoutLogic, config, DefaultLogoutLogic.INSTANCE); final JEEContext context = (JEEContext) FindBest.webContextFactory(null, config, JEEContextFactory.INSTANCE) .newContext(request, response, bestSessionStore); - bestLogic.perform(context, config, bestAdapter, this.defaultUrl, this.logoutUrlPattern, - this.localLogout, this.destroySession, this.centralLogout); + bestLogic.perform( + context, + config, + bestAdapter, + this.defaultUrl, + this.logoutUrlPattern, + this.localLogout, + this.destroySession, + this.centralLogout); } - - } diff --git a/dinky-admin/src/main/java/org/dinky/sso/web/SecurityInterceptor.java b/dinky-admin/src/main/java/org/dinky/sso/web/SecurityInterceptor.java index 933c96d8ab..5ca6cdbd3a 100644 --- a/dinky-admin/src/main/java/org/dinky/sso/web/SecurityInterceptor.java +++ b/dinky-admin/src/main/java/org/dinky/sso/web/SecurityInterceptor.java @@ -1,5 +1,29 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + package org.dinky.sso.web; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + import org.pac4j.core.authorization.authorizer.Authorizer; import org.pac4j.core.config.Config; import org.pac4j.core.context.JEEContext; @@ -14,10 +38,6 @@ import org.pac4j.core.util.FindBest; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.concurrent.atomic.AtomicInteger; - /** *

This interceptor protects an url.

* @@ -67,12 +87,14 @@ public SecurityInterceptor(final Config config, final String clients, final Auth this.authorizers = addAuthorizers(config, authorizers); } - public SecurityInterceptor(final Config config, final String clients, final String authorizers, final String matchers) { + public SecurityInterceptor( + final Config config, final String clients, final String authorizers, final String matchers) { this(config, clients, authorizers); this.matchers = matchers; } - public SecurityInterceptor(final Config config, final String clients, final Authorizer[] authorizers, final Matcher[] matchers) { + public SecurityInterceptor( + final Config config, final String clients, final Authorizer[] authorizers, final Matcher[] matchers) { this(config, clients, addAuthorizers(config, authorizers)); this.matchers = addMatchers(config, matchers); } @@ -111,12 +133,22 @@ private static String addMatchers(final Config config, final Matcher[] matchers) public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { final SessionStore bestSessionStore = FindBest.sessionStore(null, config, JEESessionStore.INSTANCE); - final HttpActionAdapter bestAdapter = FindBest.httpActionAdapter(httpActionAdapter, config, JEEHttpActionAdapter.INSTANCE); - final SecurityLogic bestLogic = FindBest.securityLogic(securityLogic, config, DefaultSecurityLogic.INSTANCE); + final HttpActionAdapter bestAdapter = + FindBest.httpActionAdapter(httpActionAdapter, config, JEEHttpActionAdapter.INSTANCE); + final SecurityLogic bestLogic = + FindBest.securityLogic(securityLogic, config, DefaultSecurityLogic.INSTANCE); final JEEContext context = (JEEContext) FindBest.webContextFactory(null, config, JEEContextFactory.INSTANCE) .newContext(request, response, bestSessionStore); - final Object result = bestLogic.perform(context, config, (ctx, profiles, parameters) -> true, bestAdapter, clients, authorizers, matchers, multiProfile); + final Object result = bestLogic.perform( + context, + config, + (ctx, profiles, parameters) -> true, + bestAdapter, + clients, + authorizers, + matchers, + multiProfile); if (result == null) { return false; } diff --git a/dinky-admin/src/main/resources/application-mysql.yml b/dinky-admin/src/main/resources/application-mysql.yml index 6c71564216..ff7894eba4 100644 --- a/dinky-admin/src/main/resources/application-mysql.yml +++ b/dinky-admin/src/main/resources/application-mysql.yml @@ -17,7 +17,7 @@ spring: datasource: - url: jdbc:mysql://${MYSQL_ADDR:127.0.0.1:3306}/${MYSQL_DATABASE:dinky}?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true - username: ${MYSQL_USERNAME:dinky} - password: ${MYSQL_PASSWORD:dinky} + url: jdbc:mysql://${MYSQL_ADDR:127.0.0.1:3306}/${MYSQL_DATABASE:dinky2}?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true + username: ${MYSQL_USERNAME:root} + password: ${MYSQL_PASSWORD:yang19980712} driver-class-name: com.mysql.cj.jdbc.Driver diff --git a/dinky-admin/src/main/resources/application.yml b/dinky-admin/src/main/resources/application.yml index d97c22e383..534c059b8e 100644 --- a/dinky-admin/src/main/resources/application.yml +++ b/dinky-admin/src/main/resources/application.yml @@ -148,7 +148,7 @@ crypto: ################################################################################################################# #see https://github.com/pac4j/spring-webmvc-pac4j-boot-demo/blob/master/src/main/resources/application.properties sso: - enabled: false #enable sso + enabled: true #enable sso logout: destroySession: true defaultUrl: /?defaulturlafterlogout @@ -166,6 +166,8 @@ pac4j: # https://github.com/pac4j/pac4j/blob/master/documentation/docs/config-module.md properties: principalNameAttribute: login #Authenticate user principal - github.id: #Authentication client id - github.secret: #Authentication client secret + github.id: 66cf7e8845a0ab15c8af + github.secret: a9ab402d124eeb9f994bf0a4bfa26527317eada7 + # Optional, change by authentication client + # Please replace and fill in your client config below when enabled SSO diff --git a/dinky-common/src/main/java/org/dinky/data/enums/Status.java b/dinky-common/src/main/java/org/dinky/data/enums/Status.java index d3cbfa91a0..b35ce1caa2 100644 --- a/dinky-common/src/main/java/org/dinky/data/enums/Status.java +++ b/dinky-common/src/main/java/org/dinky/data/enums/Status.java @@ -255,7 +255,7 @@ public enum Status { * SSO About * */ USER_TYPE_ERROR(22001, "sso.user.type.error"), - NOT_MATCHED_PRINCIPAL_NAME_ATTRIBUTE(22002,"sso.user.type.error" ), + NOT_MATCHED_PRINCIPAL_NAME_ATTRIBUTE(22002, "sso.user.type.error"), SINGLE_LOGIN_DISABLED(22003, "sso.not.enabled"), /** From db9cbb7def09b77c685fe68cfe66d40ba093394e Mon Sep 17 00:00:00 2001 From: yangzehan <627617031@qq.com> Date: Tue, 9 Apr 2024 20:48:48 +0800 Subject: [PATCH 05/21] Delete redundant files, fix the SSO client, specify the client name, and get it from the configuration instead --- dinky-admin/src/main/java/org/dinky/configure/AppConfig.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java index aad88ac830..5cf5cf2c92 100644 --- a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java +++ b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java @@ -19,6 +19,7 @@ package org.dinky.configure; +import lombok.extern.slf4j.Slf4j; import org.dinky.data.constant.BaseConstant; import org.dinky.interceptor.LocaleChangeInterceptor; import org.dinky.interceptor.TenantInterceptor; @@ -48,6 +49,7 @@ * @since 2021/11/28 19:35 */ @Configuration +@Slf4j public class AppConfig implements WebMvcConfigurer { @Autowired private Config config; @@ -97,7 +99,8 @@ public void addInterceptors(InterceptorRegistry registry) { .addPathPatterns("/api/**", "/openapi/**") .excludePathPatterns("/api/login", "/api/ldap/ldapEnableStatus", "/download/**", "/druid/**"); if (ssoEnabled) { - registry.addInterceptor(buildInterceptor("GitHubClient")).addPathPatterns("/sso/*"); + log.info("Load{}",config.getClients().getClients().get(0).getName()); + registry.addInterceptor(buildInterceptor(config.getClients().getClients().get(0).getName())).addPathPatterns("/sso/*"); } registry.addInterceptor(new TenantInterceptor()) .addPathPatterns("/api/**") From 43e685dff9a9a6112d5355084ae42332cb562613 Mon Sep 17 00:00:00 2001 From: yangzehan <627617031@qq.com> Date: Tue, 9 Apr 2024 20:52:29 +0800 Subject: [PATCH 06/21] =?UTF-8?q?mvn=20spotless=EF=BC=9Aapply?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/org/dinky/configure/AppConfig.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java index 5cf5cf2c92..a007aae58d 100644 --- a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java +++ b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java @@ -19,7 +19,6 @@ package org.dinky.configure; -import lombok.extern.slf4j.Slf4j; import org.dinky.data.constant.BaseConstant; import org.dinky.interceptor.LocaleChangeInterceptor; import org.dinky.interceptor.TenantInterceptor; @@ -42,6 +41,7 @@ import cn.dev33.satoken.interceptor.SaInterceptor; import cn.dev33.satoken.router.SaRouter; import cn.dev33.satoken.stp.StpUtil; +import lombok.extern.slf4j.Slf4j; /** * AppConfiguration @@ -99,8 +99,10 @@ public void addInterceptors(InterceptorRegistry registry) { .addPathPatterns("/api/**", "/openapi/**") .excludePathPatterns("/api/login", "/api/ldap/ldapEnableStatus", "/download/**", "/druid/**"); if (ssoEnabled) { - log.info("Load{}",config.getClients().getClients().get(0).getName()); - registry.addInterceptor(buildInterceptor(config.getClients().getClients().get(0).getName())).addPathPatterns("/sso/*"); + log.info("Load{}", config.getClients().getClients().get(0).getName()); + registry.addInterceptor(buildInterceptor( + config.getClients().getClients().get(0).getName())) + .addPathPatterns("/sso/*"); } registry.addInterceptor(new TenantInterceptor()) .addPathPatterns("/api/**") From 59a1cef88062f7fa1ea350da3893f3b9de6acf66 Mon Sep 17 00:00:00 2001 From: yangzehan <627617031@qq.com> Date: Tue, 9 Apr 2024 20:56:54 +0800 Subject: [PATCH 07/21] rollback --- dinky-admin/src/main/resources/application-mysql.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dinky-admin/src/main/resources/application-mysql.yml b/dinky-admin/src/main/resources/application-mysql.yml index ff7894eba4..d0ac8fda40 100644 --- a/dinky-admin/src/main/resources/application-mysql.yml +++ b/dinky-admin/src/main/resources/application-mysql.yml @@ -17,7 +17,7 @@ spring: datasource: - url: jdbc:mysql://${MYSQL_ADDR:127.0.0.1:3306}/${MYSQL_DATABASE:dinky2}?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true - username: ${MYSQL_USERNAME:root} - password: ${MYSQL_PASSWORD:yang19980712} - driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://${MYSQL_ADDR:127.0.0.1:3306}/${MYSQL_DATABASE:dinky}?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true + username: ${MYSQL_USERNAME:dinky} + password: ${MYSQL_PASSWORD:dinky} + driver-class-name: com.mysql.cj.jdbc.Driver \ No newline at end of file From 4aeb724dcd2ba646a6f2a29f95568363a364ca27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B3=BD=E7=BF=B0?= <627617031@qq.com> Date: Wed, 10 Apr 2024 09:28:38 +0800 Subject: [PATCH 08/21] Remove basic connection information --- dinky-admin/src/main/resources/application.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dinky-admin/src/main/resources/application.yml b/dinky-admin/src/main/resources/application.yml index 534c059b8e..13ae83cd35 100644 --- a/dinky-admin/src/main/resources/application.yml +++ b/dinky-admin/src/main/resources/application.yml @@ -166,8 +166,8 @@ pac4j: # https://github.com/pac4j/pac4j/blob/master/documentation/docs/config-module.md properties: principalNameAttribute: login #Authenticate user principal - github.id: 66cf7e8845a0ab15c8af - github.secret: a9ab402d124eeb9f994bf0a4bfa26527317eada7 + github.id: + github.secret: # Optional, change by authentication client # Please replace and fill in your client config below when enabled SSO From afc9277bc26c2967fc157cc39ca391150e1ea199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B3=BD=E7=BF=B0?= <627617031@qq.com> Date: Fri, 12 Apr 2024 11:01:16 +0800 Subject: [PATCH 09/21] Improve logic and add front-end code --- .../java/org/dinky/configure/AppConfig.java | 6 ++-- .../org/dinky/controller/SsoCpntroller.java | 30 +++++++++++++++--- .../java/org/dinky/data/dto/LoginDTO.java | 8 ++++- .../org/dinky/sso/web/CallbackController.java | 2 +- .../src/main/resources/application.yml | 3 +- dinky-web/src/locales/en-US/pages.ts | 1 + dinky-web/src/locales/zh-CN/pages.ts | 1 + .../src/pages/Other/Login/LoginForm/index.tsx | 19 ++++++++++-- dinky-web/src/pages/Other/Login/index.tsx | 31 ++++++++++++++++++- dinky-web/src/services/BusinessCrud.ts | 14 +++++++++ dinky-web/src/services/endpoints.tsx | 4 +++ 11 files changed, 105 insertions(+), 14 deletions(-) diff --git a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java index a007aae58d..3485ad0ef3 100644 --- a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java +++ b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java @@ -97,16 +97,16 @@ public void addInterceptors(InterceptorRegistry registry) { } })) .addPathPatterns("/api/**", "/openapi/**") - .excludePathPatterns("/api/login", "/api/ldap/ldapEnableStatus", "/download/**", "/druid/**"); + .excludePathPatterns("/api/sso/ssoEnableStatus","/api/login", "/api/ldap/ldapEnableStatus", "/download/**", "/druid/**"); if (ssoEnabled) { log.info("Load{}", config.getClients().getClients().get(0).getName()); registry.addInterceptor(buildInterceptor( config.getClients().getClients().get(0).getName())) - .addPathPatterns("/sso/*"); + .addPathPatterns("/api/sso/login").addPathPatterns("/api/sso/token"); } registry.addInterceptor(new TenantInterceptor()) .addPathPatterns("/api/**") - .excludePathPatterns("/api/login", "/api/ldap/ldapEnableStatus") + .excludePathPatterns("/api/sso/ssoEnableStatus","/api/login", "/api/ldap/ldapEnableStatus") .addPathPatterns("/api/alertGroup/**") .addPathPatterns("/api/alertHistory/**") .addPathPatterns("/api/alertInstance/**") diff --git a/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java b/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java index bbd15714e9..927c13e829 100644 --- a/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java +++ b/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java @@ -19,6 +19,8 @@ package org.dinky.controller; +import cn.dev33.satoken.annotation.SaIgnore; +import io.swagger.annotations.ApiOperation; import org.dinky.data.dto.LoginDTO; import org.dinky.data.dto.UserDTO; import org.dinky.data.enums.Status; @@ -39,17 +41,24 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import lombok.NoArgsConstructor; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.view.RedirectView; /** * @author 杨泽翰 */ @RestController @NoArgsConstructor +@RequestMapping("/api/sso") @ConfigurationProperties(prefix = "pac4j") public class SsoCpntroller { + @Value("${sso.baseUrl:localhost:8000}") + private String baseUrl; @Value("${sso.enabled:false}") private Boolean ssoEnabled; @@ -87,8 +96,8 @@ protected void afterPropertiesSet() { logoutController.setDestroySession(true); } - @GetMapping("/sso/token") - public Result token() throws AuthException { + @GetMapping("/token") + public Result ssoToken() throws AuthException { if (!ssoEnabled) { return Result.failed(Status.SINGLE_LOGIN_DISABLED); } @@ -103,8 +112,21 @@ public Result token() throws AuthException { return userService.loginUser(loginDTO); } - @GetMapping("/sso/logout") - public void logout() { + @GetMapping("/login") + public ModelAndView ssoLogin() { + RedirectView redirectView = new RedirectView("http://"+baseUrl+"/#/user/login?from=sso"); + return new ModelAndView(redirectView); + } + + @GetMapping("/logout") + public void ssoLogout() { logoutController.logout(webContext.getNativeRequest(), webContext.getNativeResponse()); } + + @GetMapping("/ssoEnableStatus") + @SaIgnore + @ApiOperation("Get SSO enable status") + public Result ssoStatus() { + return Result.succeed(ssoEnabled); + } } diff --git a/dinky-admin/src/main/java/org/dinky/data/dto/LoginDTO.java b/dinky-admin/src/main/java/org/dinky/data/dto/LoginDTO.java index 2470bb1ca9..5e5525b5d0 100644 --- a/dinky-admin/src/main/java/org/dinky/data/dto/LoginDTO.java +++ b/dinky-admin/src/main/java/org/dinky/data/dto/LoginDTO.java @@ -55,7 +55,13 @@ public class LoginDTO { private boolean ssoLogin; public UserType getLoginType() { + if (isLdapLogin()){ + return UserType.LDAP; + } + if (isSsoLogin()){ + return UserType.SSO; + } - return isLdapLogin() ? UserType.LDAP : UserType.SSO; + return UserType.LOCAL; } } diff --git a/dinky-admin/src/main/java/org/dinky/sso/web/CallbackController.java b/dinky-admin/src/main/java/org/dinky/sso/web/CallbackController.java index 2e15d3d813..9a8a6cf10f 100644 --- a/dinky-admin/src/main/java/org/dinky/sso/web/CallbackController.java +++ b/dinky-admin/src/main/java/org/dinky/sso/web/CallbackController.java @@ -49,7 +49,7 @@ public class CallbackController { private CallbackLogic callbackLogic; - @Value("${pac4j.callback.defaultUrl:#{null}}") + @Value("${pac4j.callback.defaultUrl:api/sso/login}") private String defaultUrl; @Value("${pac4j.callback.multiProfile:#{null}}") diff --git a/dinky-admin/src/main/resources/application.yml b/dinky-admin/src/main/resources/application.yml index 13ae83cd35..baa4243e57 100644 --- a/dinky-admin/src/main/resources/application.yml +++ b/dinky-admin/src/main/resources/application.yml @@ -16,7 +16,7 @@ spring: # If you use pgsql database, please configure pgsql database connection information in application-pgsql.yml # If you use the h2 database, please configure the h2 database connection information in application-h2.yml, # note: the h2 database is only for experience use, and the related data that has been created cannot be migrated, please use it with caution - active: ${DB_ACTIVE:h2} #[h2,mysql,pgsql] + active: ${DB_ACTIVE:mysql} #[h2,mysql,pgsql] include: jmx lifecycle: timeout-per-shutdown-phase: 30s @@ -155,6 +155,7 @@ sso: centralLogout: defaultUrl: http://localhost:8888/?defaulturlafterlogoutafteridp logoutUrlPattern: http://localhost:8888/.* + baseUrl: localhost:8000 ################################################################################################################# ################################################# pac4j Config #################################################### diff --git a/dinky-web/src/locales/en-US/pages.ts b/dinky-web/src/locales/en-US/pages.ts index 34cc0375b1..74b00fd07b 100644 --- a/dinky-web/src/locales/en-US/pages.ts +++ b/dinky-web/src/locales/en-US/pages.ts @@ -292,6 +292,7 @@ export default { 'login.chooseTenantFailed': 'Tenant selection failed, please check. . . ', 'login.chooseTenantSuccess': '{msg}, Use [ {tenantCode} ] to enter the system, loading. . .', 'login.ldapLogin': 'LDAP Login', + 'login.ssoLogin': 'SSO Login', 'login.notbindtenant': 'You have not bound a tenant, please contact the administrator', 'login.password.placeholder': 'Password', 'login.password.required': 'Please input your password!', diff --git a/dinky-web/src/locales/zh-CN/pages.ts b/dinky-web/src/locales/zh-CN/pages.ts index 07769d9f6f..9423832d26 100644 --- a/dinky-web/src/locales/zh-CN/pages.ts +++ b/dinky-web/src/locales/zh-CN/pages.ts @@ -280,6 +280,7 @@ export default { 'login.chooseTenantFailed': '租户选择失败,请检查...', 'login.chooseTenantSuccess': '{msg},使用【 {tenantCode} 】进入系统,加载中...', 'login.ldapLogin': 'LDAP登录', + 'login.ssoLogin': 'SSO 登录', 'login.notbindtenant': '您还没有绑定租户,请联系管理员', 'login.password.placeholder': '密码', 'login.password.required': '密码是必填项!', diff --git a/dinky-web/src/pages/Other/Login/LoginForm/index.tsx b/dinky-web/src/pages/Other/Login/LoginForm/index.tsx index 54b1dd887b..ec7e5792fd 100644 --- a/dinky-web/src/pages/Other/Login/LoginForm/index.tsx +++ b/dinky-web/src/pages/Other/Login/LoginForm/index.tsx @@ -40,8 +40,15 @@ const LoginForm: React.FC = (props) => { const [submitting, setSubmitting] = useState(false); const [ldapEnabled, setLdapEnabled] = useState(false); + const [ssoEnabled, setSsoEnabled] = useState(false); useEffect(() => { + getData(API_CONSTANTS.GET_SSO_ENABLE).then( + (res) => { + setSsoEnabled(res.data); + }, + (err) => console.error(err) + ); getData(API_CONSTANTS.GET_LDAP_ENABLE).then( (res) => { setLdapEnabled(res.data); @@ -95,9 +102,14 @@ const LoginForm: React.FC = (props) => { {l('login.rememberMe')} - + + + + @@ -135,3 +147,4 @@ const LoginForm: React.FC = (props) => { }; export default LoginForm; + diff --git a/dinky-web/src/pages/Other/Login/index.tsx b/dinky-web/src/pages/Other/Login/index.tsx index 1c32c35762..a5598861aa 100644 --- a/dinky-web/src/pages/Other/Login/index.tsx +++ b/dinky-web/src/pages/Other/Login/index.tsx @@ -21,7 +21,7 @@ import Footer from '@/components/Footer'; import ChooseModal from '@/pages/Other/Login/ChooseModal'; import { gotoRedirectUrl, initSomeThing, redirectToLogin } from '@/pages/Other/Login/function'; import LangSwitch from '@/pages/Other/Login/LangSwitch'; -import { chooseTenantSubmit, login, queryDataByParams } from '@/services/BusinessCrud'; +import {chooseTenantSubmit, login, queryDataByParams, ssoToken} from '@/services/BusinessCrud'; import { API } from '@/services/data'; import { API_CONSTANTS } from '@/services/endpoints'; import { SaTokenInfo, UserBaseInfo } from '@/types/AuthCenter/data.d'; @@ -34,6 +34,8 @@ import { useModel } from '@umijs/max'; import React, { useEffect, useState } from 'react'; import HelmetTitle from './HelmetTitle'; import LoginForm from './LoginForm'; +import {getData} from "@/services/api"; +import {createSearchParams} from "@@/exports"; const Login: React.FC = () => { const [submitting, setSubmitting] = useState(false); @@ -52,6 +54,33 @@ const Login: React.FC = () => { height: '100%' }; }); + useEffect(() => { + console.log(location.hash) + if (location.hash==("#/user/login?from=sso")){ + ssoToken().then( + res => { + if (res) { + setLocalStorageOfToken(JSON.stringify(res)); + } else { + // 如果没有获取到token信息,直接跳转到登录页 + redirectToLogin(); + } + setInitialState((s) => ({ ...s, currentUser: res.data })); + SuccessMessageAsync(l('login.result', '', { msg: res.msg, time: res.time })); + const tenantList: UserBaseInfo.Tenant[] = res.data.tenantList; + assertTenant(tenantList); + if (tenantList && tenantList.length > 1) { + + handleTenantVisible(true); + } else { + singleTenant(tenantList); + } + } + ) + } + + + }, []); const fetchUserInfo = async () => { const userInfo = await initialState?.fetchUserInfo?.(); diff --git a/dinky-web/src/services/BusinessCrud.ts b/dinky-web/src/services/BusinessCrud.ts index 0c7873773b..706f719988 100644 --- a/dinky-web/src/services/BusinessCrud.ts +++ b/dinky-web/src/services/BusinessCrud.ts @@ -63,6 +63,20 @@ export async function login(body: API.LoginParams, options?: { [key: string]: an ...(options ?? {}) }); } +/** + * user sso login + */ +export async function ssoToken() { + return request(API_CONSTANTS.SSO_TOKEN, { + method: METHOD_CONSTANTS.GET, + headers: { + CONTENT_TYPE: APPLICATION_JSON + } + }); +} + + + /** * choose tenant diff --git a/dinky-web/src/services/endpoints.tsx b/dinky-web/src/services/endpoints.tsx index b597be5dfe..2554f0bb36 100644 --- a/dinky-web/src/services/endpoints.tsx +++ b/dinky-web/src/services/endpoints.tsx @@ -226,6 +226,10 @@ export enum API_CONSTANTS { LDAP_LIST_USER = '/api/ldap/listUser', LDAP_IMPORT_USERS = '/api/ldap/importUsers', + // ----------------------------------------- sso ------------------------------------ + GET_SSO_ENABLE = '/api/sso/ssoEnableStatus', + SSO_TOKEN = '/api/sso/token', + SSO_LOGIN = '/api/sso/login', // ------------------------------------ home ------------------------------------ GET_RESOURCE_OVERVIEW = '/api/home/getResourceOverview', GET_JOB_STATUS_OVERVIEW = '/api/home/getJobStatusOverview', From e3d179d76eefc777f27f3d7aef30a4571a550e2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B3=BD=E7=BF=B0?= <627617031@qq.com> Date: Fri, 12 Apr 2024 11:33:01 +0800 Subject: [PATCH 10/21] mvn -T 4C spotless:apply --- .../main/java/org/dinky/configure/AppConfig.java | 12 +++++++++--- .../java/org/dinky/controller/SsoCpntroller.java | 14 +++++++------- .../src/main/java/org/dinky/data/dto/LoginDTO.java | 6 +++--- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java index 3485ad0ef3..2c60e77abb 100644 --- a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java +++ b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java @@ -97,16 +97,22 @@ public void addInterceptors(InterceptorRegistry registry) { } })) .addPathPatterns("/api/**", "/openapi/**") - .excludePathPatterns("/api/sso/ssoEnableStatus","/api/login", "/api/ldap/ldapEnableStatus", "/download/**", "/druid/**"); + .excludePathPatterns( + "/api/sso/ssoEnableStatus", + "/api/login", + "/api/ldap/ldapEnableStatus", + "/download/**", + "/druid/**"); if (ssoEnabled) { log.info("Load{}", config.getClients().getClients().get(0).getName()); registry.addInterceptor(buildInterceptor( config.getClients().getClients().get(0).getName())) - .addPathPatterns("/api/sso/login").addPathPatterns("/api/sso/token"); + .addPathPatterns("/api/sso/login") + .addPathPatterns("/api/sso/token"); } registry.addInterceptor(new TenantInterceptor()) .addPathPatterns("/api/**") - .excludePathPatterns("/api/sso/ssoEnableStatus","/api/login", "/api/ldap/ldapEnableStatus") + .excludePathPatterns("/api/sso/ssoEnableStatus", "/api/login", "/api/ldap/ldapEnableStatus") .addPathPatterns("/api/alertGroup/**") .addPathPatterns("/api/alertHistory/**") .addPathPatterns("/api/alertInstance/**") diff --git a/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java b/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java index 927c13e829..6aefaab7d5 100644 --- a/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java +++ b/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java @@ -19,8 +19,6 @@ package org.dinky.controller; -import cn.dev33.satoken.annotation.SaIgnore; -import io.swagger.annotations.ApiOperation; import org.dinky.data.dto.LoginDTO; import org.dinky.data.dto.UserDTO; import org.dinky.data.enums.Status; @@ -41,14 +39,15 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; - -import lombok.NoArgsConstructor; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.view.RedirectView; +import cn.dev33.satoken.annotation.SaIgnore; +import io.swagger.annotations.ApiOperation; +import lombok.NoArgsConstructor; + /** * @author 杨泽翰 */ @@ -59,6 +58,7 @@ public class SsoCpntroller { @Value("${sso.baseUrl:localhost:8000}") private String baseUrl; + @Value("${sso.enabled:false}") private Boolean ssoEnabled; @@ -113,8 +113,8 @@ public Result ssoToken() throws AuthException { } @GetMapping("/login") - public ModelAndView ssoLogin() { - RedirectView redirectView = new RedirectView("http://"+baseUrl+"/#/user/login?from=sso"); + public ModelAndView ssoLogin() { + RedirectView redirectView = new RedirectView("http://" + baseUrl + "/#/user/login?from=sso"); return new ModelAndView(redirectView); } diff --git a/dinky-admin/src/main/java/org/dinky/data/dto/LoginDTO.java b/dinky-admin/src/main/java/org/dinky/data/dto/LoginDTO.java index 5e5525b5d0..125214b2af 100644 --- a/dinky-admin/src/main/java/org/dinky/data/dto/LoginDTO.java +++ b/dinky-admin/src/main/java/org/dinky/data/dto/LoginDTO.java @@ -55,13 +55,13 @@ public class LoginDTO { private boolean ssoLogin; public UserType getLoginType() { - if (isLdapLogin()){ + if (isLdapLogin()) { return UserType.LDAP; } - if (isSsoLogin()){ + if (isSsoLogin()) { return UserType.SSO; } - return UserType.LOCAL; + return UserType.LOCAL; } } From 396a884b9abbe4aff70a77ca31b4ecbf4842f3f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B3=BD=E7=BF=B0?= <627617031@qq.com> Date: Wed, 17 Apr 2024 11:29:06 +0800 Subject: [PATCH 11/21] Add registration ID --- dinky-web/src/pages/AuthCenter/User/components/constants.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dinky-web/src/pages/AuthCenter/User/components/constants.tsx b/dinky-web/src/pages/AuthCenter/User/components/constants.tsx index 71580b4be5..fb99ec40e4 100644 --- a/dinky-web/src/pages/AuthCenter/User/components/constants.tsx +++ b/dinky-web/src/pages/AuthCenter/User/components/constants.tsx @@ -20,5 +20,5 @@ export const UserType = { LOCAL: 0, LDAP: 1 }; export const USER_TYPE_ENUM = () => { - return { 0: 'LOCAL', 1: 'LDAP' }; + return { 0: 'LOCAL', 1: 'LDAP',2:"SSO" }; }; From ee042a011371d2ccc214ab49009a1e47964e7983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B3=BD=E7=BF=B0?= <627617031@qq.com> Date: Thu, 18 Apr 2024 09:02:43 +0800 Subject: [PATCH 12/21] Fix user_type --- dinky-common/src/main/java/org/dinky/data/enums/UserType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dinky-common/src/main/java/org/dinky/data/enums/UserType.java b/dinky-common/src/main/java/org/dinky/data/enums/UserType.java index 865aeae52b..50b0b7350e 100644 --- a/dinky-common/src/main/java/org/dinky/data/enums/UserType.java +++ b/dinky-common/src/main/java/org/dinky/data/enums/UserType.java @@ -22,7 +22,7 @@ public enum UserType { LDAP(1, "LDAP"), LOCAL(0, "LOCAL"), - SSO(2, "LOCAL"); + SSO(2, "SSO"); private final int code; private final String type; From 697202586da97142117203d200b9741c449548bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B3=BD=E7=BF=B0?= <627617031@qq.com> Date: Tue, 23 Apr 2024 15:45:48 +0800 Subject: [PATCH 13/21] Add sso automatic assembly and Remove redundant sso dependencies --- dinky-admin/pom.xml | 39 +++++++++---------- .../Pac4jConfigAutoConfiguration.java | 31 +++++++++++++++ .../Pac4jConfigurationProperties.java | 30 ++++++++++++++ .../main/resources/META-INF/spring.factories | 3 +- .../src/main/resources/application.yml | 25 +++++++----- 5 files changed, 98 insertions(+), 30 deletions(-) create mode 100644 dinky-admin/src/main/java/org/dinky/configure/Pac4jConfigAutoConfiguration.java create mode 100644 dinky-admin/src/main/java/org/dinky/configure/propertie/Pac4jConfigurationProperties.java diff --git a/dinky-admin/pom.xml b/dinky-admin/pom.xml index d507a0d6bb..f2f49d2fcb 100644 --- a/dinky-admin/pom.xml +++ b/dinky-admin/pom.xml @@ -33,34 +33,33 @@ provided - 4.2.0 + 4.2.0 + 4.0.1 42.5.1 - - org.pac4j - pac4j-springboot - ${pac4jVersion} - - - org.apache.logging.log4j - log4j-to-slf4j - - - org.apache.logging.log4j - log4j-api - - - commons-collections - commons-collections - - + spring-webmvc-pac4j + ${spring-webmvc-pac4j.version} + + + org.pac4j + pac4j-config + ${pac4j.version} + + + org.pac4j + pac4j-oauth + ${pac4j.version} + + + org.pac4j + pac4j-http + ${pac4j.version} - org.mitre.dsmiley.httpproxy smiley-http-proxy-servlet diff --git a/dinky-admin/src/main/java/org/dinky/configure/Pac4jConfigAutoConfiguration.java b/dinky-admin/src/main/java/org/dinky/configure/Pac4jConfigAutoConfiguration.java new file mode 100644 index 0000000000..a729a064d9 --- /dev/null +++ b/dinky-admin/src/main/java/org/dinky/configure/Pac4jConfigAutoConfiguration.java @@ -0,0 +1,31 @@ +package org.dinky.configure; + +import org.dinky.configure.propertie.Pac4jConfigurationProperties; +import org.pac4j.config.client.PropertiesConfigFactory; +import org.pac4j.core.config.Config; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +/** + * The Pac4jConfigAutoConfiguration class for Spring. + * + * @author yangzehan + * + */ +@Configuration(value = "Pac4jConfigAutoConfiguration", proxyBeanMethods = false) +@EnableConfigurationProperties(org.dinky.configure.propertie.Pac4jConfigurationProperties.class) +public class Pac4jConfigAutoConfiguration { + + @Autowired + private Pac4jConfigurationProperties pac4j; + + @Bean + @ConditionalOnMissingBean + public Config config() { + final PropertiesConfigFactory factory = + new PropertiesConfigFactory(pac4j.getCallbackUrl(), pac4j.getProperties()); + return factory.build(); + } +} diff --git a/dinky-admin/src/main/java/org/dinky/configure/propertie/Pac4jConfigurationProperties.java b/dinky-admin/src/main/java/org/dinky/configure/propertie/Pac4jConfigurationProperties.java new file mode 100644 index 0000000000..c9cb477c44 --- /dev/null +++ b/dinky-admin/src/main/java/org/dinky/configure/propertie/Pac4jConfigurationProperties.java @@ -0,0 +1,30 @@ +package org.dinky.configure.propertie; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * The pac4j configuration and callback URL. + * + * @author yangzehan + * + */ +@ConfigurationProperties(prefix = "pac4j", ignoreUnknownFields = false) +@Getter +@Setter +public class Pac4jConfigurationProperties { + private Map properties = new LinkedHashMap<>(); + private Map callback = new LinkedHashMap<>(); + private Map centralLogout = new LinkedHashMap<>(); + private Map logout = new LinkedHashMap<>(); + private String callbackUrl; + +} + + + + diff --git a/dinky-admin/src/main/resources/META-INF/spring.factories b/dinky-admin/src/main/resources/META-INF/spring.factories index e756436fd6..88eaab22c8 100644 --- a/dinky-admin/src/main/resources/META-INF/spring.factories +++ b/dinky-admin/src/main/resources/META-INF/spring.factories @@ -1 +1,2 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.dinky.configure.Pac4jConfigAutoConfiguration + diff --git a/dinky-admin/src/main/resources/application.yml b/dinky-admin/src/main/resources/application.yml index baa4243e57..8e85beffdf 100644 --- a/dinky-admin/src/main/resources/application.yml +++ b/dinky-admin/src/main/resources/application.yml @@ -2,6 +2,9 @@ ################################################# Common Config ################################################# ################################################################################################################# # Dinky application port + + + server: port: 8888 shutdown: graceful @@ -16,7 +19,7 @@ spring: # If you use pgsql database, please configure pgsql database connection information in application-pgsql.yml # If you use the h2 database, please configure the h2 database connection information in application-h2.yml, # note: the h2 database is only for experience use, and the related data that has been created cannot be migrated, please use it with caution - active: ${DB_ACTIVE:mysql} #[h2,mysql,pgsql] + active: ${DB_ACTIVE:h2} #[h2,mysql,pgsql] include: jmx lifecycle: timeout-per-shutdown-phase: 30s @@ -149,19 +152,23 @@ crypto: #see https://github.com/pac4j/spring-webmvc-pac4j-boot-demo/blob/master/src/main/resources/application.properties sso: enabled: true #enable sso - logout: - destroySession: true - defaultUrl: /?defaulturlafterlogout - centralLogout: - defaultUrl: http://localhost:8888/?defaulturlafterlogoutafteridp - logoutUrlPattern: http://localhost:8888/.* - baseUrl: localhost:8000 + redirect: http://localhost:8000/#/user/login?from=sso #Front-end address ################################################################################################################# ################################################# pac4j Config #################################################### ################################################################################################################# pac4j: - callbackUrl: http://localhost:8888/callback # The callback URL + callback: + defaultUrl: ${sso.redirect} + logout: + defaultUrl: + destroySession: true + callback: + multiProfile: true + centralLogout: + defaultUrl: http://localhost:${server.port}/?defaulturlafterlogoutafteridp + logoutUrlPattern: http://localhost:${server.port}/.* + callbackUrl: http://localhost:${server.port}/callback # The callback URL # Put all parameters under `properties` # Check supported sso config parameters for different authentication clients from the below link # https://github.com/pac4j/pac4j/blob/master/documentation/docs/config-module.md From 01720f3aa787fffa115c478cb8df74b7dd0b2f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B3=BD=E7=BF=B0?= <627617031@qq.com> Date: Tue, 23 Apr 2024 15:47:24 +0800 Subject: [PATCH 14/21] Remove redundant code --- .../java/org/dinky/configure/AppConfig.java | 8 +- .../org/dinky/controller/SsoCpntroller.java | 17 +- .../sso/annotation/AnnotationConfig.java | 48 ---- .../dinky/sso/annotation/CommonAspect.java | 78 ------- .../sso/annotation/ui/RequireAllRoles.java | 38 ---- .../sso/annotation/ui/RequireAnyRole.java | 38 ---- .../sso/annotation/ui/UIAnnotationAspect.java | 45 ---- .../sso/annotation/ws/RequireAllRoles.java | 38 ---- .../sso/annotation/ws/RequireAnyRole.java | 38 ---- .../sso/annotation/ws/WSAnnotationAspect.java | 45 ---- .../dinky/sso/component/ComponentConfig.java | 72 ------ .../org/dinky/sso/web/CallbackController.java | 154 ------------- .../org/dinky/sso/web/LogoutController.java | 93 -------- .../dinky/sso/web/SecurityInterceptor.java | 213 ------------------ 14 files changed, 17 insertions(+), 908 deletions(-) delete mode 100644 dinky-admin/src/main/java/org/dinky/sso/annotation/AnnotationConfig.java delete mode 100644 dinky-admin/src/main/java/org/dinky/sso/annotation/CommonAspect.java delete mode 100644 dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAllRoles.java delete mode 100644 dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAnyRole.java delete mode 100644 dinky-admin/src/main/java/org/dinky/sso/annotation/ui/UIAnnotationAspect.java delete mode 100644 dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAllRoles.java delete mode 100644 dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAnyRole.java delete mode 100644 dinky-admin/src/main/java/org/dinky/sso/annotation/ws/WSAnnotationAspect.java delete mode 100644 dinky-admin/src/main/java/org/dinky/sso/component/ComponentConfig.java delete mode 100644 dinky-admin/src/main/java/org/dinky/sso/web/CallbackController.java delete mode 100644 dinky-admin/src/main/java/org/dinky/sso/web/LogoutController.java delete mode 100644 dinky-admin/src/main/java/org/dinky/sso/web/SecurityInterceptor.java diff --git a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java index 2c60e77abb..afa4af4550 100644 --- a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java +++ b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java @@ -22,16 +22,20 @@ import org.dinky.data.constant.BaseConstant; import org.dinky.interceptor.LocaleChangeInterceptor; import org.dinky.interceptor.TenantInterceptor; -import org.dinky.sso.web.SecurityInterceptor; import java.util.Locale; import org.pac4j.core.config.Config; import org.pac4j.core.http.adapter.JEEHttpActionAdapter; +import org.pac4j.springframework.annotation.AnnotationConfig; +import org.pac4j.springframework.component.ComponentConfig; +import org.pac4j.springframework.web.SecurityInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -50,6 +54,8 @@ */ @Configuration @Slf4j +@Import({ComponentConfig.class, AnnotationConfig.class}) +@ComponentScan(basePackages = "org.pac4j.springframework.web") public class AppConfig implements WebMvcConfigurer { @Autowired private Config config; diff --git a/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java b/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java index 6aefaab7d5..7dc9642c27 100644 --- a/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java +++ b/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java @@ -25,7 +25,7 @@ import org.dinky.data.exception.AuthException; import org.dinky.data.result.Result; import org.dinky.service.UserService; -import org.dinky.sso.web.LogoutController; + import java.util.List; @@ -35,6 +35,7 @@ import org.pac4j.core.context.JEEContext; import org.pac4j.core.profile.CommonProfile; import org.pac4j.core.profile.ProfileManager; +import org.pac4j.springframework.web.LogoutController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -54,18 +55,18 @@ @RestController @NoArgsConstructor @RequestMapping("/api/sso") -@ConfigurationProperties(prefix = "pac4j") public class SsoCpntroller { - @Value("${sso.baseUrl:localhost:8000}") - private String baseUrl; + @Value("${sso.redirect}") + private String redirect; @Value("${sso.enabled:false}") private Boolean ssoEnabled; - @Value("${sso.centralLogout.defaultUrl:#{null}}") + + @Value("${pac4j.centralLogout.defaultUrl:#{null}}") private String defaultUrl; - @Value("${sso.centralLogout.logoutUrlPattern:#{null}}") + @Value("${pac4j.centralLogout.logoutUrlPattern:#{null}}") private String logoutUrlPattern; @Value("${pac4j.properties.principalNameAttribute:#{null}}") @@ -114,13 +115,15 @@ public Result ssoToken() throws AuthException { @GetMapping("/login") public ModelAndView ssoLogin() { - RedirectView redirectView = new RedirectView("http://" + baseUrl + "/#/user/login?from=sso"); + RedirectView redirectView = new RedirectView(redirect); return new ModelAndView(redirectView); } @GetMapping("/logout") public void ssoLogout() { + logoutController.logout(webContext.getNativeRequest(), webContext.getNativeResponse()); + } @GetMapping("/ssoEnableStatus") diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/AnnotationConfig.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/AnnotationConfig.java deleted file mode 100644 index ec4d2dafdf..0000000000 --- a/dinky-admin/src/main/java/org/dinky/sso/annotation/AnnotationConfig.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.dinky.sso.annotation; - -import org.dinky.sso.annotation.ui.UIAnnotationAspect; -import org.dinky.sso.annotation.ws.WSAnnotationAspect; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.EnableAspectJAutoProxy; - -/** - * The configuration for aspects. - * - * @author Jerome Leleu - * @since 3.2.0 - */ -@Configuration -@EnableAspectJAutoProxy -public class AnnotationConfig { - - @Bean - public WSAnnotationAspect wsAnnotationAspect() { - return new WSAnnotationAspect(); - } - - @Bean - public UIAnnotationAspect uiAnnotationAspect() { - return new UIAnnotationAspect(); - } -} diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/CommonAspect.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/CommonAspect.java deleted file mode 100644 index 9a2021a937..0000000000 --- a/dinky-admin/src/main/java/org/dinky/sso/annotation/CommonAspect.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.dinky.sso.annotation; - -import java.util.List; - -import org.pac4j.core.authorization.authorizer.IsAuthenticatedAuthorizer; -import org.pac4j.core.authorization.authorizer.RequireAllRolesAuthorizer; -import org.pac4j.core.authorization.authorizer.RequireAnyRoleAuthorizer; -import org.pac4j.core.context.JEEContext; -import org.pac4j.core.exception.http.ForbiddenAction; -import org.pac4j.core.exception.http.UnauthorizedAction; -import org.pac4j.core.profile.CommonProfile; -import org.pac4j.core.profile.ProfileManager; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -/** - * Common aspect behaviors. - * - * @author Jerome Leleu - * @since 3.2.0 - */ -@Component -public class CommonAspect { - - private static final IsAuthenticatedAuthorizer IS_AUTHENTICATED_AUTHORIZER = new IsAuthenticatedAuthorizer(); - - @Autowired - private JEEContext webContext; - - @Autowired - private ProfileManager profileManager; - - protected List isAuthenticated(final boolean readFromSession) { - final List profiles = profileManager.getAll(readFromSession); - - if (!IS_AUTHENTICATED_AUTHORIZER.isAuthorized(webContext, profiles)) { - throw UnauthorizedAction.INSTANCE; - } - return profiles; - } - - protected void requireAnyRole(final boolean readFromSession, final String... roles) { - final List profiles = isAuthenticated(readFromSession); - - final RequireAnyRoleAuthorizer authorizer = new RequireAnyRoleAuthorizer<>(roles); - if (!authorizer.isAuthorized(webContext, profiles)) { - throw ForbiddenAction.INSTANCE; - } - } - - protected void requireAllRoles(final boolean readFromSession, final String... roles) { - final List profiles = isAuthenticated(readFromSession); - - final RequireAllRolesAuthorizer authorizer = new RequireAllRolesAuthorizer<>(roles); - if (!authorizer.isAuthorized(webContext, profiles)) { - throw ForbiddenAction.INSTANCE; - } - } -} diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAllRoles.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAllRoles.java deleted file mode 100644 index 66c0104cb8..0000000000 --- a/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAllRoles.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.dinky.sso.annotation.ui; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * The "require all roles" authorization check. - * - * @author Jerome Leleu - * @since 3.2.0 - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface RequireAllRoles { - - String[] value() default {}; -} diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAnyRole.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAnyRole.java deleted file mode 100644 index 9eb0119a22..0000000000 --- a/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/RequireAnyRole.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.dinky.sso.annotation.ui; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * The "require any role" authorization check. - * - * @author Jerome Leleu - * @since 3.2.0 - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface RequireAnyRole { - - String[] value() default {}; -} diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/UIAnnotationAspect.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/UIAnnotationAspect.java deleted file mode 100644 index 6278ea60be..0000000000 --- a/dinky-admin/src/main/java/org/dinky/sso/annotation/ui/UIAnnotationAspect.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.dinky.sso.annotation.ui; - -import org.dinky.sso.annotation.CommonAspect; - -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Before; - -/** - * The aspect to define the web applications annotations. - * - * @author Jerome Leleu - * @since 3.2.0 - */ -@Aspect -public class UIAnnotationAspect extends CommonAspect { - - @Before("@annotation(requireAnyRole)") - public void beforeRequireAnyRole(final RequireAnyRole requireAnyRole) { - requireAnyRole(true, requireAnyRole.value()); - } - - @Before("@annotation(requireAllRoles)") - public void beforeRequireAllRoles(final RequireAllRoles requireAllRoles) { - requireAllRoles(true, requireAllRoles.value()); - } -} diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAllRoles.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAllRoles.java deleted file mode 100644 index 7b7c4c349b..0000000000 --- a/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAllRoles.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.dinky.sso.annotation.ws; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * The "require all roles" authorization check. - * - * @author Jerome Leleu - * @since 3.2.0 - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface RequireAllRoles { - - String[] value() default {}; -} diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAnyRole.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAnyRole.java deleted file mode 100644 index 2e2862714a..0000000000 --- a/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/RequireAnyRole.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.dinky.sso.annotation.ws; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * The "require any role" authorization check. - * - * @author Jerome Leleu - * @since 3.2.0 - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface RequireAnyRole { - - String[] value() default {}; -} diff --git a/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/WSAnnotationAspect.java b/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/WSAnnotationAspect.java deleted file mode 100644 index 5112a82e8a..0000000000 --- a/dinky-admin/src/main/java/org/dinky/sso/annotation/ws/WSAnnotationAspect.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.dinky.sso.annotation.ws; - -import org.dinky.sso.annotation.CommonAspect; - -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Before; - -/** - * The aspect to define the web services annotations. - * - * @author Jerome Leleu - * @since 3.2.0 - */ -@Aspect -public class WSAnnotationAspect extends CommonAspect { - - @Before("@annotation(requireAnyRole)") - public void beforeRequireAnyRole(final RequireAnyRole requireAnyRole) { - requireAnyRole(false, requireAnyRole.value()); - } - - @Before("@annotation(requireAllRoles)") - public void beforeRequireAllRoles(final RequireAllRoles requireAllRoles) { - requireAllRoles(false, requireAllRoles.value()); - } -} diff --git a/dinky-admin/src/main/java/org/dinky/sso/component/ComponentConfig.java b/dinky-admin/src/main/java/org/dinky/sso/component/ComponentConfig.java deleted file mode 100644 index 2ce6477fe4..0000000000 --- a/dinky-admin/src/main/java/org/dinky/sso/component/ComponentConfig.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.dinky.sso.component; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.pac4j.core.config.Config; -import org.pac4j.core.context.JEEContext; -import org.pac4j.core.context.session.JEESessionStore; -import org.pac4j.core.context.session.SessionStore; -import org.pac4j.core.profile.ProfileManager; -import org.pac4j.core.util.FindBest; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.context.annotation.RequestScope; - -/** - * The configuration of the pac4j components. - * - * @author Jerome Leleu - * @since 3.2.0 - */ -@Configuration -public class ComponentConfig { - - @Autowired - protected HttpServletRequest request; - - @Autowired - protected HttpServletResponse response; - - @Autowired(required = false) - protected Config config; - - @Autowired(required = false) - protected SessionStore sessionStore; - - protected SessionStore getSessionStore() { - return FindBest.sessionStore(sessionStore, config, JEESessionStore.INSTANCE); - } - - @Bean - @RequestScope - public JEEContext getWebContext() { - return new JEEContext(request, response, getSessionStore()); - } - - @Bean - @RequestScope - public ProfileManager getProfileManager() { - return new ProfileManager<>(getWebContext()); - } -} diff --git a/dinky-admin/src/main/java/org/dinky/sso/web/CallbackController.java b/dinky-admin/src/main/java/org/dinky/sso/web/CallbackController.java deleted file mode 100644 index 9a8a6cf10f..0000000000 --- a/dinky-admin/src/main/java/org/dinky/sso/web/CallbackController.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.dinky.sso.web; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.pac4j.core.config.Config; -import org.pac4j.core.context.JEEContext; -import org.pac4j.core.context.JEEContextFactory; -import org.pac4j.core.context.session.JEESessionStore; -import org.pac4j.core.context.session.SessionStore; -import org.pac4j.core.engine.CallbackLogic; -import org.pac4j.core.engine.DefaultCallbackLogic; -import org.pac4j.core.http.adapter.HttpActionAdapter; -import org.pac4j.core.http.adapter.JEEHttpActionAdapter; -import org.pac4j.core.util.FindBest; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; - -/** - *

This controller finishes the login process for an indirect client.

- * - * @author Jerome Leleu - * @since 1.0.0 - */ -@Controller -public class CallbackController { - - private CallbackLogic callbackLogic; - - @Value("${pac4j.callback.defaultUrl:api/sso/login}") - private String defaultUrl; - - @Value("${pac4j.callback.multiProfile:#{null}}") - private Boolean multiProfile; - - @Value("${pac4j.callback.saveInSession:#{null}}") - private Boolean saveInSession; - - @Value("${pac4j.callback.renewSession:#{null}}") - private Boolean renewSession; - - @Value("${pac4j.callback.defaultClient:#{null}}") - private String defaultClient; - - @Autowired - private Config config; - - @RequestMapping("${pac4j.callback.path:/callback}") - public void callback(final HttpServletRequest request, final HttpServletResponse response) { - - final SessionStore bestSessionStore = FindBest.sessionStore(null, config, JEESessionStore.INSTANCE); - final HttpActionAdapter bestAdapter = - FindBest.httpActionAdapter(null, config, JEEHttpActionAdapter.INSTANCE); - final CallbackLogic bestLogic = - FindBest.callbackLogic(callbackLogic, config, DefaultCallbackLogic.INSTANCE); - - final JEEContext context = (JEEContext) FindBest.webContextFactory(null, config, JEEContextFactory.INSTANCE) - .newContext(request, response, bestSessionStore); - bestLogic.perform( - context, - config, - bestAdapter, - this.defaultUrl, - this.saveInSession, - this.multiProfile, - this.renewSession, - this.defaultClient); - } - - @RequestMapping("${pac4j.callback.path/{cn}:/callback/{cn}}") - public void callbackWithClientName( - final HttpServletRequest request, final HttpServletResponse response, @PathVariable("cn") final String cn) { - - callback(request, response); - } - - public String getDefaultUrl() { - return defaultUrl; - } - - public void setDefaultUrl(final String defaultUrl) { - this.defaultUrl = defaultUrl; - } - - public CallbackLogic getCallbackLogic() { - return callbackLogic; - } - - public void setCallbackLogic(final CallbackLogic callbackLogic) { - this.callbackLogic = callbackLogic; - } - - public Boolean getMultiProfile() { - return multiProfile; - } - - public void setMultiProfile(final Boolean multiProfile) { - this.multiProfile = multiProfile; - } - - public Boolean getSaveInSession() { - return saveInSession; - } - - public void setSaveInSession(final Boolean saveInSession) { - this.saveInSession = saveInSession; - } - - public Boolean getRenewSession() { - return renewSession; - } - - public void setRenewSession(final Boolean renewSession) { - this.renewSession = renewSession; - } - - public String getDefaultClient() { - return defaultClient; - } - - public void setDefaultClient(final String client) { - this.defaultClient = client; - } - - public Config getConfig() { - return config; - } - - public void setConfig(final Config config) { - this.config = config; - } -} diff --git a/dinky-admin/src/main/java/org/dinky/sso/web/LogoutController.java b/dinky-admin/src/main/java/org/dinky/sso/web/LogoutController.java deleted file mode 100644 index 93e69b7ca8..0000000000 --- a/dinky-admin/src/main/java/org/dinky/sso/web/LogoutController.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.dinky.sso.web; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.pac4j.core.config.Config; -import org.pac4j.core.context.JEEContext; -import org.pac4j.core.context.JEEContextFactory; -import org.pac4j.core.context.session.JEESessionStore; -import org.pac4j.core.context.session.SessionStore; -import org.pac4j.core.engine.DefaultLogoutLogic; -import org.pac4j.core.engine.LogoutLogic; -import org.pac4j.core.http.adapter.HttpActionAdapter; -import org.pac4j.core.http.adapter.JEEHttpActionAdapter; -import org.pac4j.core.util.FindBest; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; - -import lombok.Data; - -/** - *

This controller handles the (application + identity provider) logout process.

- * - * @author Jerome Leleu - * @since 1.0.0 - */ -@Controller -@Data -public class LogoutController { - - private LogoutLogic logoutLogic; - - @Value("${sso.logout.defaultUrl:#{null}}") - private String defaultUrl; - - @Value("${sso.logout.logoutUrlPattern:#{null}}") - private String logoutUrlPattern; - - @Value("${sso.logout.localLogout:#{null}}") - private Boolean localLogout; - - @Value("${sso.logout.destroySession:#{null}}") - private Boolean destroySession; - - @Value("${sso.logout.centralLogout:#{null}}") - private Boolean centralLogout; - - @Autowired - private Config config; - - @RequestMapping("${sso.logout.path:/logout}") - public void logout(final HttpServletRequest request, final HttpServletResponse response) { - - final SessionStore bestSessionStore = FindBest.sessionStore(null, config, JEESessionStore.INSTANCE); - final HttpActionAdapter bestAdapter = - FindBest.httpActionAdapter(null, config, JEEHttpActionAdapter.INSTANCE); - final LogoutLogic bestLogic = - FindBest.logoutLogic(logoutLogic, config, DefaultLogoutLogic.INSTANCE); - - final JEEContext context = (JEEContext) FindBest.webContextFactory(null, config, JEEContextFactory.INSTANCE) - .newContext(request, response, bestSessionStore); - bestLogic.perform( - context, - config, - bestAdapter, - this.defaultUrl, - this.logoutUrlPattern, - this.localLogout, - this.destroySession, - this.centralLogout); - } -} diff --git a/dinky-admin/src/main/java/org/dinky/sso/web/SecurityInterceptor.java b/dinky-admin/src/main/java/org/dinky/sso/web/SecurityInterceptor.java deleted file mode 100644 index 5ca6cdbd3a..0000000000 --- a/dinky-admin/src/main/java/org/dinky/sso/web/SecurityInterceptor.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.dinky.sso.web; - -import java.util.concurrent.atomic.AtomicInteger; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.pac4j.core.authorization.authorizer.Authorizer; -import org.pac4j.core.config.Config; -import org.pac4j.core.context.JEEContext; -import org.pac4j.core.context.JEEContextFactory; -import org.pac4j.core.context.session.JEESessionStore; -import org.pac4j.core.context.session.SessionStore; -import org.pac4j.core.engine.DefaultSecurityLogic; -import org.pac4j.core.engine.SecurityLogic; -import org.pac4j.core.http.adapter.HttpActionAdapter; -import org.pac4j.core.http.adapter.JEEHttpActionAdapter; -import org.pac4j.core.matching.matcher.Matcher; -import org.pac4j.core.util.FindBest; -import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; - -/** - *

This interceptor protects an url.

- * - * @author Jerome Leleu - * @since 1.0.0 - */ -public class SecurityInterceptor extends HandlerInterceptorAdapter { - - private static final AtomicInteger internalNumber = new AtomicInteger(1); - - private SecurityLogic securityLogic; - - private String clients; - - private String authorizers; - - private String matchers; - - private Boolean multiProfile; - - private Config config; - - private HttpActionAdapter httpActionAdapter; - - public SecurityInterceptor(final Config config) { - this.config = config; - } - - public SecurityInterceptor(final Config config, final String clients) { - this(config); - this.clients = clients; - } - - public SecurityInterceptor(final Config config, final String clients, final HttpActionAdapter httpActionAdapter) { - this.clients = clients; - this.config = config; - this.httpActionAdapter = httpActionAdapter; - } - - public SecurityInterceptor(final Config config, final String clients, final String authorizers) { - this(config, clients); - this.authorizers = authorizers; - } - - public SecurityInterceptor(final Config config, final String clients, final Authorizer[] authorizers) { - this(config, clients); - this.authorizers = addAuthorizers(config, authorizers); - } - - public SecurityInterceptor( - final Config config, final String clients, final String authorizers, final String matchers) { - this(config, clients, authorizers); - this.matchers = matchers; - } - - public SecurityInterceptor( - final Config config, final String clients, final Authorizer[] authorizers, final Matcher[] matchers) { - this(config, clients, addAuthorizers(config, authorizers)); - this.matchers = addMatchers(config, matchers); - } - - private static String addAuthorizers(final Config config, final Authorizer[] authorizers) { - final int n = internalNumber.getAndAdd(1); - final int nbAuthorizers = authorizers.length; - final StringBuilder names = new StringBuilder(""); - for (int i = 0; i < nbAuthorizers; i++) { - final String name = "$int_authorizer" + n + "." + i; - config.addAuthorizer(name, authorizers[i]); - if (i > 0) { - names.append(","); - } - names.append(name); - } - return names.toString(); - } - - private static String addMatchers(final Config config, final Matcher[] matchers) { - final int n = internalNumber.getAndAdd(1); - final int nbMatchers = matchers.length; - final StringBuilder names = new StringBuilder(""); - for (int i = 0; i < nbMatchers; i++) { - final String name = "$int_matcher" + n + "." + i; - config.addMatcher(name, matchers[i]); - if (i > 0) { - names.append(","); - } - names.append(name); - } - return names.toString(); - } - - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { - - final SessionStore bestSessionStore = FindBest.sessionStore(null, config, JEESessionStore.INSTANCE); - final HttpActionAdapter bestAdapter = - FindBest.httpActionAdapter(httpActionAdapter, config, JEEHttpActionAdapter.INSTANCE); - final SecurityLogic bestLogic = - FindBest.securityLogic(securityLogic, config, DefaultSecurityLogic.INSTANCE); - - final JEEContext context = (JEEContext) FindBest.webContextFactory(null, config, JEEContextFactory.INSTANCE) - .newContext(request, response, bestSessionStore); - final Object result = bestLogic.perform( - context, - config, - (ctx, profiles, parameters) -> true, - bestAdapter, - clients, - authorizers, - matchers, - multiProfile); - if (result == null) { - return false; - } - return Boolean.parseBoolean(result.toString()); - } - - public SecurityLogic getSecurityLogic() { - return securityLogic; - } - - public void setSecurityLogic(final SecurityLogic securityLogic) { - this.securityLogic = securityLogic; - } - - public String getClients() { - return clients; - } - - public void setClients(final String clients) { - this.clients = clients; - } - - public String getAuthorizers() { - return authorizers; - } - - public void setAuthorizers(final String authorizers) { - this.authorizers = authorizers; - } - - public String getMatchers() { - return matchers; - } - - public void setMatchers(final String matchers) { - this.matchers = matchers; - } - - public Boolean getMultiProfile() { - return multiProfile; - } - - public void setMultiProfile(final Boolean multiProfile) { - this.multiProfile = multiProfile; - } - - public Config getConfig() { - return config; - } - - public void setConfig(final Config config) { - this.config = config; - } - - public HttpActionAdapter getHttpActionAdapter() { - return httpActionAdapter; - } - - public void setHttpActionAdapter(final HttpActionAdapter httpActionAdapter) { - this.httpActionAdapter = httpActionAdapter; - } -} From c9456d9272bd61e81279226f3bb78090bf1d57d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B3=BD=E7=BF=B0?= <627617031@qq.com> Date: Tue, 23 Apr 2024 15:47:59 +0800 Subject: [PATCH 15/21] Optimize the logout logic and fix the inability to access SSO related interfaces after logging out. --- .../src/main/java/org/dinky/service/impl/UserServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java b/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java index 46dc3e416c..084f19482f 100644 --- a/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java +++ b/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java @@ -19,6 +19,7 @@ package org.dinky.service.impl; +import cn.dev33.satoken.session.SaSession; import org.dinky.assertion.Asserts; import org.dinky.context.RowLevelPermissionsContext; import org.dinky.context.TenantContextHolder; @@ -478,6 +479,8 @@ public void buildRowPermission() { @Override public void outLogin() { + SaSession session = StpUtil.getSession(); + session.logout(); StpUtil.logout(StpUtil.getLoginIdAsInt()); } From de2f460d9942e0c189402e131acd64a96a6bf732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B3=BD=E7=BF=B0?= <627617031@qq.com> Date: Thu, 25 Apr 2024 16:35:26 +0800 Subject: [PATCH 16/21] mvn -T 4C spotless:apply --- dinky-admin/pom.xml | 2 +- .../Pac4jConfigAutoConfiguration.java | 23 ++++++++++++- .../Pac4jConfigurationProperties.java | 33 ++++++++++++++----- .../org/dinky/controller/SsoCpntroller.java | 4 --- .../dinky/service/impl/UserServiceImpl.java | 2 +- 5 files changed, 48 insertions(+), 16 deletions(-) diff --git a/dinky-admin/pom.xml b/dinky-admin/pom.xml index f2f49d2fcb..8308905ff1 100644 --- a/dinky-admin/pom.xml +++ b/dinky-admin/pom.xml @@ -34,8 +34,8 @@ provided 4.2.0 - 4.0.1 42.5.1 + 4.0.1 diff --git a/dinky-admin/src/main/java/org/dinky/configure/Pac4jConfigAutoConfiguration.java b/dinky-admin/src/main/java/org/dinky/configure/Pac4jConfigAutoConfiguration.java index a729a064d9..f80d3a8a8c 100644 --- a/dinky-admin/src/main/java/org/dinky/configure/Pac4jConfigAutoConfiguration.java +++ b/dinky-admin/src/main/java/org/dinky/configure/Pac4jConfigAutoConfiguration.java @@ -1,6 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + package org.dinky.configure; import org.dinky.configure.propertie.Pac4jConfigurationProperties; + import org.pac4j.config.client.PropertiesConfigFactory; import org.pac4j.core.config.Config; import org.springframework.beans.factory.annotation.Autowired; @@ -8,6 +28,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; + /** * The Pac4jConfigAutoConfiguration class for Spring. * @@ -25,7 +46,7 @@ public class Pac4jConfigAutoConfiguration { @ConditionalOnMissingBean public Config config() { final PropertiesConfigFactory factory = - new PropertiesConfigFactory(pac4j.getCallbackUrl(), pac4j.getProperties()); + new PropertiesConfigFactory(pac4j.getCallbackUrl(), pac4j.getProperties()); return factory.build(); } } diff --git a/dinky-admin/src/main/java/org/dinky/configure/propertie/Pac4jConfigurationProperties.java b/dinky-admin/src/main/java/org/dinky/configure/propertie/Pac4jConfigurationProperties.java index c9cb477c44..560f7a99c8 100644 --- a/dinky-admin/src/main/java/org/dinky/configure/propertie/Pac4jConfigurationProperties.java +++ b/dinky-admin/src/main/java/org/dinky/configure/propertie/Pac4jConfigurationProperties.java @@ -1,12 +1,32 @@ -package org.dinky.configure.propertie; +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ -import lombok.Getter; -import lombok.Setter; -import org.springframework.boot.context.properties.ConfigurationProperties; +package org.dinky.configure.propertie; import java.util.LinkedHashMap; import java.util.Map; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import lombok.Getter; +import lombok.Setter; + /** * The pac4j configuration and callback URL. * @@ -22,9 +42,4 @@ public class Pac4jConfigurationProperties { private Map centralLogout = new LinkedHashMap<>(); private Map logout = new LinkedHashMap<>(); private String callbackUrl; - } - - - - diff --git a/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java b/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java index 7dc9642c27..6ff6464b2f 100644 --- a/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java +++ b/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java @@ -26,7 +26,6 @@ import org.dinky.data.result.Result; import org.dinky.service.UserService; - import java.util.List; import javax.annotation.PostConstruct; @@ -38,7 +37,6 @@ import org.pac4j.springframework.web.LogoutController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -62,7 +60,6 @@ public class SsoCpntroller { @Value("${sso.enabled:false}") private Boolean ssoEnabled; - @Value("${pac4j.centralLogout.defaultUrl:#{null}}") private String defaultUrl; @@ -123,7 +120,6 @@ public ModelAndView ssoLogin() { public void ssoLogout() { logoutController.logout(webContext.getNativeRequest(), webContext.getNativeResponse()); - } @GetMapping("/ssoEnableStatus") diff --git a/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java b/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java index 084f19482f..611be0eef1 100644 --- a/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java +++ b/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java @@ -19,7 +19,6 @@ package org.dinky.service.impl; -import cn.dev33.satoken.session.SaSession; import org.dinky.assertion.Asserts; import org.dinky.context.RowLevelPermissionsContext; import org.dinky.context.TenantContextHolder; @@ -70,6 +69,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import cn.dev33.satoken.secure.SaSecureUtil; +import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; From 5896c5de5442eda0b5e27ddbb90e2129fa35e327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B3=BD=E7=BF=B0?= <627617031@qq.com> Date: Thu, 25 Apr 2024 16:39:17 +0800 Subject: [PATCH 17/21] delete console.log(location.hash) --- dinky-web/src/pages/Other/Login/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/dinky-web/src/pages/Other/Login/index.tsx b/dinky-web/src/pages/Other/Login/index.tsx index a5598861aa..eec36a1687 100644 --- a/dinky-web/src/pages/Other/Login/index.tsx +++ b/dinky-web/src/pages/Other/Login/index.tsx @@ -55,7 +55,6 @@ const Login: React.FC = () => { }; }); useEffect(() => { - console.log(location.hash) if (location.hash==("#/user/login?from=sso")){ ssoToken().then( res => { From d068481826cc108cc4fbe9ee503bd9e254e9f2ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B3=BD=E7=BF=B0?= <627617031@qq.com> Date: Mon, 27 May 2024 14:18:47 +0800 Subject: [PATCH 18/21] perf(sso): Remove redundant code --- dinky-admin/pom.xml | 44 +++++++++++----- .../Pac4jConfigAutoConfiguration.java | 52 ------------------- .../Pac4jConfigurationProperties.java | 45 ---------------- .../org/dinky/controller/SsoCpntroller.java | 28 ++-------- .../dinky/service/impl/UserServiceImpl.java | 9 ++-- .../main/resources/META-INF/spring.factories | 3 +- .../java/org/dinky/data/enums/Status.java | 1 - 7 files changed, 42 insertions(+), 140 deletions(-) delete mode 100644 dinky-admin/src/main/java/org/dinky/configure/Pac4jConfigAutoConfiguration.java delete mode 100644 dinky-admin/src/main/java/org/dinky/configure/propertie/Pac4jConfigurationProperties.java diff --git a/dinky-admin/pom.xml b/dinky-admin/pom.xml index 5280cf5e37..c8ec3cad45 100644 --- a/dinky-admin/pom.xml +++ b/dinky-admin/pom.xml @@ -42,23 +42,41 @@ org.pac4j - spring-webmvc-pac4j - ${spring-webmvc-pac4j.version} - - - org.pac4j - pac4j-config - ${pac4j.version} - - - org.pac4j - pac4j-oauth + pac4j-springboot ${pac4j.version} + + + org.springframework.boot + spring-boot-starter-web + + + org.apache.logging.log4j + log4j-to-slf4j + + + org.apache.logging.log4j + log4j-api + + org.pac4j - pac4j-http - ${pac4j.version} + spring-webmvc-pac4j + ${spring-webmvc-pac4j.version} + + + org.springframework + spring-webmvc + + + org.springframework + spring-core + + + org.springframework + spring-aop + + org.mitre.dsmiley.httpproxy diff --git a/dinky-admin/src/main/java/org/dinky/configure/Pac4jConfigAutoConfiguration.java b/dinky-admin/src/main/java/org/dinky/configure/Pac4jConfigAutoConfiguration.java deleted file mode 100644 index f80d3a8a8c..0000000000 --- a/dinky-admin/src/main/java/org/dinky/configure/Pac4jConfigAutoConfiguration.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.dinky.configure; - -import org.dinky.configure.propertie.Pac4jConfigurationProperties; - -import org.pac4j.config.client.PropertiesConfigFactory; -import org.pac4j.core.config.Config; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * The Pac4jConfigAutoConfiguration class for Spring. - * - * @author yangzehan - * - */ -@Configuration(value = "Pac4jConfigAutoConfiguration", proxyBeanMethods = false) -@EnableConfigurationProperties(org.dinky.configure.propertie.Pac4jConfigurationProperties.class) -public class Pac4jConfigAutoConfiguration { - - @Autowired - private Pac4jConfigurationProperties pac4j; - - @Bean - @ConditionalOnMissingBean - public Config config() { - final PropertiesConfigFactory factory = - new PropertiesConfigFactory(pac4j.getCallbackUrl(), pac4j.getProperties()); - return factory.build(); - } -} diff --git a/dinky-admin/src/main/java/org/dinky/configure/propertie/Pac4jConfigurationProperties.java b/dinky-admin/src/main/java/org/dinky/configure/propertie/Pac4jConfigurationProperties.java deleted file mode 100644 index 560f7a99c8..0000000000 --- a/dinky-admin/src/main/java/org/dinky/configure/propertie/Pac4jConfigurationProperties.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.dinky.configure.propertie; - -import java.util.LinkedHashMap; -import java.util.Map; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -import lombok.Getter; -import lombok.Setter; - -/** - * The pac4j configuration and callback URL. - * - * @author yangzehan - * - */ -@ConfigurationProperties(prefix = "pac4j", ignoreUnknownFields = false) -@Getter -@Setter -public class Pac4jConfigurationProperties { - private Map properties = new LinkedHashMap<>(); - private Map callback = new LinkedHashMap<>(); - private Map centralLogout = new LinkedHashMap<>(); - private Map logout = new LinkedHashMap<>(); - private String callbackUrl; -} diff --git a/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java b/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java index 6ff6464b2f..2eca9bac13 100644 --- a/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java +++ b/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java @@ -31,10 +31,9 @@ import javax.annotation.PostConstruct; import org.pac4j.core.config.Config; -import org.pac4j.core.context.JEEContext; import org.pac4j.core.profile.CommonProfile; import org.pac4j.core.profile.ProfileManager; -import org.pac4j.springframework.web.LogoutController; +import org.pac4j.springframework.web.CallbackController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; @@ -60,12 +59,6 @@ public class SsoCpntroller { @Value("${sso.enabled:false}") private Boolean ssoEnabled; - @Value("${pac4j.centralLogout.defaultUrl:#{null}}") - private String defaultUrl; - - @Value("${pac4j.centralLogout.logoutUrlPattern:#{null}}") - private String logoutUrlPattern; - @Value("${pac4j.properties.principalNameAttribute:#{null}}") private String principalNameAttribute; @@ -73,25 +66,18 @@ public class SsoCpntroller { private Config config; @Autowired - private JEEContext webContext; + CallbackController callbackController; @Autowired private ProfileManager profileManager; - private LogoutController logoutController; - @Autowired private UserService userService; @PostConstruct protected void afterPropertiesSet() { - logoutController = new LogoutController(); - logoutController.setDefaultUrl(defaultUrl); - logoutController.setLogoutUrlPattern(logoutUrlPattern); - logoutController.setLocalLogout(true); - logoutController.setCentralLogout(true); - logoutController.setConfig(config); - logoutController.setDestroySession(true); + callbackController.setDefaultUrl(redirect); + callbackController.setConfig(config); } @GetMapping("/token") @@ -116,12 +102,6 @@ public ModelAndView ssoLogin() { return new ModelAndView(redirectView); } - @GetMapping("/logout") - public void ssoLogout() { - - logoutController.logout(webContext.getNativeRequest(), webContext.getNativeResponse()); - } - @GetMapping("/ssoEnableStatus") @SaIgnore @ApiOperation("Get SSO enable status") diff --git a/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java b/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java index 29238817ab..4487703f41 100644 --- a/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java +++ b/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java @@ -63,13 +63,13 @@ import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; +import org.pac4j.core.profile.ProfileManager; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import cn.dev33.satoken.secure.SaSecureUtil; -import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; @@ -87,6 +87,7 @@ @RequiredArgsConstructor @Slf4j public class UserServiceImpl extends SuperServiceImpl implements UserService { + private final ProfileManager profileManager; private static final String DEFAULT_PASSWORD = "123456"; @@ -484,8 +485,10 @@ public void buildRowPermission() { @Override public void outLogin() { - SaSession session = StpUtil.getSession(); - session.logout(); + if (profileManager != null) { + profileManager.logout(); + } + StpUtil.logout(StpUtil.getLoginIdAsInt()); } diff --git a/dinky-admin/src/main/resources/META-INF/spring.factories b/dinky-admin/src/main/resources/META-INF/spring.factories index 88eaab22c8..e756436fd6 100644 --- a/dinky-admin/src/main/resources/META-INF/spring.factories +++ b/dinky-admin/src/main/resources/META-INF/spring.factories @@ -1,2 +1 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.dinky.configure.Pac4jConfigAutoConfiguration - +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ diff --git a/dinky-common/src/main/java/org/dinky/data/enums/Status.java b/dinky-common/src/main/java/org/dinky/data/enums/Status.java index a667feed4f..ce11a56053 100644 --- a/dinky-common/src/main/java/org/dinky/data/enums/Status.java +++ b/dinky-common/src/main/java/org/dinky/data/enums/Status.java @@ -454,7 +454,6 @@ public enum Status { PROCESS_CLEAR_LOG_FAILED(199, "process.clear.log.failed"), ; - private final int code; private final String key; From e2eade9cb537c91223a3583d14a321f3eca4fe4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B3=BD=E7=BF=B0?= <627617031@qq.com> Date: Mon, 27 May 2024 14:21:41 +0800 Subject: [PATCH 19/21] perf(sso): Delete redundant configuration information --- dinky-admin/src/main/resources/application.yml | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/dinky-admin/src/main/resources/application.yml b/dinky-admin/src/main/resources/application.yml index 3f4f94767f..c95aacab22 100644 --- a/dinky-admin/src/main/resources/application.yml +++ b/dinky-admin/src/main/resources/application.yml @@ -181,16 +181,6 @@ sso: ################################################# pac4j Config #################################################### ################################################################################################################# pac4j: - callback: - defaultUrl: ${sso.redirect} - logout: - defaultUrl: - destroySession: true - callback: - multiProfile: true - centralLogout: - defaultUrl: http://localhost:${server.port}/?defaulturlafterlogoutafteridp - logoutUrlPattern: http://localhost:${server.port}/.* callbackUrl: http://localhost:${server.port}/callback # The callback URL # Put all parameters under `properties` # Check supported sso config parameters for different authentication clients from the below link @@ -199,6 +189,5 @@ pac4j: principalNameAttribute: login #Authenticate user principal github.id: github.secret: - # Optional, change by authentication client - # Please replace and fill in your client config below when enabled SSO + From ed026f456c64bc75905db80263be534e5978e98f Mon Sep 17 00:00:00 2001 From: Zzm0809 <934230207@qq.com> Date: Thu, 30 May 2024 09:59:37 +0800 Subject: [PATCH 20/21] op code Signed-off-by: Zzm0809 <934230207@qq.com> --- .../controller/{SsoCpntroller.java => SsoController.java} | 2 +- dinky-admin/src/main/resources/application.yml | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) rename dinky-admin/src/main/java/org/dinky/controller/{SsoCpntroller.java => SsoController.java} (99%) diff --git a/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java b/dinky-admin/src/main/java/org/dinky/controller/SsoController.java similarity index 99% rename from dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java rename to dinky-admin/src/main/java/org/dinky/controller/SsoController.java index 2eca9bac13..3b63991f82 100644 --- a/dinky-admin/src/main/java/org/dinky/controller/SsoCpntroller.java +++ b/dinky-admin/src/main/java/org/dinky/controller/SsoController.java @@ -52,7 +52,7 @@ @RestController @NoArgsConstructor @RequestMapping("/api/sso") -public class SsoCpntroller { +public class SsoController { @Value("${sso.redirect}") private String redirect; diff --git a/dinky-admin/src/main/resources/application.yml b/dinky-admin/src/main/resources/application.yml index c95aacab22..d11263c1c8 100644 --- a/dinky-admin/src/main/resources/application.yml +++ b/dinky-admin/src/main/resources/application.yml @@ -2,9 +2,6 @@ ################################################# Common Config ################################################# ################################################################################################################# # Dinky application port - - - server: port: 8888 shutdown: graceful @@ -169,14 +166,16 @@ crypto: enabled: false encryption-password: +--- ################################################################################################################# ################################################# SSO Config #################################################### ################################################################################################################# #see https://github.com/pac4j/spring-webmvc-pac4j-boot-demo/blob/master/src/main/resources/application.properties sso: - enabled: true #enable sso + enabled: false #enable sso default false redirect: http://localhost:8000/#/user/login?from=sso #Front-end address +--- ################################################################################################################# ################################################# pac4j Config #################################################### ################################################################################################################# From f075adacdc22ff5091270aa4a6ca5180c398a18c Mon Sep 17 00:00:00 2001 From: Zzm0809 <934230207@qq.com> Date: Thu, 19 Sep 2024 20:48:57 +0800 Subject: [PATCH 21/21] Update AppConfig.java --- dinky-admin/src/main/java/org/dinky/configure/AppConfig.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java index f79703cf88..35cecd0ea5 100644 --- a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java +++ b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java @@ -108,9 +108,8 @@ public void addInterceptors(InterceptorRegistry registry) { "/api/login", "/api/ldap/ldapEnableStatus", "/download/**", - "/druid/**", "/api/version" - - ); + "/druid/**", + "/api/version"); if (ssoEnabled) { log.info("Load{}", config.getClients().getClients().get(0).getName()); registry.addInterceptor(buildInterceptor(