Skip to content

Commit

Permalink
Merge pull request #9 from opensourceways/release/om-webserver0130
Browse files Browse the repository at this point in the history
[CHG]解决etherpad登录失败问题
  • Loading branch information
tfhddd authored Feb 8, 2025
2 parents 2d663e1 + 74505a0 commit c7a6046
Show file tree
Hide file tree
Showing 10 changed files with 179 additions and 133 deletions.
6 changes: 0 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

<properties>
<java.version>17</java.version>
<netty.version>4.1.108.Final</netty.version>
<spring-framework.version>6.1.14</spring-framework.version>
</properties>

Expand Down Expand Up @@ -115,11 +114,6 @@
<artifactId>unirest-java</artifactId>
<version>3.13.8</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.108.Final</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
Expand Down
95 changes: 93 additions & 2 deletions src/main/java/com/om/dao/AuthingManagerDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
import cn.authing.core.types.AuthorizedTargetsParam;
import cn.authing.core.types.CommonMessage;
import cn.authing.core.types.FindUserParam;
import cn.authing.core.types.IAction;
import cn.authing.core.types.IResourceDto;
import cn.authing.core.types.IResourceResponse;
import cn.authing.core.types.Identity;
import cn.authing.core.types.Operator;
import cn.authing.core.types.PaginatedAuthorizedResources;
Expand All @@ -31,6 +34,7 @@
import com.om.controller.bean.request.NamespaceInfoPage;
import com.om.dao.bean.AuthorizeInfo;
import com.om.dao.bean.UserInfo;
import com.om.utils.CommonUtil;
import jakarta.annotation.PostConstruct;

