diff --git a/backend/pom.xml b/backend/pom.xml index ba4a89c78b..fe17cb8c80 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -252,11 +252,11 @@ 20171018 - + net.oneandone.reflections8 diff --git a/backend/src/main/java/io/dataease/auth/api/AuthApi.java b/backend/src/main/java/io/dataease/auth/api/AuthApi.java index ce79742bde..f5e72afbb0 100644 --- a/backend/src/main/java/io/dataease/auth/api/AuthApi.java +++ b/backend/src/main/java/io/dataease/auth/api/AuthApi.java @@ -4,9 +4,7 @@ import com.github.xiaoymin.knife4j.annotations.ApiSupport; import io.dataease.auth.api.dto.CurrentUserDto; import io.dataease.auth.api.dto.LoginDto; import io.swagger.annotations.Api; -import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiOperation; -import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -46,4 +44,9 @@ public interface AuthApi { @PostMapping("/isOpenLdap") boolean isOpenLdap(); + + @ApiOperation("是否开启oidc") + @PostMapping("/isOpenOidc") + boolean isOpenOidc(); + } diff --git a/backend/src/main/java/io/dataease/auth/entity/TokenInfo.java b/backend/src/main/java/io/dataease/auth/entity/TokenInfo.java index ade63a71ce..e018cca48a 100644 --- a/backend/src/main/java/io/dataease/auth/entity/TokenInfo.java +++ b/backend/src/main/java/io/dataease/auth/entity/TokenInfo.java @@ -13,6 +13,8 @@ public class TokenInfo implements Serializable { private Long userId; + /* private String idToken; */ + public String format(){ return username + "," +userId; } diff --git a/backend/src/main/java/io/dataease/auth/filter/F2CLogoutFilter.java b/backend/src/main/java/io/dataease/auth/filter/F2CLogoutFilter.java index cd5b76320f..3587c52404 100644 --- a/backend/src/main/java/io/dataease/auth/filter/F2CLogoutFilter.java +++ b/backend/src/main/java/io/dataease/auth/filter/F2CLogoutFilter.java @@ -4,7 +4,6 @@ import org.apache.shiro.subject.Subject; import org.apache.shiro.web.filter.authc.LogoutFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; diff --git a/backend/src/main/java/io/dataease/auth/server/AuthServer.java b/backend/src/main/java/io/dataease/auth/server/AuthServer.java index 9408ccff57..03925bb8b8 100644 --- a/backend/src/main/java/io/dataease/auth/server/AuthServer.java +++ b/backend/src/main/java/io/dataease/auth/server/AuthServer.java @@ -21,17 +21,19 @@ import io.dataease.plugins.util.PluginUtils; import io.dataease.plugins.xpack.ldap.dto.request.LdapValidateRequest; import io.dataease.plugins.xpack.ldap.dto.response.ValidateResult; import io.dataease.plugins.xpack.ldap.service.LdapXpackService; +import io.dataease.plugins.xpack.oidc.service.OidcXpackService; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.apache.shiro.SecurityUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; - import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.servlet.http.HttpServletRequest; + @RestController public class AuthServer implements AuthApi { @@ -113,6 +115,13 @@ public class AuthServer implements AuthApi { @Override public String logout() { String token = ServletUtils.getToken(); + + if (isOpenOidc()) { + HttpServletRequest request = ServletUtils.request(); + String idToken = request.getHeader("IdToken"); + OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class); + oidcXpackService.logout(idToken); + } if (StringUtils.isEmpty(token) || StringUtils.equals("null", token) || StringUtils.equals("undefined", token)) { return "success"; } @@ -144,6 +153,15 @@ public class AuthServer implements AuthApi { return open; } + @Override + public boolean isOpenOidc() { + Boolean licValid = PluginUtils.licValid(); + if(!licValid) return false; + return authUserService.supportOidc(); + } + + + /*@Override public Boolean isLogin() { return null; diff --git a/backend/src/main/java/io/dataease/auth/service/AuthUserService.java b/backend/src/main/java/io/dataease/auth/service/AuthUserService.java index 2c514686f3..2c2c6cf08b 100644 --- a/backend/src/main/java/io/dataease/auth/service/AuthUserService.java +++ b/backend/src/main/java/io/dataease/auth/service/AuthUserService.java @@ -23,6 +23,8 @@ public interface AuthUserService { boolean supportLdap(); + Boolean supportOidc(); + } diff --git a/backend/src/main/java/io/dataease/auth/service/impl/AuthUserServiceImpl.java b/backend/src/main/java/io/dataease/auth/service/impl/AuthUserServiceImpl.java index 029bc709d6..614d6d54f2 100644 --- a/backend/src/main/java/io/dataease/auth/service/impl/AuthUserServiceImpl.java +++ b/backend/src/main/java/io/dataease/auth/service/impl/AuthUserServiceImpl.java @@ -10,6 +10,8 @@ import io.dataease.commons.constants.AuthConstants; import io.dataease.commons.utils.LogUtil; import io.dataease.plugins.config.SpringContextUtil; import io.dataease.plugins.xpack.ldap.service.LdapXpackService; +import io.dataease.plugins.xpack.oidc.service.OidcXpackService; + import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.cache.annotation.CacheEvict; @@ -114,4 +116,15 @@ public class AuthUserServiceImpl implements AuthUserService { if(ObjectUtils.isEmpty(ldapXpackService)) return false; return ldapXpackService.isOpen(); } + + @Override + public Boolean supportOidc() { + Map beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((OidcXpackService.class)); + if(beansOfType.keySet().size() == 0) return false; + OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class); + if(ObjectUtils.isEmpty(oidcXpackService)) return false; + return oidcXpackService.isSuuportOIDC(); + } + + } diff --git a/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java b/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java index 36ff6845b6..aecb307469 100644 --- a/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java +++ b/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java @@ -56,9 +56,15 @@ public class ShiroServiceImpl implements ShiroService { // filterChainDefinitionMap.put("/axios.map", ANON); filterChainDefinitionMap.put("/api/auth/login", ANON); - filterChainDefinitionMap.put("/api/auth/logout", ANON); + // filterChainDefinitionMap.put("/api/auth/logout", ANON); filterChainDefinitionMap.put("/api/auth/validateName", ANON); filterChainDefinitionMap.put("/api/auth/isOpenLdap", ANON); + filterChainDefinitionMap.put("/api/auth/isOpenOidc", ANON); + filterChainDefinitionMap.put("/api/pluginCommon/component/*", ANON); + filterChainDefinitionMap.put("/plugin/oidc/authInfo", ANON); + filterChainDefinitionMap.put("/sso/callBack*", ANON); + + filterChainDefinitionMap.put("/unauth", ANON); filterChainDefinitionMap.put("/display/**", ANON); filterChainDefinitionMap.put("/tokenExpired", ANON); diff --git a/backend/src/main/java/io/dataease/auth/util/JWTUtils.java b/backend/src/main/java/io/dataease/auth/util/JWTUtils.java index 7736983d55..544c7a9cb8 100644 --- a/backend/src/main/java/io/dataease/auth/util/JWTUtils.java +++ b/backend/src/main/java/io/dataease/auth/util/JWTUtils.java @@ -2,16 +2,18 @@ package io.dataease.auth.util; import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.JWTCreator.Builder; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.JWTDecodeException; import com.auth0.jwt.interfaces.DecodedJWT; +import com.auth0.jwt.interfaces.Verification; import io.dataease.auth.entity.TokenInfo; +import io.dataease.auth.entity.TokenInfo.TokenInfoBuilder; import io.dataease.commons.utils.CommonBeanFactory; import io.dataease.exception.DataEaseException; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.core.env.Environment; - import java.util.Date; @@ -34,10 +36,13 @@ public class JWTUtils { */ public static boolean verify(String token, TokenInfo tokenInfo, String secret) { Algorithm algorithm = Algorithm.HMAC256(secret); - JWTVerifier verifier = JWT.require(algorithm) + Verification verification = JWT.require(algorithm) .withClaim("username", tokenInfo.getUsername()) - .withClaim("userId", tokenInfo.getUserId()) - .build(); + .withClaim("userId", tokenInfo.getUserId()); + /* if (StringUtils.isNotBlank(tokenInfo.getIdToken())) { + verification.withClaim("idToken", tokenInfo.getIdToken()); + } */ + JWTVerifier verifier = verification.build(); verifier.verify(token); return true; } @@ -50,10 +55,15 @@ public class JWTUtils { DecodedJWT jwt = JWT.decode(token); String username = jwt.getClaim("username").asString(); Long userId = jwt.getClaim("userId").asLong(); + // String idToken = jwt.getClaim("idToken").asString(); if (StringUtils.isEmpty(username) || ObjectUtils.isEmpty(userId) ){ DataEaseException.throwException("token格式错误!"); } - TokenInfo tokenInfo = TokenInfo.builder().username(username).userId(userId).build(); + TokenInfoBuilder tokenInfoBuilder = TokenInfo.builder().username(username).userId(userId); + /* if (StringUtils.isNotBlank(idToken)) { + tokenInfoBuilder.idToken(idToken); + } */ + TokenInfo tokenInfo = tokenInfoBuilder.build(); return tokenInfo; } @@ -107,12 +117,14 @@ public class JWTUtils { try { Date date = new Date(System.currentTimeMillis()+EXPIRE_TIME); Algorithm algorithm = Algorithm.HMAC256(secret); - // 附带username信息 - return JWT.create() + Builder builder = JWT.create() .withClaim("username", tokenInfo.getUsername()) - .withClaim("userId", tokenInfo.getUserId()) - .withExpiresAt(date) - .sign(algorithm); + .withClaim("userId", tokenInfo.getUserId()); + /* if (StringUtils.isNotBlank(tokenInfo.getIdToken())) { + builder.withClaim("idToken", tokenInfo.getIdToken()); + } */ + return builder.withExpiresAt(date).sign(algorithm); + } catch (Exception e) { return null; } diff --git a/backend/src/main/java/io/dataease/plugins/config/LoadjarUtil.java b/backend/src/main/java/io/dataease/plugins/config/LoadjarUtil.java index 8637a0beb1..f50d6d04ed 100644 --- a/backend/src/main/java/io/dataease/plugins/config/LoadjarUtil.java +++ b/backend/src/main/java/io/dataease/plugins/config/LoadjarUtil.java @@ -2,6 +2,7 @@ package io.dataease.plugins.config; import io.dataease.base.domain.MyPlugin; import io.dataease.plugins.loader.ClassloaderResponsity; +import io.dataease.plugins.loader.ControllerLoader; import io.dataease.plugins.loader.ModuleClassLoader; import io.dataease.plugins.loader.MybatisLoader; import org.springframework.beans.factory.annotation.Autowired; @@ -19,6 +20,9 @@ public class LoadjarUtil { @Autowired private MybatisLoader mybatisLoader; + @Autowired + private ControllerLoader controllerLoader; + public List loadJar(String jarPath, MyPlugin myPlugin) throws Exception{ File jar = new File(jarPath); URI uri = jar.toURI(); @@ -34,6 +38,10 @@ public class LoadjarUtil { Thread.currentThread().setContextClassLoader(classLoader); classLoader.initBean(); mybatisLoader.loadMybatis(myPlugin); + + List controllers = classLoader.getRegisteredController(); + controllerLoader.registerController(controllers); + ClassloaderResponsity.getInstance().addClassLoader(moduleName,classLoader); diff --git a/backend/src/main/java/io/dataease/plugins/loader/ControllerLoader.java b/backend/src/main/java/io/dataease/plugins/loader/ControllerLoader.java new file mode 100644 index 0000000000..99c5cce463 --- /dev/null +++ b/backend/src/main/java/io/dataease/plugins/loader/ControllerLoader.java @@ -0,0 +1,95 @@ +package io.dataease.plugins.loader; + + +import io.dataease.commons.utils.LogUtil; +import io.dataease.plugins.config.SpringContextUtil; +import org.springframework.stereotype.Component; +import org.springframework.util.ClassUtils; +import org.springframework.util.ReflectionUtils; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; +import java.lang.reflect.Method; +import java.util.List; + +@Component +public class ControllerLoader { + + /** + * 去掉Controller的Mapping + * @param controllerBeanName + */ + private void unregisterController(String controllerBeanName){ + final RequestMappingHandlerMapping requestMappingHandlerMapping=(RequestMappingHandlerMapping)SpringContextUtil.getBean("requestMappingHandlerMapping"); + + if(requestMappingHandlerMapping!=null){ + String handler=controllerBeanName; + Object controller= SpringContextUtil.getBean(handler); + if(controller==null){ + return; + } + final Class targetClass=controller.getClass(); + ReflectionUtils.doWithMethods(targetClass, new ReflectionUtils.MethodCallback() { + public void doWith(Method method) { + Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass); + try { + Method createMappingMethod = RequestMappingHandlerMapping.class. + getDeclaredMethod("getMappingForMethod", Method.class, Class.class); + createMappingMethod.setAccessible(true); + RequestMappingInfo requestMappingInfo =(RequestMappingInfo) + createMappingMethod.invoke(requestMappingHandlerMapping,specificMethod,targetClass); + if(requestMappingInfo != null) { + requestMappingHandlerMapping.unregisterMapping(requestMappingInfo); + } + }catch (Exception e){ + e.printStackTrace(); + } + } + }, ReflectionUtils.USER_DECLARED_METHODS); + } + } + + /** + * 注册Controller + * @param controllerBeanName + * @throws Exception + */ + private void registerController(String controllerBeanName) throws Exception{ + final RequestMappingHandlerMapping requestMappingHandlerMapping=(RequestMappingHandlerMapping) SpringContextUtil.getBean("requestMappingHandlerMapping"); + + if(requestMappingHandlerMapping!=null){ + String handler=controllerBeanName; + Object controller= SpringContextUtil.getBean(handler); + if(controller==null){ + return; + } + unregisterController(controllerBeanName); + //注册Controller + Method method=requestMappingHandlerMapping.getClass().getSuperclass().getSuperclass().getDeclaredMethod("detectHandlerMethods",Object.class); + + method.setAccessible(true); + method.invoke(requestMappingHandlerMapping,handler); + } + } + + public void registerController(List beanNames) { + beanNames.forEach(name -> { + try { + registerController(name); + } catch (Exception e) { + // e.printStackTrace(); + LogUtil.error(e); + } + }); + } + + + + + + + + + + + +} diff --git a/backend/src/main/java/io/dataease/plugins/loader/ModuleClassLoader.java b/backend/src/main/java/io/dataease/plugins/loader/ModuleClassLoader.java index 794c7b49e1..5a357ae773 100644 --- a/backend/src/main/java/io/dataease/plugins/loader/ModuleClassLoader.java +++ b/backend/src/main/java/io/dataease/plugins/loader/ModuleClassLoader.java @@ -7,10 +7,14 @@ import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.type.TypeAliasRegistry; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.stereotype.Component; +import org.springframework.stereotype.Controller; import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.RequestMapping; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -35,6 +39,8 @@ public class ModuleClassLoader extends URLClassLoader { //需要注册的spring bean的name集合 private List registeredBean = new ArrayList<>(); + private List registeredController = new ArrayList<>(); + //构造 public ModuleClassLoader(URL[] urls, ClassLoader parent) { @@ -150,8 +156,12 @@ public class ModuleClassLoader extends URLClassLoader { beanName = StringUtils.uncapitalize(beanName); SpringContextUtil.getBeanFactory().registerBeanDefinition(beanName,beanDefinition); + + if (isHandler(cla)) { + registeredController.add(beanName); + } + registeredBean.add(beanName); -// System.out.println("注册bean:"+beanName); } } @@ -164,6 +174,10 @@ public class ModuleClassLoader extends URLClassLoader { return registeredBean; } + public List getRegisteredController() { + return registeredController; + } + /** * 方法描述 判断class对象是否带有spring的注解 @@ -184,6 +198,9 @@ public class ModuleClassLoader extends URLClassLoader { if( Modifier.isAbstract(cla.getModifiers())){ return false; } + if (isHandler(cla)) { + return true; + } if(cla.getAnnotation(Component.class)!=null){ return true; @@ -194,8 +211,15 @@ public class ModuleClassLoader extends URLClassLoader { if(cla.getAnnotation(Service.class)!=null){ return true; } + if(cla.getAnnotation(Service.class)!=null){ + return true; + } return false; } + protected boolean isHandler(Class beanType) { + return AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) || AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class); + } + } diff --git a/backend/src/main/java/io/dataease/plugins/server/PluginCommonServer.java b/backend/src/main/java/io/dataease/plugins/server/PluginCommonServer.java index 225542842f..b33e60244c 100644 --- a/backend/src/main/java/io/dataease/plugins/server/PluginCommonServer.java +++ b/backend/src/main/java/io/dataease/plugins/server/PluginCommonServer.java @@ -2,6 +2,7 @@ package io.dataease.plugins.server; import io.dataease.commons.utils.ServletUtils; import io.dataease.plugins.common.dto.PluginSysMenu; +import io.dataease.plugins.common.service.PluginComponentService; import io.dataease.plugins.common.service.PluginMenuService; import io.dataease.plugins.config.SpringContextUtil; import org.springframework.web.bind.annotation.GetMapping; @@ -9,7 +10,6 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import springfox.documentation.annotations.ApiIgnore; - import javax.servlet.http.HttpServletResponse; import java.io.BufferedInputStream; import java.io.IOException; @@ -25,7 +25,7 @@ import java.util.concurrent.atomic.AtomicReference; public class PluginCommonServer { @GetMapping("/async/{menuId}") - public void componentInfo(@PathVariable Long menuId) { + public void menuInfo(@PathVariable Long menuId) { Map pluginMenuServiceMap = SpringContextUtil.getApplicationContext().getBeansOfType(PluginMenuService.class); pluginMenuServiceMap.values().stream().forEach(service -> { AtomicReference atomicReference = new AtomicReference<>(); @@ -65,4 +65,41 @@ public class PluginCommonServer { return; }); } + + @GetMapping("/component/{componentName}") + public void componentInfo(@PathVariable String componentName) { + Map beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType(PluginComponentService.class); + beansOfType.values().stream().forEach(service -> { + List components = service.components(); + if (components.contains(componentName)) { + HttpServletResponse response = ServletUtils.response(); + BufferedInputStream bis = null; + InputStream inputStream = null; + OutputStream os = null; //输出流 + try{ + inputStream = service.vueResource(componentName); + byte[] buffer = new byte[1024]; + os = response.getOutputStream(); + bis = new BufferedInputStream(inputStream); + int i = bis.read(buffer); + while(i != -1){ + os.write(buffer, 0, i); + i = bis.read(buffer); + } + os.flush(); + }catch (Exception e) { + e.printStackTrace(); + }finally { + try { + bis.close(); + inputStream.close(); + os.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return; + } + }); + } } diff --git a/backend/src/main/java/io/dataease/plugins/server/SSOServer.java b/backend/src/main/java/io/dataease/plugins/server/SSOServer.java new file mode 100644 index 0000000000..d91d48df62 --- /dev/null +++ b/backend/src/main/java/io/dataease/plugins/server/SSOServer.java @@ -0,0 +1,85 @@ +package io.dataease.plugins.server; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.servlet.ModelAndView; +import io.dataease.auth.entity.SysUserEntity; +import io.dataease.auth.entity.TokenInfo; +import io.dataease.auth.service.AuthUserService; +import io.dataease.auth.util.JWTUtils; +import io.dataease.commons.exception.DEException; +import io.dataease.commons.utils.CodingUtil; +import io.dataease.commons.utils.ServletUtils; +import io.dataease.plugins.config.SpringContextUtil; +import io.dataease.plugins.xpack.display.dto.response.SysSettingDto; +import io.dataease.plugins.xpack.oidc.dto.SSOToken; +import io.dataease.plugins.xpack.oidc.dto.SSOUserInfo; +import io.dataease.plugins.xpack.oidc.service.OidcXpackService; +import io.dataease.service.sys.SysUserService; + +@RequestMapping("/sso") +@Controller +public class SSOServer { + + @Autowired + private AuthUserService authUserService; + + @Autowired + private SysUserService sysUserService; + + @GetMapping("/callBack") + public ModelAndView callBack(@RequestParam("code") String code, @RequestParam("state") String state) { + Map beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((OidcXpackService.class)); + if(beansOfType.keySet().size() == 0) { + DEException.throwException("缺少oidc插件"); + } + OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class); + Boolean suuportOIDC = oidcXpackService.isSuuportOIDC(); + if (!suuportOIDC) { + DEException.throwException("未开启oidc"); + } + Map config = config(oidcXpackService); + SSOToken ssoToken = oidcXpackService.requestSsoToken(config, code, state); + + SSOUserInfo ssoUserInfo = oidcXpackService.requestUserInfo(config, ssoToken.getAccessToken()); + SysUserEntity sysUserEntity = authUserService.getUserByName(ssoUserInfo.getUserName()); + if(null == sysUserEntity){ + sysUserService.saveOIDCUser(ssoUserInfo); + sysUserEntity = authUserService.getUserByName(ssoUserInfo.getUserName()); + } + TokenInfo tokenInfo = TokenInfo.builder().userId(sysUserEntity.getUserId()).username(sysUserEntity.getUsername()).build(); + String realPwd = CodingUtil.md5(sysUserService.defaultPWD()); + String token = JWTUtils.sign(tokenInfo, realPwd); + ServletUtils.setToken(token); + HttpServletResponse response = ServletUtils.response(); + + Cookie cookie_token = new Cookie("Authorization", token);cookie_token.setPath("/"); + Cookie cookie_id_token = new Cookie("IdToken", ssoToken.getIdToken());cookie_id_token.setPath("/"); + Cookie cookie_ac_token = new Cookie("AccessToken", ssoToken.getAccessToken());cookie_ac_token.setPath("/"); + + response.addCookie(cookie_token); + response.addCookie(cookie_id_token); + response.addCookie(cookie_ac_token); + ModelAndView modelAndView = new ModelAndView("redirect:/"); + return modelAndView; + } + private Map config(OidcXpackService oidcXpackService) { + List sysSettingDtos = oidcXpackService.oidcSettings(); + Map config = sysSettingDtos.stream().collect(Collectors.toMap(SysSettingDto::getParamKey, SysSettingDto::getParamValue)); + return config; + } + + + + +} diff --git a/backend/src/main/java/io/dataease/plugins/server/XOidcServer.java b/backend/src/main/java/io/dataease/plugins/server/XOidcServer.java index c2c21f24e7..debb306ccc 100644 --- a/backend/src/main/java/io/dataease/plugins/server/XOidcServer.java +++ b/backend/src/main/java/io/dataease/plugins/server/XOidcServer.java @@ -4,9 +4,11 @@ package io.dataease.plugins.server; import io.dataease.plugins.config.SpringContextUtil; import io.dataease.plugins.xpack.display.dto.response.SysSettingDto; import io.dataease.plugins.xpack.oidc.service.OidcXpackService; +import org.apache.commons.lang3.StringUtils; import org.springframework.web.bind.annotation.*; - +import java.util.HashMap; import java.util.List; +import java.util.Map; @RequestMapping("/plugin/oidc") @RestController @@ -24,4 +26,34 @@ public class XOidcServer { OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class); oidcXpackService.save(settings); } + + @PostMapping(value="/authInfo") + public Map authInfo() { + OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class); + Map result = new HashMap(); + List oidcSettings = oidcXpackService.oidcSettings(); + + Map authParam = new HashMap<>(); + authParam.put("response_type", "code"); + authParam.put("state", "state"); + // authParam.put("redirect_uri", "http://localhost:9528"); + + + oidcSettings.forEach(param -> { + if(StringUtils.isNotBlank(param.getParamKey())) { + if (StringUtils.equals(param.getParamKey(), "oidc.authEndpoint")) { + result.put("authEndpoint", param.getParamValue()); + } + if (StringUtils.equals(param.getParamKey(), "oidc.scope")) { + authParam.put("scope", param.getParamValue()); + } + if (StringUtils.equals(param.getParamKey(), "oidc.clientId")) { + authParam.put("client_id", param.getParamValue()); + } + } + + }); + result.put("authParam", authParam); + return result; + } } diff --git a/backend/src/main/java/io/dataease/service/sys/SysUserService.java b/backend/src/main/java/io/dataease/service/sys/SysUserService.java index c7af67b383..d40e3d6881 100644 --- a/backend/src/main/java/io/dataease/service/sys/SysUserService.java +++ b/backend/src/main/java/io/dataease/service/sys/SysUserService.java @@ -22,6 +22,8 @@ import io.dataease.controller.sys.response.SysUserGridResponse; import io.dataease.controller.sys.response.SysUserRole; import io.dataease.i18n.Translator; import io.dataease.plugins.common.entity.XpackLdapUserEntity; +import io.dataease.plugins.xpack.oidc.dto.SSOUserInfo; + import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; @@ -31,6 +33,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; + +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -103,6 +107,33 @@ public class SysUserService { return insert; } + @Transactional + public void saveOIDCUser(SSOUserInfo ssoUserInfo) { + long now = System.currentTimeMillis(); + SysUser sysUser = new SysUser(); + sysUser.setUsername(ssoUserInfo.getUserName()); + sysUser.setNickName(ssoUserInfo.getNickName()); + sysUser.setEmail(ssoUserInfo.getEmail()); + sysUser.setPassword(CodingUtil.md5(DEFAULT_PWD)); + sysUser.setCreateTime(now); + sysUser.setUpdateTime(now); + sysUser.setEnabled(1L); + sysUser.setLanguage("zh_CN"); + sysUser.setFrom(2); + sysUserMapper.insert(sysUser); + SysUser dbUser = findOne(sysUser); + if (null != dbUser && null != dbUser.getUserId()) { + // oidc默认角色是普通员工 + List roleIds = new ArrayList(); + roleIds.add(2L); + saveUserRoles( dbUser.getUserId(), roleIds); + } + } + + public String defaultPWD() { + return DEFAULT_PWD; + } + @Transactional public void saveLdapUsers(LdapAddRequest request) { long now = System.currentTimeMillis(); @@ -116,6 +147,7 @@ public class SysUserService { sysUser.setCreateTime(now); sysUser.setUpdateTime(now); sysUser.setEnabled(request.getEnabled()); + sysUser.setLanguage("zh_CN"); sysUser.setFrom(1); return sysUser; }).collect(Collectors.toList()); diff --git a/frontend/src/api/user.js b/frontend/src/api/user.js index 1768205ce8..e9ddcd6ab0 100644 --- a/frontend/src/api/user.js +++ b/frontend/src/api/user.js @@ -57,3 +57,10 @@ export function ldapStatus() { method: 'post' }) } + +export function oidcStatus() { + return request({ + url: '/api/auth/isOpenOidc', + method: 'post' + }) +} diff --git a/frontend/src/views/login/index.vue b/frontend/src/views/login/index.vue index 813637c455..552452644a 100644 --- a/frontend/src/views/login/index.vue +++ b/frontend/src/views/login/index.vue @@ -15,11 +15,11 @@ {{ $t('login.welcome') + (uiInfo && uiInfo['ui.title'] && uiInfo['ui.title'].paramValue || ' DataEase') }} + diff --git a/frontend/src/views/system/user/index.vue b/frontend/src/views/system/user/index.vue index c5f4188913..1a9d8555f9 100644 --- a/frontend/src/views/system/user/index.vue +++ b/frontend/src/views/system/user/index.vue @@ -22,7 +22,7 @@