diff --git a/.gitignore b/.gitignore index 2373a66776..dd0d793cda 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,7 @@ yarn-error.log* pnpm-debug.log* # Editor directories and files +.lh .idea .vscode *.suo diff --git a/backend/pom.xml b/backend/pom.xml index c4bda7ce63..908d3ba808 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -252,11 +252,11 @@ 20171018 - + net.oneandone.reflections8 @@ -337,10 +337,10 @@ 5.7.4 - + ru.yandex.clickhouse 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..57bce9fbaa 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,16 @@ public class AuthServer implements AuthApi { @Override public String logout() { String token = ServletUtils.getToken(); + + if (isOpenOidc()) { + HttpServletRequest request = ServletUtils.request(); + String idToken = request.getHeader("IdToken"); + if (StringUtils.isNotBlank(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 +156,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..22462d5fe9 100644 --- a/backend/src/main/java/io/dataease/auth/service/AuthUserService.java +++ b/backend/src/main/java/io/dataease/auth/service/AuthUserService.java @@ -13,6 +13,8 @@ public interface AuthUserService { SysUserEntity getUserByName(String username); + SysUserEntity getUserBySub(String sub); + List roles(Long userId); List permissions(Long userId); @@ -23,6 +25,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 aceebabb1e..fe11af4de1 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; @@ -19,6 +21,7 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; @@ -49,6 +52,11 @@ public class AuthUserServiceImpl implements AuthUserService { return authMapper.findUserByName(username); } + @Override + public SysUserEntity getUserBySub(String sub) { + return authMapper.findUserBySub(sub); + } + @Override public List roles(Long userId){ return authMapper.roleCodes(userId); @@ -107,8 +115,21 @@ public class AuthUserServiceImpl implements AuthUserService { @Override public boolean supportLdap() { + Map beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((LdapXpackService.class)); + if(beansOfType.keySet().size() == 0) return false; LdapXpackService ldapXpackService = SpringContextUtil.getBean(LdapXpackService.class); 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/DynamicMenuServiceImpl.java b/backend/src/main/java/io/dataease/auth/service/impl/DynamicMenuServiceImpl.java index 70b7f9f280..667aaa09e6 100644 --- a/backend/src/main/java/io/dataease/auth/service/impl/DynamicMenuServiceImpl.java +++ b/backend/src/main/java/io/dataease/auth/service/impl/DynamicMenuServiceImpl.java @@ -13,7 +13,6 @@ import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; 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/base/domain/SysUser.java b/backend/src/main/java/io/dataease/base/domain/SysUser.java index e07c73e757..8867cc75c4 100644 --- a/backend/src/main/java/io/dataease/base/domain/SysUser.java +++ b/backend/src/main/java/io/dataease/base/domain/SysUser.java @@ -39,5 +39,7 @@ public class SysUser implements Serializable { private Integer from; + private String sub; + private static final long serialVersionUID = 1L; } \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/base/domain/SysUserExample.java b/backend/src/main/java/io/dataease/base/domain/SysUserExample.java index 800cfe3d76..1b8fc36618 100644 --- a/backend/src/main/java/io/dataease/base/domain/SysUserExample.java +++ b/backend/src/main/java/io/dataease/base/domain/SysUserExample.java @@ -1213,6 +1213,76 @@ public class SysUserExample { addCriterion("`from` not between", value1, value2, "from"); return (Criteria) this; } + + public Criteria andSubIsNull() { + addCriterion("sub is null"); + return (Criteria) this; + } + + public Criteria andSubIsNotNull() { + addCriterion("sub is not null"); + return (Criteria) this; + } + + public Criteria andSubEqualTo(String value) { + addCriterion("sub =", value, "sub"); + return (Criteria) this; + } + + public Criteria andSubNotEqualTo(String value) { + addCriterion("sub <>", value, "sub"); + return (Criteria) this; + } + + public Criteria andSubGreaterThan(String value) { + addCriterion("sub >", value, "sub"); + return (Criteria) this; + } + + public Criteria andSubGreaterThanOrEqualTo(String value) { + addCriterion("sub >=", value, "sub"); + return (Criteria) this; + } + + public Criteria andSubLessThan(String value) { + addCriterion("sub <", value, "sub"); + return (Criteria) this; + } + + public Criteria andSubLessThanOrEqualTo(String value) { + addCriterion("sub <=", value, "sub"); + return (Criteria) this; + } + + public Criteria andSubLike(String value) { + addCriterion("sub like", value, "sub"); + return (Criteria) this; + } + + public Criteria andSubNotLike(String value) { + addCriterion("sub not like", value, "sub"); + return (Criteria) this; + } + + public Criteria andSubIn(List values) { + addCriterion("sub in", values, "sub"); + return (Criteria) this; + } + + public Criteria andSubNotIn(List values) { + addCriterion("sub not in", values, "sub"); + return (Criteria) this; + } + + public Criteria andSubBetween(String value1, String value2) { + addCriterion("sub between", value1, value2, "sub"); + return (Criteria) this; + } + + public Criteria andSubNotBetween(String value1, String value2) { + addCriterion("sub not between", value1, value2, "sub"); + return (Criteria) this; + } } public static class Criteria extends GeneratedCriteria { diff --git a/backend/src/main/java/io/dataease/base/mapper/SysUserMapper.xml b/backend/src/main/java/io/dataease/base/mapper/SysUserMapper.xml index d2f11fdd43..b779a3a538 100644 --- a/backend/src/main/java/io/dataease/base/mapper/SysUserMapper.xml +++ b/backend/src/main/java/io/dataease/base/mapper/SysUserMapper.xml @@ -19,6 +19,7 @@ + @@ -81,7 +82,7 @@ user_id, dept_id, username, nick_name, gender, phone, email, `password`, is_admin, enabled, create_by, update_by, pwd_reset_time, create_time, update_time, `language`, - `from` + `from`, sub @@ -296,6 +305,9 @@ `from` = #{record.from,jdbcType=INTEGER}, + + sub = #{record.sub,jdbcType=VARCHAR}, + @@ -319,7 +331,8 @@ create_time = #{record.createTime,jdbcType=BIGINT}, update_time = #{record.updateTime,jdbcType=BIGINT}, `language` = #{record.language,jdbcType=VARCHAR}, - `from` = #{record.from,jdbcType=INTEGER} + `from` = #{record.from,jdbcType=INTEGER}, + sub = #{record.sub,jdbcType=VARCHAR} @@ -375,6 +388,9 @@ `from` = #{from,jdbcType=INTEGER}, + + sub = #{sub,jdbcType=VARCHAR}, + where user_id = #{userId,jdbcType=BIGINT} @@ -395,7 +411,8 @@ create_time = #{createTime,jdbcType=BIGINT}, update_time = #{updateTime,jdbcType=BIGINT}, `language` = #{language,jdbcType=VARCHAR}, - `from` = #{from,jdbcType=INTEGER} + `from` = #{from,jdbcType=INTEGER}, + sub = #{sub,jdbcType=VARCHAR} where user_id = #{userId,jdbcType=BIGINT} \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/AuthMapper.java b/backend/src/main/java/io/dataease/base/mapper/ext/AuthMapper.java index d082a0faea..2b1355256f 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ext/AuthMapper.java +++ b/backend/src/main/java/io/dataease/base/mapper/ext/AuthMapper.java @@ -25,6 +25,8 @@ public interface AuthMapper { SysUserEntity findUserByName(@Param("username") String username); + SysUserEntity findUserBySub(@Param("sub") String sub); + List roles(@Param("userId") Long userId); diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/AuthMapper.xml b/backend/src/main/java/io/dataease/base/mapper/ext/AuthMapper.xml index 981dfc5c93..3492d7ec10 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ext/AuthMapper.xml +++ b/backend/src/main/java/io/dataease/base/mapper/ext/AuthMapper.xml @@ -28,6 +28,10 @@ select user_id, username,nick_name, dept_id, password, enabled,email, phone, language ,is_admin from sys_user where username = #{username} + +