import com.alibaba.fastjson2.JSON;
Expand Down Expand Up @@ -107,6 +111,11 @@ public class AuthingManagerDao {
*/
private static final String LIST_COMMON_RESOURCE = "/list-common-resource";

/**
* 创建账号.
*/
private static final String CREATE_USER = "/create-user";

/**
* 允许的社区列表.
*/
Expand Down Expand Up @@ -621,7 +630,11 @@ public List<UserOfResourceInfo> listUserOfResource(String nameSpaceCode, String
}
List<String> userIds = sourceList.stream()
.map(ResourcePermissionAssignment::getTargetIdentifier).collect(Collectors.toList());
List<User> users = managementClient.users().batch(userIds).execute();
List<List<String>> splitUserIds = CommonUtil.splitList(userIds, 80);
List<User> users = new ArrayList<>();
for (List<String> userIdList : splitUserIds) {
users.addAll(managementClient.users().batch(userIdList).execute());
}
HashMap<String, List<IdentityInfo>> identityBeanMap = new HashMap<>();
HashMap<String, User> userMap = new HashMap<>();
for (User user : users) {
Expand Down Expand Up @@ -890,6 +903,46 @@ public String updateAccountInfo(String token, String account, String type) {
return "true";
}

/**
* 创建资源.
*
* @param namespace 命名空间
* @param resource 资源
* @param actions 操作
* @return 创建结果
*/
public boolean createResource(String namespace, String resource, List<String> actions) {
try {
String resourceName = convertResource(resource);
IResourceResponse execute = managementClient.acl().findResourceByCode(resourceName, namespace).execute();
if (execute != null && StringUtils.isNotBlank(execute.getCode())) {
return true;
}
ArrayList<IAction> list = new ArrayList<>();
for (String action : actions) {
list.add(new IAction(action, null));
}
IResourceDto iResourceDto = new IResourceDto(
resourceName,
ResourceType.DATA,
null,
list,
namespace
);
IResourceResponse res = managementClient.acl().createResource(iResourceDto).execute();
if (res != null && StringUtils.equals(res.getCode(), resourceName)) {
LOGGER.info("create resource({}:{}) success", namespace, resource);
return true;
} else {
LOGGER.info("create resource({}:{}) failed", namespace, resource);
return false;
}
} catch (Exception e) {
LOGGER.error("create resource {} failed {}", resource, e.getMessage());
return false;
}
}

/**
* 授权.
*
Expand Down Expand Up @@ -973,7 +1026,7 @@ public boolean revokeResource(String namespaceCode, String resource, List<String
}

/**
* 根据ID批量获取用户.
* 根据ID批量获取用户(最多一次只能查询50个用户).
*
* @param type 用户类型
* @param extIdpId 三方平台ID
Expand Down Expand Up @@ -1033,6 +1086,44 @@ public List<UserInfo> getUsersByIds(String type, String extIdpId, List<String> u
}
}

/**
* 创建用户.
*
* @param usersObj 用户消息体
* @return 创建用户结果
*/
public UserInfo createUser(JSONObject usersObj) {
try {
String mToken = (String) redisDao.get(Constant.REDIS_KEY_AUTH_MANAGER_TOKEN);
if (StringUtils.isBlank(mToken) || "null".equals(mToken)) {
mToken = getManagementToken();
}
System.out.println(usersObj.toString());
HttpResponse<JsonNode> response = Unirest.post(authingApiHostV3 + CREATE_USER)
.header("Content-Type", "application/json")
.header("x-authing-userpool-id", userPoolId)
.header("authorization", mToken)
.body(usersObj.toString())
.asJson();
JSONObject resObj = response.getBody().getObject();
if (resObj.getInt("statusCode") != 200) {
LOGGER.error("create users failed {}", resObj.getString("message"));
return null;
}
JSONObject data = resObj.getJSONObject("data");
if (data == null) {
return null;
}
UserInfo userInfo = new UserInfo();
userInfo.setUserId(data.getString("userId"));
userInfo.setUsername(data.getString("username"));
return userInfo;
} catch (Exception e) {
LOGGER.error("delete resource failed {}", e.getMessage());
return null;
}
}

/**
* 转换resource(部分resource在authing无法使用,需要转化使用).
*
Expand Down
25 changes: 14 additions & 11 deletions src/main/java/com/om/dao/AuthingUserDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -1462,7 +1462,7 @@ public String updateUserBaseInfo(String token, Map<String, Object> map, String u
updateUserInput.withCompany(inputValue);
break;
case "username":
msg = checkUsername(appId, inputValue, community);
msg = checkUsername(appId, inputValue, community, false);
if (!msg.equals("success")) {
return msg;
}
Expand Down Expand Up @@ -1671,10 +1671,12 @@ public void deleteObsObjectByUrl(String objectUrl) {
* @param appId 应用程序 ID
* @param userName 用户名
* @param community 社区名
* @param isJustContent 只检测内容
* @return 如果用户名可用则返回消息提示,否则返回错误信息
* @throws ServerErrorException 如果在检查过程中出现服务器错误
*/
public String checkUsername(String appId, String userName, String community) throws ServerErrorException {
public String checkUsername(String appId, String userName, String community, boolean isJustContent)
throws ServerErrorException {
String msg = "success";
if (StringUtils.isBlank(userName)) {
msg = "用户名不能为空";
Expand All @@ -1693,16 +1695,17 @@ public String checkUsername(String appId, String userName, String community) thr
return msg;
}
}
if (reservedUsernames.contains(userName) || isUserExists(appId, userName, "username")) {
msg = "用户名已存在";
return msg;
}
if (!moderatorService.checkText(userName)) {
msg = "Username is illegal";
LOGGER.error("username is illegal: {}", userName);
return msg;
if (!isJustContent) {
if (reservedUsernames.contains(userName) || isUserExists(appId, userName, "username")) {
msg = "用户名已存在";
return msg;
}
if (!moderatorService.checkText(userName)) {
msg = "Username is illegal";
LOGGER.error("username is illegal: {}", userName);
return msg;
}
}

return msg;
}

Expand Down
23 changes: 19 additions & 4 deletions src/main/java/com/om/service/AuthingService.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import cn.authing.core.types.Application;
import cn.authing.core.types.Identity;
import cn.authing.core.types.UpdateUserInput;
import cn.authing.core.types.User;
import com.alibaba.fastjson2.JSON;
import com.auth0.jwt.JWT;
Expand Down Expand Up @@ -64,6 +65,7 @@
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.HtmlUtils;

import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.spec.InvalidKeySpecException;
Expand Down Expand Up @@ -452,7 +454,7 @@ public ResponseEntity register(HttpServletRequest servletRequest, HttpServletRes
String accountType;
try {
// 用户名校验
msg = authingUserDao.checkUsername(appId, username, instanceCommunity);
msg = authingUserDao.checkUsername(appId, username, instanceCommunity, false);
if (!msg.equals(Constant.SUCCESS)) {
return result(HttpStatus.BAD_REQUEST, null, msg, null);
}
Expand Down Expand Up @@ -850,6 +852,7 @@ public ResponseEntity tokenApply(HttpServletRequest httpServletRequest,
String idToken = user.get("id_token").toString();
String picture = user.get("picture").toString();
String userName = (String) user.get("username");
userName = resetUserName(appId, userName, userId);
String phone = (String) user.get("phone_number");
String email = (String) user.get("email");
if ("openeuler".equals(instanceCommunity) && StringUtils.isBlank(email)) {
Expand Down Expand Up @@ -877,7 +880,6 @@ public ResponseEntity tokenApply(HttpServletRequest httpServletRequest,
if (listSize > maxLoginNum) {
redisDao.removeListTail(loginKey, maxLoginNum);
}

String token = tokens[0];
String verifyToken = tokens[1];
// 写cookie
Expand Down Expand Up @@ -909,6 +911,19 @@ public ResponseEntity tokenApply(HttpServletRequest httpServletRequest,
}
}

private String resetUserName(String appId, String userName, String userId)
throws ServerErrorException, IOException {
if (Constant.SUCCESS.equals(authingUserDao.checkUsername(appId, userName, instanceCommunity, true))) {
return userName;
} else {
LOGGER.warn("username: {} is invalid, auto clean", userName);
UpdateUserInput updateUserInput = new UpdateUserInput();
updateUserInput.withUsername("");
authingManagerDao.updateUserInfo(userId, updateUserInput);
return "";
}
}

/**
* 发送验证码方法.
*
Expand Down Expand Up @@ -1598,11 +1613,11 @@ public ResponseEntity message(String res) {
if (!res.contains(":")) {
return result(HttpStatus.BAD_REQUEST, null, res, null);
}
ObjectMapper objectMapper = new ObjectMapper();
ObjectMapper jsonReader = new ObjectMapper();
String message = "faild";
try {
res = res.substring(Constant.AUTHING_RES_PREFIX_LENGTH);
Iterator<JsonNode> buckets = objectMapper.readTree(res).iterator();
Iterator<JsonNode> buckets = jsonReader.readTree(res).iterator();
if (buckets.hasNext()) {
message = buckets.next().get("message").get("message").asText();
}
Expand Down
21 changes: 20 additions & 1 deletion src/main/java/com/om/service/OidcService.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import cn.authing.core.types.Application;
import com.alibaba.fastjson2.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
Expand Down Expand Up @@ -55,7 +56,9 @@
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
Expand Down Expand Up @@ -737,7 +740,7 @@ private ResponseEntity getOidcTokenByCode(String appId, String appSecret, String
}
String idToken = jsonNode.get("idToken").asText();
if (scopes.contains("id_token")) {
tokens.put("id_token", idToken);
tokens.put("id_token", createOidcIdToken(appId, appSecret, userId));
}
redisDao.remove(code);
addOidcLogoutUrl(userId, idToken, redirectUri, logoutUrl);
Expand All @@ -750,6 +753,22 @@ private ResponseEntity getOidcTokenByCode(String appId, String appSecret, String
}
}

private String createOidcIdToken(String appId, String appSecret, String userId) throws NoSuchAlgorithmException {
LocalDateTime nowDate = LocalDateTime.now();
Date issuedAt = Date.from(nowDate.atZone(ZoneId.systemDefault()).toInstant());
LocalDateTime expireDate = nowDate.plusSeconds(72000);
Date expireAt = Date.from(expireDate.atZone(ZoneId.systemDefault()).toInstant());
String token = JWT.create()
.withAudience(appId) //谁接受签名
.withIssuedAt(issuedAt) //生成签名的时间
.withExpiresAt(expireAt) //过期时间
.withJWTId(codeUtil.randomStrBuilder(Constant.RANDOM_DEFAULT_LENGTH))
.withClaim("sub", userId)
.withClaim("iss", env.getProperty("oidc.login.page"))
.sign(Algorithm.HMAC256(appSecret));
return token;
}

/**
* oidc扩展协议,增加退出接入应用的机制.
*
Expand Down
Loading

0 comments on commit c7a6046

Please sign in to comment.