bootsaas logo

How to protect API endpoints

API endpoints will be protected by default, so instead a better question would be how to permit access to them.

When you create a new endpoint if you want it to be public add it to SecurityConfiguration, for example:

... .requestMatchers(antMatcher(HttpMethod.POST, "/api/newsletter/subscribe")).permitAll()

You've now allowed public access to POST /api/newsletter/subscribe, if you haven't done that the API would allow only authenticated user access.

There is a util class that will help you to get authenticated user or the organization of current authenticated user from anywhere, SecurityUtil

These are the methods you'll find in that class:

/** * Get the authenticated user from the SecurityContextHolder * @throws ApiException if the user is not found in the SecurityContextHolder */ public static User getAuthenticatedUser()
/** * Get the organization of the authenticated user, this is a shortcut to getAuthenticatedUser().getOrganization() */ public static Organization getOrganization()
public static Optional<User> getOptionalAuthenticatedUser()

For example let's say you want to allow users only to update their own profiles. Let's imagine this is the endpoint: PUT /api/users/{id}

The way I prefer to do permission checks is in the service layer in places where they're needed, so I would do it like this:

public UserResponse update(UpdateUserRequestDTO requestDTO, Long userId) { User user = SecurityUtil.getAuthenticatedUser(); if (!Objects.equals(user.getId(), userId)) { throw new AccessDeniedException("You are not allowed to update this user"); }

But you can also use method level security annotations from spring security and then it would look something like this:

@PutMapping("/{id}") @PreAuthorize("#id == principal.id") public ResponseEntity<UserResponse> update(@Valid @RequestBody UpdateUserRequestDTO requestDTO, @PathVariable Long id)
bootsaas logoCopyright © 2024 - All rights reserved