Skip to content

Commit

Permalink
[#1263] api authentication add includePath and excludePath for auth (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
chengyouling committed May 6, 2024
1 parent 744b4a3 commit 694c27e
Show file tree
Hide file tree
Showing 8 changed files with 361 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,9 @@ public class GovernanceConst {

public static final String AUTH_API_PATH_WHITELIST = "spring.cloud.servicecomb.webmvc.publicKey.apiPathWhitelist";

public static final String AUTH_API_PATH_INCLUDE = "spring.cloud.servicecomb.webmvc.publicKey.includePathPatterns";

public static final String AUTH_API_PATH_EXCLUDE = "spring.cloud.servicecomb.webmvc.publicKey.excludePathPatterns";

public static final String CONTEXT_CURRENT_INSTANCE = "x-current-instance";
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package com.huaweicloud.governance.authentication;

import org.apache.commons.lang3.StringUtils;
import org.springframework.core.env.Environment;

import com.huaweicloud.governance.GovernanceConst;
Expand All @@ -34,18 +35,56 @@ public static boolean isPatternMatch(String value, String pattern) {
return value.endsWith(pattern.substring(index));
}
if (pattern.endsWith("*")) {
return value.startsWith(pattern.substring(0, pattern.length() - 1));
int index = pattern.length() - 1;
for (int i = pattern.length() - 1; i >= 0; i--) {
if (pattern.charAt(i) != '*' && pattern.charAt(i) != '/') {
break;
}
index--;
}
return value.startsWith(pattern.substring(0, index + 1));
}
return value.equals(pattern);
}

public static boolean isMatchUriWhitelist(String uri, Environment environment) {
String whiteList = environment.getProperty(GovernanceConst.AUTH_API_PATH_WHITELIST, String.class, "");
if (whiteList.isEmpty()) {
/**
* first determine configured non-authentication path is matched requestPath, if match not needed auth.
* second determine whether of configured authentication path, if not configured, default all path need auth;
* if configured, then check whether of matched requestPath, if match needed auth, otherwise not needed auth.
*
* @param requestPath path
* @param env environment
* @return notRequiredAuth
*/
public static boolean isRequiredAuth(String requestPath, Environment env) {
if (excludePathMatchPath(requestPath, env)) {
return false;
}
return includePathMatchPath(requestPath, env);
}

private static boolean excludePathMatchPath(String requestPath, Environment env) {
String excludePathPattern = env.getProperty(GovernanceConst.AUTH_API_PATH_EXCLUDE, String.class, "");
if (StringUtils.isEmpty(excludePathPattern)) {
excludePathPattern = env.getProperty(GovernanceConst.AUTH_API_PATH_WHITELIST, String.class, "");
}
if (StringUtils.isEmpty(excludePathPattern)) {
return false;
}
for (String whiteUri : whiteList.split(",")) {
if (!whiteUri.isEmpty() && MatcherUtils.isPatternMatch(uri, whiteUri)) {
return isPathMather(requestPath, excludePathPattern);
}

private static boolean includePathMatchPath(String requestPath, Environment env) {
String includePathPattern = env.getProperty(GovernanceConst.AUTH_API_PATH_INCLUDE, String.class, "");
if (StringUtils.isEmpty(includePathPattern)) {
return true;
}
return isPathMather(requestPath, includePathPattern);
}

private static boolean isPathMather(String requestPath, String pathPattern) {
for (String pattern : pathPattern.split(",")) {
if (!pattern.isEmpty() && isPatternMatch(requestPath, pattern)) {
return true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public int getOrder() {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
try {
if (!webFluxRSAProviderAuthManager.checkUriWhitelist(exchange.getRequest().getURI().getPath())) {
if (webFluxRSAProviderAuthManager.isRequiredAuth(exchange.getRequest().getURI().getPath())) {
webFluxRSAProviderAuthManager.valid(exchange);
}
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public void valid(ServerWebExchange exchange) throws Exception {
}
}

public boolean checkUriWhitelist(String uri) {
return MatcherUtils.isMatchUriWhitelist(uri, environment);
public boolean isRequiredAuth(String uri) {
return MatcherUtils.isRequiredAuth(uri, environment);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
return;
}
try {
if (!webMvcRSAProviderAuthManager.checkUriWhitelist(((HttpServletRequest) request).getRequestURI())) {
if (webMvcRSAProviderAuthManager.isRequiredAuth(((HttpServletRequest) request).getRequestURI())) {
webMvcRSAProviderAuthManager.valid((HttpServletRequest) request);
}
chain.doFilter(request, response);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void valid(HttpServletRequest request) throws Exception {
}
}

public boolean checkUriWhitelist(String uri) {
return MatcherUtils.isMatchUriWhitelist(uri, environment);
public boolean isRequiredAuth(String uri) {
return MatcherUtils.isRequiredAuth(uri, environment);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,47 +35,193 @@ public class WebFluxRSAProviderAuthManagerTest {
public void testCheckUriWhitelistPrefixMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_WHITELIST, String.class, ""))
.thenReturn("*/whitelist");
Assertions.assertTrue(manager.checkUriWhitelist("/api/check/whitelist"));
Assertions.assertFalse(manager.isRequiredAuth("/api/check/whitelist"));
}

@Test
public void testCheckUriExcludePrefixMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_EXCLUDE, String.class, ""))
.thenReturn("*/whitelist");
Assertions.assertFalse(manager.isRequiredAuth("/api/check/whitelist"));
clearEnv();
}

@Test
public void testCheckUriIncludePrefixMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_INCLUDE, String.class, ""))
.thenReturn("*/whitelist");
Assertions.assertTrue(manager.isRequiredAuth("/api/check/whitelist"));
clearEnv();
}

@Test
public void testCheckUriWhitelistPrefixSlashMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_WHITELIST, String.class, ""))
.thenReturn("/*/whitelist");
Assertions.assertTrue(manager.checkUriWhitelist("/api/check/whitelist"));
Assertions.assertFalse(manager.isRequiredAuth("/api/check/whitelist"));
clearEnv();
}

@Test
public void testCheckUriExcludePrefixSlashMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_EXCLUDE, String.class, ""))
.thenReturn("/*/whitelist");
Assertions.assertFalse(manager.isRequiredAuth("/api/check/whitelist"));
clearEnv();
}

