Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add local API authorization #2975

Merged
merged 9 commits into from
Mar 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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