Bladeren bron

fix: 三级等保渗透测试【中危】,修改密码未校验原始密码

lihao16 1 maand geleden
bovenliggende
commit
9aa889e116

+ 7 - 1
smsb-customer-manager-adapter/src/main/java/com/inspur/customer/web/controller/keyclaok/KeycloakUserController.java

@@ -89,10 +89,16 @@ public class KeycloakUserController {
 
     @SmsbMethodLog(description = "密码重置", business = "密码重置")
     @PutMapping("/keycloak/changePassword")
-    public Response changePassword(@RequestHeader("userId") String userId, String newPassword) {
+    public Response changePassword(@RequestHeader("userId") String userId, String newPassword,String oldPassword) {
         if (StringUtils.isEmpty(userId)) {
             return Response.buildFailure("400", "密码不能为空");
         }
+        if (StringUtils.isEmpty(oldPassword)) {
+            return Response.buildFailure("400", "原始密码不能为空");
+        }
+        if (!keycloakService.checkUserPassword(userId,oldPassword)) {
+            return Response.buildFailure("400", "原始密码不正确");
+        }
         keycloakService.changePassword(userId, newPassword);
         return Response.buildSuccess();
     }

+ 37 - 0
smsb-customer-manager-app/src/main/java/com/inspur/customer/service/keycloak/KeycloakServiceImpl.java

@@ -16,8 +16,12 @@ import com.inspur.customer.object.wechat.Pair;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.apache.dubbo.config.annotation.DubboService;
+import org.keycloak.OAuth2Constants;
+import org.keycloak.admin.client.Keycloak;
+import org.keycloak.admin.client.KeycloakBuilder;
 import org.keycloak.admin.client.resource.*;
 import org.keycloak.representations.idm.*;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.util.CollectionUtils;
@@ -34,6 +38,15 @@ import java.util.stream.Stream;
 @DubboService
 public class KeycloakServiceImpl implements KeycloakService {
 
+    @Value("${keycloak.auth-server-url}")
+    private String authServerUrl;
+    @Value("${keycloak.realm}")
+    private String realm;
+    @Value("${keycloak.resource}")
+    private String clientId;
+    @Value("${keycloak.credentials.secret}")
+    private String clientSecret;
+
     @Resource
     private RealmResource realmResource;
     @DubboReference
@@ -242,6 +255,30 @@ public class KeycloakServiceImpl implements KeycloakService {
         return resultMap;
     }
 
+    @Override
+    public boolean checkUserPassword(String userId, String oldPassword) {
+        UserResource user = realmResource.users().get(userId);
+        String userName = user.toRepresentation().getUsername();
+        try {
+            // 注意:clientId 必须允许 direct access grants
+            Keycloak kc = KeycloakBuilder.builder()
+                .serverUrl(authServerUrl)
+                .realm(realm)
+                .clientId(clientId)
+                .clientSecret(clientSecret)
+                .username(userName)
+                .password(oldPassword)
+                .grantType(OAuth2Constants.PASSWORD)
+                .build();
+            // 如果能获取token,说明密码正确
+            kc.tokenManager().getAccessToken();
+            return true;
+        } catch (Exception e) {
+            // 校验失败
+            return false;
+        }
+    }
+
     @Override
     public void changePassword(String userId, String newPassword) {
         CredentialRepresentation cr = new CredentialRepresentation();

+ 9 - 0
smsb-customer-manager-client/src/main/java/com/inspur/customer/client/keycloak/KeycloakService.java

@@ -238,4 +238,13 @@ public interface KeycloakService {
      * @return openId的集合
      */
     List<String> queryWechatByRole(String role);
+
+    /**
+     * 检查用户密码
+     *
+     * @param userId
+     * @param oldPassword
+     * @return
+     */
+    boolean checkUserPassword(String userId, String oldPassword);
 }