@Test
public void testCheckUriIncludePrefixSlashMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_INCLUDE, String.class, ""))
.thenReturn("/*/whitelist");
Assertions.assertTrue(manager.isRequiredAuth("/api/check/whitelist"));
clearEnv();
}

@Test
public void testCheckUriWhitelistPrefixNotMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_WHITELIST, String.class, ""))
.thenReturn("*/whitelist");
Assertions.assertFalse(manager.checkUriWhitelist("/api/check/query"));
Assertions.assertTrue(manager.isRequiredAuth("/api/check/query"));
clearEnv();
}

@Test
public void testCheckUriExcludePrefixNotMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_EXCLUDE, String.class, ""))
.thenReturn("*/whitelist");
Assertions.assertTrue(manager.isRequiredAuth("/api/check/query"));
clearEnv();
}

@Test
public void testCheckUriIncludePrefixNotMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_INCLUDE, String.class, ""))
.thenReturn("*/whitelist");
Assertions.assertFalse(manager.isRequiredAuth("/api/check/query"));
clearEnv();
}

@Test
public void testCheckUriWhitelistSuffixMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_WHITELIST, String.class, ""))
.thenReturn("/api/*");
Assertions.assertTrue(manager.checkUriWhitelist("/api/check/whitelist"));
Assertions.assertFalse(manager.isRequiredAuth("/api/check/whitelist"));
clearEnv();
}

