Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[Feature] Sso Backend support #3366

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
yangzehan wants to merge 23 commits into DataLinkDC:dev
base: dev
Choose a base branch
Loading
from yangzehan:sso
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
b721d8e
Add sso support for github oauth
yangzehan Apr 9, 2024
ddc20d7
Add sso support for github oauth
yangzehan Apr 9, 2024
e5bbc74
Add sso support for github oauth
yangzehan Apr 9, 2024
2b84285
mvn -T 4C spotless:apply
yangzehan Apr 9, 2024
db9cbb7
Delete redundant files, fix the SSO client, specify the client name, ...
yangzehan Apr 9, 2024
43e685d
mvn spotless:apply
yangzehan Apr 9, 2024
59a1cef
rollback
yangzehan Apr 9, 2024
4aeb724
Remove basic connection information
yangzehan Apr 10, 2024
afc9277
Improve logic and add front-end code
yangzehan Apr 12, 2024
e3d179d
mvn -T 4C spotless:apply
yangzehan Apr 12, 2024
396a884
Add registration ID
yangzehan Apr 17, 2024
ee042a0
Fix user_type
yangzehan Apr 18, 2024
6972025
Add sso automatic assembly and Remove redundant sso dependencies
yangzehan Apr 23, 2024
01720f3
Remove redundant code
yangzehan Apr 23, 2024
c9456d9
Optimize the logout logic and fix the inability to access SSO related...
yangzehan Apr 23, 2024
de2f460
mvn -T 4C spotless:apply
yangzehan Apr 25, 2024
5896c5d
delete console.log(location.hash)
yangzehan Apr 25, 2024
f2f132e
Merge remote-tracking branch 'refs/remotes/origin/dev' into sso
yangzehan May 27, 2024
d068481
perf(sso): Remove redundant code
yangzehan May 27, 2024
e2eade9
perf(sso): Delete redundant configuration information
yangzehan May 27, 2024
ed026f4
op code
Zzzz-zmy May 30, 2024
765e3c1
Merge branch 'dev' into sso
Zzzz-zmy Sep 19, 2024
f075ada
Update AppConfig.java
Zzzz-zmy Sep 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions dinky-admin/pom.xml
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@

<properties>
<expand.scope>provided</expand.scope>
<!-- Pac4j 4.x for jdk 8 -->
<pac4j.version>4.2.0</pac4j.version>
<postgresql.version>42.5.1</postgresql.version>
<spring-webmvc-pac4j.version>4.0.1</spring-webmvc-pac4j.version>

</properties>

