Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion db/init/mysql/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ CREATE TABLE `dashboard_user` (
-- ----------------------------
-- Records of dashboard_user
-- ----------------------------
INSERT INTO `dashboard_user` VALUES ('1', 'admin', 'ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413', 1, 1, null, '2022-05-25 18:02:52', '2022-05-25 18:02:52');
INSERT INTO `dashboard_user` VALUES ('1', 'admin', '$2b$12$VRoSQ/.z8C/ldOO9TBfclesgVQ8BxyQK/4Rg/e.DNCisEd.gSyCBG', 1, 1, null, '2022-05-25 18:02:52', '2022-05-25 18:02:52');

-- ----------------------------
-- Table structure for data_permission
Expand Down
2 changes: 1 addition & 1 deletion db/init/ob/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ CREATE TABLE `dashboard_user` (
-- ----------------------------
-- Records of dashboard_user
-- ----------------------------
INSERT INTO `dashboard_user` VALUES ('1', 'admin', 'ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413', 1, 1, null, '2022-05-25 18:02:52', '2022-05-25 18:02:52');
INSERT INTO `dashboard_user` VALUES ('1', 'admin', '$2b$12$VRoSQ/.z8C/ldOO9TBfclesgVQ8BxyQK/4Rg/e.DNCisEd.gSyCBG', 1, 1, null, '2022-05-25 18:02:52', '2022-05-25 18:02:52');

-- ----------------------------
-- Table structure for data_permission
Expand Down
2 changes: 1 addition & 1 deletion db/init/og/create-table.sql
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ COMMENT ON COLUMN "public"."dashboard_user"."date_updated" IS 'update time';
-- ----------------------------
-- Records of dashboard_user
-- ----------------------------
INSERT INTO "public"."dashboard_user" VALUES ('1', 'admin', 'ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413', 1, 1, null, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
INSERT INTO "public"."dashboard_user" VALUES ('1', 'admin', '$2b$12$VRoSQ/.z8C/ldOO9TBfclesgVQ8BxyQK/4Rg/e.DNCisEd.gSyCBG', 1, 1, null, '2022-05-25 18:08:01', '2022-05-25 18:08:01');

-- ----------------------------
-- Table structure for data_permission
Expand Down
4 changes: 2 additions & 2 deletions db/init/oracle/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -891,7 +891,7 @@ comment on column FIELD.date_updated
is 'update time';

/**default admin user**/
INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(dashboard_user(id)) */ INTO dashboard_user (id, user_name, password, role, enabled) VALUES ('1','admin','ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413', '1', '1');
INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(dashboard_user(id)) */ INTO dashboard_user (id, user_name, password, role, enabled) VALUES ('1','admin','$2b$12$VRoSQ/.z8C/ldOO9TBfclesgVQ8BxyQK/4Rg/e.DNCisEd.gSyCBG', '1', '1');

/** insert admin role */
INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(user_role(id)) */ INTO user_role (id, user_id, role_id) VALUES ('1351007709096976384', '1', '1346358560427216896');
Expand Down Expand Up @@ -3813,4 +3813,4 @@ INSERT INTO permission (id, object_id, resource_id, date_created, date_updated)
INSERT INTO permission (id, object_id, resource_id, date_created, date_updated) VALUES ('1953049887387303902', '1346358560427216896', '1953048313980116901', sysdate, sysdate);
INSERT INTO permission (id, object_id, resource_id, date_created, date_updated) VALUES ('1953049887387303903', '1346358560427216896', '1953048313980116902', sysdate, sysdate);
INSERT INTO permission (id, object_id, resource_id, date_created, date_updated) VALUES ('1953049887387303904', '1346358560427216896', '1953048313980116903', sysdate, sysdate);
INSERT INTO permission (id, object_id, resource_id, date_created, date_updated) VALUES ('1953049887387303905', '1346358560427216896', '1953048313980116904', sysdate, sysdate);
INSERT INTO permission (id, object_id, resource_id, date_created, date_updated) VALUES ('1953049887387303905', '1346358560427216896', '1953048313980116904', sysdate, sysdate);
2 changes: 1 addition & 1 deletion db/init/pg/create-table.sql
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ COMMENT ON COLUMN "public"."dashboard_user"."date_updated" IS 'update time';
-- ----------------------------
-- Records of dashboard_user
-- ----------------------------
INSERT INTO "public"."dashboard_user" VALUES ('1', 'admin', 'ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413', 1, 1, null, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
INSERT INTO "public"."dashboard_user" VALUES ('1', 'admin', '$2b$12$VRoSQ/.z8C/ldOO9TBfclesgVQ8BxyQK/4Rg/e.DNCisEd.gSyCBG', 1, 1, null, '2022-05-25 18:08:01', '2022-05-25 18:08:01');

-- ----------------------------
-- Table structure for data_permission
Expand Down
5 changes: 5 additions & 0 deletions shenyu-admin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@
import org.apache.shenyu.admin.model.vo.DashboardUserEditVO;
import org.apache.shenyu.admin.model.vo.DashboardUserVO;
import org.apache.shenyu.admin.service.DashboardUserService;
import org.apache.shenyu.admin.service.PasswordHashService;
import org.apache.shenyu.admin.utils.Assert;
import org.apache.shenyu.admin.utils.ResultUtil;
import org.apache.shenyu.admin.utils.SessionUtil;
import org.apache.shenyu.admin.utils.ShenyuResultMessage;
import org.apache.shenyu.admin.validation.annotation.Existed;
import org.apache.shenyu.common.utils.DigestUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.DeleteMapping;
Expand All @@ -65,9 +65,13 @@
public class DashboardUserController {

private final DashboardUserService dashboardUserService;

private final PasswordHashService passwordHashService;

public DashboardUserController(final DashboardUserService dashboardUserService) {
public DashboardUserController(final DashboardUserService dashboardUserService,
final PasswordHashService passwordHashService) {
this.dashboardUserService = dashboardUserService;
this.passwordHashService = passwordHashService;
}

/**
Expand Down Expand Up @@ -119,7 +123,7 @@ public ShenyuAdminResult detailDashboardUser(@PathVariable("id") final String id
public ShenyuAdminResult createDashboardUser(@Valid @RequestBody final DashboardUserDTO dashboardUserDTO) {
return Optional.ofNullable(dashboardUserDTO)
.map(item -> {
item.setPassword(DigestUtils.sha512Hex(item.getPassword()));
item.setPassword(passwordHashService.encode(item.getPassword()));
Integer createCount = dashboardUserService.createOrUpdate(item);
return ShenyuAdminResult.success(ShenyuResultMessage.CREATE_SUCCESS, createCount);
})
Expand All @@ -141,7 +145,7 @@ public ShenyuAdminResult updateDashboardUser(@PathVariable("id")
@Valid @RequestBody final DashboardUserDTO dashboardUserDTO) {
dashboardUserDTO.setId(id);
if (StringUtils.isNotBlank(dashboardUserDTO.getPassword())) {
dashboardUserDTO.setPassword(DigestUtils.sha512Hex(dashboardUserDTO.getPassword()));
dashboardUserDTO.setPassword(passwordHashService.encode(dashboardUserDTO.getPassword()));
}
Integer updateCount = dashboardUserService.createOrUpdate(dashboardUserDTO);
return ShenyuAdminResult.success(ShenyuResultMessage.UPDATE_SUCCESS, updateCount);
Expand All @@ -167,8 +171,6 @@ public ShenyuAdminResult modifyPassword(@PathVariable("id")
if (!userInfo.getUserId().equals(id) && !userInfo.getUserName().equals(dashboardUserModifyPasswordDTO.getUserName())) {
return ShenyuAdminResult.error(ShenyuResultMessage.DASHBOARD_MODIFY_PASSWORD_ERROR);
}
dashboardUserModifyPasswordDTO.setPassword(DigestUtils.sha512Hex(dashboardUserModifyPasswordDTO.getPassword()));
dashboardUserModifyPasswordDTO.setOldPassword(DigestUtils.sha512Hex(dashboardUserModifyPasswordDTO.getOldPassword()));
return ShenyuAdminResult.success(ShenyuResultMessage.UPDATE_SUCCESS, dashboardUserService.modifyPassword(dashboardUserModifyPasswordDTO));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,11 @@ public interface DashboardUserMapper extends ExistProvider {
* find dashboard user by query.
*
* @param userName user name
* @param password user password
* @param password exact stored password value
* @return {@linkplain DashboardUserDO}
* @deprecated do not use this method for authentication with raw passwords.
*/
@Deprecated
DashboardUserDO findByQuery(@Param("userName") String userName, @Param("password") String password);

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,11 @@ public interface DashboardUserService {
* find dashboard user by query.
*
* @param userName user name
* @param password user password
* @param password exact stored password value
* @return {@linkplain DashboardUserVO}
* @deprecated use {@link #findByUserName(String)} and {@link PasswordHashService} for authentication.
*/
@Deprecated
DashboardUserVO findByQuery(String userName, String password);

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* 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.apache.shenyu.admin.service;

import org.apache.commons.lang3.StringUtils;
import org.apache.shenyu.common.utils.DigestUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.regex.Pattern;

/**
* Central password storage policy for dashboard users.
*/
@Service
public class PasswordHashService {

private static final Pattern BCRYPT_PATTERN = Pattern.compile("^\\$2[aby]\\$\\d{2}\\$[./A-Za-z0-9]{53}$");

private static final Pattern LEGACY_SHA512_PATTERN = Pattern.compile("^[A-Fa-f0-9]{128}$");

private static final int BCRYPT_STRENGTH = 12;

private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(BCRYPT_STRENGTH);

/**
* Encode a raw dashboard user password for storage.
* Returns the input unchanged if it is blank.
*
* @param requestPassword raw password
* @return bcrypt encoded password
*/
public String encode(final String requestPassword) {
if (StringUtils.isBlank(requestPassword)) {
return requestPassword;
}
return passwordEncoder.encode(requestPassword);
}

/**
* Verify a raw password against a bcrypt hash.
*
* @param requestPassword raw password
* @param storedPasswordHash stored password hash
* @return true when the password matches
*/
public boolean matches(final String requestPassword, final String storedPasswordHash) {
if (!isBcryptHash(storedPasswordHash)) {
return false;
}
return passwordEncoder.matches(requestPassword, storedPasswordHash);
}

/**
* Determine whether a stored password uses bcrypt format.
*
* @param storedPasswordHash stored password hash
* @return true when the stored password is bcrypt
*/
public boolean isBcryptHash(final String storedPasswordHash) {
return StringUtils.isNotBlank(storedPasswordHash) && BCRYPT_PATTERN.matcher(storedPasswordHash).matches();
}

/**
* Verify a raw password against the legacy SHA-512 hex format.
*
* @param requestPassword raw password
* @param storedPasswordHash stored password hash
* @return true when the password matches the legacy hash
*/
public boolean matchesLegacySha512(final String requestPassword, final String storedPasswordHash) {
return isLegacySha512Hash(storedPasswordHash)
&& StringUtils.equals(DigestUtils.sha512Hex(requestPassword), storedPasswordHash);
}

/**
* Determine whether a stored password uses the legacy SHA-512 hex format.
*
* @param storedPasswordHash stored password hash
* @return true when the stored password is a legacy SHA-512 hex hash
*/
public boolean isLegacySha512Hash(final String storedPasswordHash) {
return StringUtils.isNotBlank(storedPasswordHash) && LEGACY_SHA512_PATTERN.matcher(storedPasswordHash).matches();
}
}
Loading
Loading