Skip to content

Commit

Permalink
feat($Authorization): enhance authorization flow - check HTTP method
Browse files Browse the repository at this point in the history
enhance authorization flow - check HTTP method

BREAKING CHANGE: enhanced authorization flow - check HTTP method
  • Loading branch information
Johnny Miller (锺俊) committed Jan 13, 2021
1 parent a08ccf7 commit 01a50de
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import lombok.val;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.ReactiveAuthorizationManager;
import org.springframework.security.core.Authentication;
Expand All @@ -26,6 +27,7 @@

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
Expand Down Expand Up @@ -113,19 +115,41 @@ public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, Au
.filter(permission -> StrUtil.isNotBlank(permission.getUrl()))
.filter(permission -> StrUtil.isNotBlank(permission.getMethod()))
.collect(Collectors.toList());
val path = request.getURI().getPath();
val userPrincipal = mapper.getT2();
for (val buttonPermission : buttonPermissionList) {
// FIXME: currently, the `method` in permission is useless
if (antPathMatcher.match(buttonPermission.getUrl(), path)) {
if (checkRestfulAccess(buttonPermission, request)) {
log.info("Authorization success! Resource [{}] {} is accessible for user(username: {})",
request.getMethod(), request.getURI(), userPrincipal.getUsername());
return new AuthorizationDecision(true);
}
}
log.warn("Authorization failure! Resource [{}] {} is inaccessible for user(username: {})",
log.warn("Authorization failure! Resource [{}] {} is not accessible for user(username: {})",
request.getMethod(), request.getURI(), userPrincipal.getUsername());
return new AuthorizationDecision(false);
});
}

/**
* <p>Check Restful access.</p>
* <ul>
* <li>Check if the URL is matched</li>
* <li>Check if the HTTP method is matched</li>
* </ul>
*
* @param buttonPermission the button permission
* @param request the request
* @return true: accessible; false: not accessible
* @author Johnny Miller (锺俊), email: johnnysviva@outlook.com, date: 1/13/2021 11:04 AM
*/
private boolean checkRestfulAccess(GetPermissionListByRoleIdListResponse.Permission buttonPermission,
ServerHttpRequest request) {
val urlMatched = antPathMatcher.match(buttonPermission.getUrl(), request.getURI().getPath());
// "*" is for super user. Super user's permission is like URL: "/**", method: "*"
val allMethods = StrUtil.equals(buttonPermission.getMethod(), "*");
if (allMethods) {
return urlMatched;
}
val methodMatched = Objects.requireNonNull(request.getMethod()).matches(buttonPermission.getMethod());
return urlMatched && methodMatched;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.jmsoftware.maf.apigateway;

import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.AntPathMatcher;

/**
* Description: AuthorizationTests, change description here.
*
* @author 钟俊(zhongjun), email: zhongjun@toguide.cn, date: 1/13/2021 11:27 AM
**/
@Slf4j
@SpringBootTest
public class AuthorizationTests {
@Test
void antPathMatcherTests() {
val antPathMatcher = new AntPathMatcher();
val urlMatched = antPathMatcher.match("/**", "/spring-boot-admin/common/app-info");
log.info("urlMatched: {}", urlMatched);
Assertions.assertTrue(urlMatched);
}
}

0 comments on commit 01a50de

Please sign in to comment.