Ad

How Can I Correctly Set A Spring Security Matcher To Handle Request Containing An ID In The Middle Of The URI?

I am going crazy with the following Spring Security matcher expression.

I have this Controller class containing this 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
    .............................................................................................................................................................................................................................................................
    .............................................................................................................................................................................................................................................................
    .............................................................................................................................................................................................................................................................   
    

}

As you can see this API handle GET call toward URI like this: http://localhost:8019/api/admin/user/54/wallet

Now I have the following matcher:

private static final String[] CLIENT_MATCHER = { 

                                                    "/api/users/email/*",
                                                    "/api/admin/**",
                                                    "/api/admin/user/*/wallet/"
                                                };

In this way a CLIENT user (having the appropriate authority into the JWT token) correctly retrieve the information from this API (the controller method is executed and return the expected output).

It works because there is this rule: "/api/admin/"** that allow call toward all the API having an endpoint starting with /api/admin/ folloeed by anything else (so something like http://localhost:8019/api/admin/user/54/wallet is perfectly allowed).

My problem is that I really don't want to give to this type of users (CLIENT users) the possibility to access to all my api starting with /api/admin/ but I need that a user like this have access to the previous endpoint.

So I changed the previous matcher in this way:

private static final String[] CLIENT_MATCHER = { 

                                                    "/api/users/email/*",
                                                    "/api/admin/user/*/wallet"
                                                };

Bascially I removed this rule:

"/api/admin/**",

and I replaced with this one:

"/api/admin/user/*/wallet"

I thought doing so this second version correctly matches request like http://localhost:8019/api/admin/user/54/wallet but it is not working. Calling my API with Postamn I am now obtaining this error message:

{
    "timestamp": "2022-02-10T23:21:47.994+00:00",
    "status": 403,
    "error": "Forbidden",
    "message": "Forbidden",
    "path": "/api/admin/user/54/wallet"
}
Ad

Answer

put this expression -> "/api/admin/user/{userID}/wallet" in CLIENT_MATCHER

Ad
source: stackoverflow.com
Ad