<dependencies>
Expand All @@ -59,6 +63,44 @@
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-springboot</artifactId>
<version>${pac4j.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>spring-webmvc-pac4j</artifactId>
<version>${spring-webmvc-pac4j.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mitre.dsmiley.httpproxy</groupId>
<artifactId>smiley-http-proxy-servlet</artifactId>
Expand Down
39 changes: 36 additions & 3 deletions dinky-admin/src/main/java/org/dinky/configure/AppConfig.java
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,17 @@

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;
Expand All @@ -36,14 +45,23 @@
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import lombok.extern.slf4j.Slf4j;

/**
* AppConfiguration
*
* @since 2021年11月28日 19:35
*/
@Configuration
@Slf4j
@Import({ComponentConfig.class, AnnotationConfig.class})
@ComponentScan(basePackages = "org.pac4j.springframework.web")
public class AppConfig implements WebMvcConfigurer {
@Autowired
private Config config;

@Value("${sso.enabled:false}")
private boolean ssoEnabled;
/**
* Cookie
*
Expand Down Expand Up @@ -86,11 +104,22 @@ public void addInterceptors(InterceptorRegistry registry) {
}))
.addPathPatterns("/api/**", "/openapi/**")
.excludePathPatterns(
"/api/login", "/api/ldap/ldapEnableStatus", "/download/**", "/druid/**", "/api/version");

"/api/sso/ssoEnableStatus",
"/api/login",
"/api/ldap/ldapEnableStatus",
"/download/**",
"/druid/**",
"/api/version");
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");
}
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/**")
Expand All @@ -110,4 +139,8 @@ public void addInterceptors(InterceptorRegistry registry) {
.addPathPatterns("/api/git/**")
.addPathPatterns("/api/jar/*");
}

private SecurityInterceptor buildInterceptor(final String client) {
return new SecurityInterceptor(config, client, JEEHttpActionAdapter.INSTANCE);
}
}
111 changes: 111 additions & 0 deletions dinky-admin/src/main/java/org/dinky/controller/SsoController.java
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
*
* 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 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 java.util.List;

import javax.annotation.PostConstruct;

import org.pac4j.core.config.Config;
import org.pac4j.core.profile.CommonProfile;
import org.pac4j.core.profile.ProfileManager;
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;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
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 杨泽翰
*/
@RestController
@NoArgsConstructor
@RequestMapping("/api/sso")
public class SsoController {
@Value("${sso.redirect}")
private String redirect;

@Value("${sso.enabled:false}")
private Boolean ssoEnabled;

@Value("${pac4j.properties.principalNameAttribute:#{null}}")
private String principalNameAttribute;

@Autowired
private Config config;

@Autowired
CallbackController callbackController;

@Autowired
private ProfileManager profileManager;

@Autowired
private UserService userService;

@PostConstruct
protected void afterPropertiesSet() {
callbackController.setDefaultUrl(redirect);
callbackController.setConfig(config);
}

@GetMapping("/token")
public Result<UserDTO> ssoToken() throws AuthException {
if (!ssoEnabled) {
return Result.failed(Status.SINGLE_LOGIN_DISABLED);
}
List<CommonProfile> 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("/login")
public ModelAndView ssoLogin() {
RedirectView redirectView = new RedirectView(redirect);
return new ModelAndView(redirectView);
}

@GetMapping("/ssoEnableStatus")
@SaIgnore
@ApiOperation("Get SSO enable status")
public Result<Boolean> ssoStatus() {
return Result.succeed(ssoEnabled);
}
}
16 changes: 16 additions & 0 deletions dinky-admin/src/main/java/org/dinky/data/dto/LoginDTO.java
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

package org.dinky.data.dto;

import org.dinky.data.enums.UserType;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
Expand Down Expand Up @@ -48,4 +50,18 @@ 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() {
if (isLdapLogin()) {
return UserType.LDAP;
}
if (isSsoLogin()) {
return UserType.SSO;
}

return UserType.LOCAL;
}
}
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
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;

Expand All @@ -86,6 +87,7 @@
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl extends SuperServiceImpl<UserMapper, User> implements UserService {
private final ProfileManager profileManager;

private static final String DEFAULT_PASSWORD = "123456";

Expand Down Expand Up @@ -177,9 +179,19 @@ public Boolean removeUser(Integer id) {
@Override
public Result<UserDTO> 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());
Expand Down Expand Up @@ -210,6 +222,36 @@ public Result<UserDTO> 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<Integer> 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();
Expand Down Expand Up @@ -443,6 +485,10 @@ public void buildRowPermission() {

@Override
public void outLogin() {
if (profileManager != null) {
profileManager.logout();
}

StpUtil.logout(StpUtil.getLoginIdAsInt());
}

Expand Down
2 changes: 1 addition & 1 deletion dinky-admin/src/main/resources/application-mysql.yml
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ spring:
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
driver-class-name: com.mysql.cj.jdbc.Driver
25 changes: 25 additions & 0 deletions dinky-admin/src/main/resources/application.yml
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,28 @@ 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 default false
redirect: http://localhost:8000/#/user/login?from=sso #Front-end address

---
#################################################################################################################
################################################# pac4j Config ####################################################
#################################################################################################################
pac4j:
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
properties:
principalNameAttribute: login #Authenticate user principal
github.id:
github.secret:


Loading
Loading

AltStyle によって変換されたページ (->オリジナル) /