Skip to content

Commit

Permalink
Add local API authorization (#2975)
Browse files Browse the repository at this point in the history
* add local api authorization

* add local api authorization

* add local api authorization

* add local api authorization

* recover ShenyuConfig

* fix integrated test

* for comments
  • Loading branch information
tuohai666 committed Mar 5, 2022
1 parent d6f8ef4 commit 552672e
Show file tree
Hide file tree
Showing 22 changed files with 145 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
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.utils.ShaUtils;
import org.apache.shenyu.common.utils.ShaUtils;
import org.apache.shenyu.admin.utils.ShenyuResultMessage;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.validation.annotation.Validated;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
import org.apache.shenyu.admin.service.DashboardUserService;
import org.apache.shenyu.admin.transfer.DashboardUserTransfer;
import org.apache.shenyu.admin.utils.JwtUtils;
import org.apache.shenyu.admin.utils.ShaUtils;
import org.apache.shenyu.common.utils.ShaUtils;
import org.apache.shenyu.common.constant.AdminConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import org.apache.shenyu.admin.model.entity.DashboardUserDO;
import org.apache.shenyu.admin.model.page.PageParameter;
import org.apache.shenyu.admin.model.query.DashboardUserQuery;
import org.apache.shenyu.admin.utils.ShaUtils;
import org.apache.shenyu.common.utils.ShaUtils;
import org.apache.shenyu.common.utils.UUIDUtils;
import org.junit.jupiter.api.Test;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import org.apache.shenyu.admin.model.vo.DashboardUserVO;
import org.apache.shenyu.admin.model.vo.LoginDashboardUserVO;
import org.apache.shenyu.admin.service.impl.DashboardUserServiceImpl;
import org.apache.shenyu.admin.utils.ShaUtils;
import org.apache.shenyu.common.utils.ShaUtils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
Expand Down
3 changes: 3 additions & 0 deletions shenyu-bootstrap/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ shenyu:
printInterval: 60000
ribbon:
serverListRefreshInterval: 10000
local:
enabled: true
sha512Key: "BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413"

eureka:
client:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,27 @@ public class ShenyuConfig {
private InstanceConfig instance = new InstanceConfig();

private RibbonConfig ribbon = new RibbonConfig();


private Local local = new Local();

/**
* Gets the local config.
*
* @return the local config
*/
public Local getLocal() {
return local;
}

/**
* Sets the local config.
*
* @param local the local config
*/
public void setLocal(final Local local) {
this.local = local;
}

/**
* Gets ribbon.
*
Expand Down Expand Up @@ -1050,4 +1070,57 @@ public void setServerListRefreshInterval(final Integer serverListRefreshInterval
this.serverListRefreshInterval = serverListRefreshInterval;
}
}

/**
* The local config.
*/
public static class Local {

private Boolean enabled = true;

private String sha512Key;

public Local() {
}

public Local(final String sha512Key) {
this.sha512Key = sha512Key;
}

/**
* Gets enabled.
*
* @return the enabled
*/
public Boolean getEnabled() {
return enabled;
}

/**
* Sets enabled.
*
* @param enabled the enabled
*/
public void setEnabled(final Boolean enabled) {
this.enabled = enabled;
}

/**
* Get Sha512Key.
*
* @return the key
*/
public String getSha512Key() {
return sha512Key;
}

/**
* Set Sha512Key.
*
* @param sha512Key sha512Key
*/
public void setSha512Key(final String sha512Key) {
this.sha512Key = sha512Key;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,11 @@ public interface Constants {
* jwt handle key for secretKey.
*/
String SECRET_KEY = "secretKey";

/**
* local key.
*/
String LOCAL_KEY = "localKey";

/**
* jwt handle key for filterPath.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* limitations under the License.
*/

package org.apache.shenyu.admin.utils;
package org.apache.shenyu.common.utils;

import java.security.MessageDigest;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
* limitations under the License.
*/

package org.apache.shenyu.admin.utils;
package org.apache.shenyu.common.utils;

import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;

/**
* Test cases for ShaUtils.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ shenyu:
paths:
- /favicon.ico
- /actuator/health
local:
enabled: true
sha512Key: "BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413"

logging:
level:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ shenyu:
paths:
- /favicon.ico
- /actuator/health
local:
enabled: true
sha512Key: "BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413"

logging:
level:
root: info
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ shenyu:
paths:
- /favicon.ico
- /actuator/health
local:
enabled: true
sha512Key: "BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413"

logging:
level:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.apache.shenyu.common.constant.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
Expand Down Expand Up @@ -57,6 +58,8 @@ public class HttpHelper {
private static final Gson GSON = new Gson();

private final OkHttpClient client = new OkHttpClient.Builder().build();

private final String localKey = "123456";

/**
* Send a post http request to shenyu gateway.
Expand Down Expand Up @@ -157,7 +160,7 @@ public <S, Q> S postGateway(final String path, final Map<String, Object> headers
* @throws IOException IO exception
*/
public <S> S postGateway(final String path, final RequestBody requestBody, final Class<S> respType) throws IOException {
Request.Builder requestBuilder = new Request.Builder().post(requestBody).url(GATEWAY_END_POINT + path);
Request.Builder requestBuilder = new Request.Builder().post(requestBody).url(GATEWAY_END_POINT + path).addHeader(Constants.LOCAL_KEY, localKey);
Response response = client.newCall(requestBuilder.build()).execute();
String respBody = Objects.requireNonNull(response.body()).string();
try {
Expand All @@ -168,7 +171,7 @@ public <S> S postGateway(final String path, final RequestBody requestBody, final
}

private <Q> String post(final String path, final Map<String, Object> headers, final Q req) throws IOException {
Request.Builder requestBuilder = new Request.Builder().post(RequestBody.create(GSON.toJson(req), JSON)).url(GATEWAY_END_POINT + path);
Request.Builder requestBuilder = new Request.Builder().post(RequestBody.create(GSON.toJson(req), JSON)).url(GATEWAY_END_POINT + path).addHeader(Constants.LOCAL_KEY, localKey);
if (!CollectionUtils.isEmpty(headers)) {
headers.forEach((key, value) -> requestBuilder.addHeader(key, String.valueOf(value)));
}
Expand All @@ -188,7 +191,7 @@ private <Q> String post(final String path, final Map<String, Object> headers, fi
* @throws IOException IO exception
*/
public <S, Q> S putGateway(final String path, final Q req, final Class<S> respType) throws IOException {
Request request = new Request.Builder().put(RequestBody.create(GSON.toJson(req), JSON)).url(GATEWAY_END_POINT + path).build();
Request request = new Request.Builder().put(RequestBody.create(GSON.toJson(req), JSON)).url(GATEWAY_END_POINT + path).addHeader(Constants.LOCAL_KEY, localKey).build();
Response response = client.newCall(request).execute();
String respBody = Objects.requireNonNull(response.body()).string();
LOG.info("postGateway({}) resp({})", path, respBody);
Expand Down Expand Up @@ -254,7 +257,7 @@ public Response getResponseFromGateway(final String path, final Map<String, Obje
* @throws IOException IO exception
*/
public Response getHttpService(final String url, final Map<String, Object> headers) throws IOException {
Request.Builder requestBuilder = new Request.Builder().url(url);
Request.Builder requestBuilder = new Request.Builder().url(url).addHeader(Constants.LOCAL_KEY, localKey);
if (!CollectionUtils.isEmpty(headers)) {
headers.forEach((key, value) -> requestBuilder.addHeader(key, String.valueOf(value)));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ shenyu:
paths:
- /favicon.ico
- /actuator/health
local:
enabled: true
sha512Key: "BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413"

logging:
level:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ shenyu:
paths:
- /favicon.ico
- /actuator/health
local:
enabled: true
sha512Key: "BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413"

#eureka:
# client:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ shenyu:
paths:
- /favicon.ico
- /actuator/health
local:
enabled: true
sha512Key: "BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413"

logging:
level:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ shenyu:
paths:
- /favicon.ico
- /actuator/health
local:
enabled: true
sha512Key: "BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413"

logging:
level:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ shenyu:
paths:
- /favicon.ico
- /actuator/health
local:
enabled: true
sha512Key: "BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413"

logging:
level:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ shenyu:
paths:
- /favicon.ico
- /actuator/health
local:
enabled: true
sha512Key: "BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413"

logging:
level:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ shenyu:
paths:
- /favicon.ico
- /actuator/health
local:
enabled: true
sha512Key: "BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413"

logging:
level:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,15 @@ public RemoteAddressResolver remoteAddressResolver() {
* Local dispatcher filter web filter.
*
* @param dispatcherHandler the dispatcher handler
* @param shenyuConfig the shenyuConfig
*
* @return the web filter
*/
@Bean
@Order(-200)
@ConditionalOnProperty(name = "shenyu.switchConfig.local", havingValue = "true", matchIfMissing = true)
public WebFilter localDispatcherFilter(final DispatcherHandler dispatcherHandler) {
return new LocalDispatcherFilter(dispatcherHandler);
@ConditionalOnProperty(name = "shenyu.local.enable", havingValue = "false", matchIfMissing = true)
public WebFilter localDispatcherFilter(final DispatcherHandler dispatcherHandler, final ShenyuConfig shenyuConfig) {
return new LocalDispatcherFilter(dispatcherHandler, shenyuConfig.getLocal().getSha512Key());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,19 @@

package org.apache.shenyu.web.filter;

import org.apache.shenyu.common.constant.Constants;
import org.apache.shenyu.common.utils.PathMatchUtils;
import org.apache.shenyu.common.utils.ShaUtils;
import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.DispatcherHandler;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

import javax.annotation.Nonnull;
import java.util.Objects;

/**
* The type Local dispatcher filter.
Expand All @@ -35,13 +40,16 @@ public class LocalDispatcherFilter implements WebFilter {

private final DispatcherHandler dispatcherHandler;

private String sha512Key;

/**
* Instantiates a new Local dispatcher filter.
*
* @param dispatcherHandler the dispatcher handler
*/
public LocalDispatcherFilter(final DispatcherHandler dispatcherHandler) {
public LocalDispatcherFilter(final DispatcherHandler dispatcherHandler, final String sha512Key) {
this.dispatcherHandler = dispatcherHandler;
this.sha512Key = sha512Key;
}

/**
Expand All @@ -57,6 +65,10 @@ public LocalDispatcherFilter(final DispatcherHandler dispatcherHandler) {
public Mono<Void> filter(@Nonnull final ServerWebExchange exchange, @Nonnull final WebFilterChain chain) {
String path = exchange.getRequest().getURI().getPath();
if (PathMatchUtils.match(DISPATCHER_PATH, path)) {
String localKey = exchange.getRequest().getHeaders().getFirst(Constants.LOCAL_KEY);
if (Objects.isNull(sha512Key) || !sha512Key.equalsIgnoreCase(ShaUtils.shaEncryption(localKey)) || Objects.isNull(localKey)) {
return Mono.error(new ResponseStatusException(HttpStatus.FORBIDDEN, "The key is not correct."));
}
return dispatcherHandler.handle(exchange);
}
return chain.filter(exchange);
Expand Down

0 comments on commit 552672e

Please sign in to comment.