如何正确设置 Spring 安全匹配器来处理在 URI 中间包含 ID 的请求?
How can I correctly set a Spring Security matcher to handle request containing an ID in the middle of the URI?
我对以下 Spring 安全匹配器表达式感到疯狂。
我有这个控制器 class 包含这个 API
@RestController
@RequestMapping("/api")
@Log
public class WalletController {
@Autowired
private WalletService walletService;
@Autowired
private UserService userService;
@Autowired
private CoinService coinService;
@Autowired
private ResourceBundleMessageSource errMessage;
@ApiOperation(
value = "Retrieve the wallets list of a specific user",
notes = "Pass the user ID into the URL",
produces = "application/json")
@GetMapping(value = "/admin/user/{userID}/wallet", produces = "application/json")
public ResponseEntity<List<WalletDTO>> getUserWalletsList(@PathVariable("userID") String userID) throws NotFoundException {
log.info(String.format("****** Retrieve the list of wallets owned by the user: %s *******", userID));
List<WalletDTO> walletsDTOList = this.walletService.getAllWalletsOfAnUser(Integer.parseInt(userID));
return new ResponseEntity<List<WalletDTO>>(walletsDTOList, HttpStatus.OK);
}
.............................................................................................................................................................................................................................................................
.............................................................................................................................................................................................................................................................
.............................................................................................................................................................................................................................................................
OTHER APIs
.............................................................................................................................................................................................................................................................
.............................................................................................................................................................................................................................................................
.............................................................................................................................................................................................................................................................
}
如您所见,API 像这样处理对 URI 的 GET 调用:http://localhost:8019/api/admin/user/54/wallet
现在我有以下匹配器:
private static final String[] CLIENT_MATCHER = {
"/api/users/email/*",
"/api/admin/**",
"/api/admin/user/*/wallet/"
};
通过这种方式,CLIENT 用户(对 JWT 令牌具有适当的权限)可以正确地从此 API 检索信息(执行控制器方法并且 return 预期输出)。
之所以有效,是因为存在以下规则:"/api/admin/"** 允许调用所有 API 端点以 /api/admin/ 后面跟着其他任何东西(所以像 http://localhost:8019/api/admin/user/54/wallet 是完全允许的) .
我的问题是我真的不想让这种类型的用户(CLIENT 用户)有机会访问我所有的 api 从 /api/admin 开始/ 但我需要像这样的用户可以访问上一个端点。
所以我把之前的matcher改成这样:
private static final String[] CLIENT_MATCHER = {
"/api/users/email/*",
"/api/admin/user/*/wallet"
};
基本上我删除了这条规则:
"/api/admin/**",
我用这个代替了:
"/api/admin/user/*/wallet"
我认为这样做的第二个版本正确地匹配了像 http://localhost:8019/api/admin/user/54/wallet 这样的请求,但它不起作用。使用 Postamn 调用我的 API 我现在收到此错误消息:
{
"timestamp": "2022-02-10T23:21:47.994+00:00",
"status": 403,
"error": "Forbidden",
"message": "Forbidden",
"path": "/api/admin/user/54/wallet"
}
将此表达式 -> "/api/admin/user/{userID}/wallet" 放入 CLIENT_MATCHER
我对以下 Spring 安全匹配器表达式感到疯狂。
我有这个控制器 class 包含这个 API
@RestController
@RequestMapping("/api")
@Log
public class WalletController {
@Autowired
private WalletService walletService;
@Autowired
private UserService userService;
@Autowired
private CoinService coinService;
@Autowired
private ResourceBundleMessageSource errMessage;
@ApiOperation(
value = "Retrieve the wallets list of a specific user",
notes = "Pass the user ID into the URL",
produces = "application/json")
@GetMapping(value = "/admin/user/{userID}/wallet", produces = "application/json")
public ResponseEntity<List<WalletDTO>> getUserWalletsList(@PathVariable("userID") String userID) throws NotFoundException {
log.info(String.format("****** Retrieve the list of wallets owned by the user: %s *******", userID));
List<WalletDTO> walletsDTOList = this.walletService.getAllWalletsOfAnUser(Integer.parseInt(userID));
return new ResponseEntity<List<WalletDTO>>(walletsDTOList, HttpStatus.OK);
}
.............................................................................................................................................................................................................................................................
.............................................................................................................................................................................................................................................................
.............................................................................................................................................................................................................................................................
OTHER APIs
.............................................................................................................................................................................................................................................................
.............................................................................................................................................................................................................................................................
.............................................................................................................................................................................................................................................................
}
如您所见,API 像这样处理对 URI 的 GET 调用:http://localhost:8019/api/admin/user/54/wallet
现在我有以下匹配器:
private static final String[] CLIENT_MATCHER = {
"/api/users/email/*",
"/api/admin/**",
"/api/admin/user/*/wallet/"
};
通过这种方式,CLIENT 用户(对 JWT 令牌具有适当的权限)可以正确地从此 API 检索信息(执行控制器方法并且 return 预期输出)。
之所以有效,是因为存在以下规则:"/api/admin/"** 允许调用所有 API 端点以 /api/admin/ 后面跟着其他任何东西(所以像 http://localhost:8019/api/admin/user/54/wallet 是完全允许的) .
我的问题是我真的不想让这种类型的用户(CLIENT 用户)有机会访问我所有的 api 从 /api/admin 开始/ 但我需要像这样的用户可以访问上一个端点。
所以我把之前的matcher改成这样:
private static final String[] CLIENT_MATCHER = {
"/api/users/email/*",
"/api/admin/user/*/wallet"
};
基本上我删除了这条规则:
"/api/admin/**",
我用这个代替了:
"/api/admin/user/*/wallet"
我认为这样做的第二个版本正确地匹配了像 http://localhost:8019/api/admin/user/54/wallet 这样的请求,但它不起作用。使用 Postamn 调用我的 API 我现在收到此错误消息:
{
"timestamp": "2022-02-10T23:21:47.994+00:00",
"status": 403,
"error": "Forbidden",
"message": "Forbidden",
"path": "/api/admin/user/54/wallet"
}
将此表达式 -> "/api/admin/user/{userID}/wallet" 放入 CLIENT_MATCHER