@Test
public void testCheckUriExcludeSuffixMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_EXCLUDE, String.class, ""))
.thenReturn("/api/*");
Assertions.assertFalse(manager.isRequiredAuth("/api/check/whitelist"));
clearEnv();
}

@Test
public void testCheckUriIncludeSuffixMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_INCLUDE, String.class, ""))
.thenReturn("/api/*");
Assertions.assertTrue(manager.isRequiredAuth("/api/check/whitelist"));
clearEnv();
}

@Test
public void testCheckUriWhitelistSuffixNotMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_WHITELIST, String.class, ""))
.thenReturn("/apg/*");
Assertions.assertFalse(manager.checkUriWhitelist("/api/check/whitelist"));
Assertions.assertTrue(manager.isRequiredAuth("/api/check/whitelist"));
clearEnv();
}

@Test
public void testCheckUriExcludeSuffixNotMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_EXCLUDE, String.class, ""))
.thenReturn("/apg/*");
Assertions.assertTrue(manager.isRequiredAuth("/api/check/whitelist"));
clearEnv();
}

@Test
public void testCheckUriIncludeSuffixNotMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_INCLUDE, String.class, ""))
.thenReturn("/apg/*");
Assertions.assertFalse(manager.isRequiredAuth("/api/check/whitelist"));
clearEnv();
}

@Test
public void testCheckUriWhitelistEqualMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_WHITELIST, String.class, ""))
.thenReturn("/api/check/whitelist");
Assertions.assertTrue(manager.checkUriWhitelist("/api/check/whitelist"));
Assertions.assertFalse(manager.isRequiredAuth("/api/check/whitelist"));
clearEnv();
}

@Test
public void testCheckUriExcludeEqualMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_EXCLUDE, String.class, ""))
.thenReturn("/api/check/whitelist");
Assertions.assertFalse(manager.isRequiredAuth("/api/check/whitelist"));
clearEnv();
}

@Test
public void testCheckUriIncludeEqualMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_INCLUDE, String.class, ""))
.thenReturn("/api/check/whitelist");
Assertions.assertTrue(manager.isRequiredAuth("/api/check/whitelist"));
clearEnv();
}

@Test
public void testCheckUriWhitelistEqualNotMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_WHITELIST, String.class, ""))
.thenReturn("/api/check/white");
Assertions.assertFalse(manager.checkUriWhitelist("/api/check/whitelist"));
Assertions.assertTrue(manager.isRequiredAuth("/api/check/whitelist"));
clearEnv();
}

@Test
public void testCheckUriExcludeEqualNotMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_EXCLUDE, String.class, ""))
.thenReturn("/api/check/white");
Assertions.assertTrue(manager.isRequiredAuth("/api/check/whitelist"));
clearEnv();
}

@Test
public void testCheckUriIncludeEqualNotMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_INCLUDE, String.class, ""))
.thenReturn("/api/check/white");
Assertions.assertFalse(manager.isRequiredAuth("/api/check/whitelist"));
clearEnv();
}

@Test
public void testCheckUriAllNotSet() {
Assertions.assertTrue(manager.isRequiredAuth("/api/check/whitelist"));
}

/**
* include and exclude both math url, no auth
*/
@Test
public void testCheckUriBothMatch() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_INCLUDE, String.class, ""))
.thenReturn("/api/check/white");
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_EXCLUDE, String.class, ""))
.thenReturn("/api/check/white");
Assertions.assertFalse(manager.isRequiredAuth("/api/check/white"));
clearEnv();
}

private void clearEnv() {
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_INCLUDE, String.class, ""))
.thenReturn("");
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_EXCLUDE, String.class, ""))
.thenReturn("");
Mockito.when(environment.getProperty(GovernanceConst.AUTH_API_PATH_WHITELIST, String.class, ""))
.thenReturn("");
}
}

0 comments on commit 694c27e

Please sign in to comment.