9

I have implemented Ouath2 as security for my Spring boot rest controllers. Before any of my resource is called, oauth2 validates the token for the users in user table. My question is how to avoid situation where if user1 token is in the request and the request body has data for user2 modification? I need to put a check such that User1 with his token should be able to modify data only for himself. If user1 with his toekn has user2 data in request body should throw 403.

I was thinking if i can get username from token at service layer to do this check? Any help appreciated

RK3
  • 1,221
  • 9
  • 26
  • 37

2 Answers2

5

You are using Spring Security for authentication.

You can get User Detail from SecurityContext

Authentication authentication = SecurityContextHolder.getContext()
    .getAuthentication();

UserDetails userDetail = authentication.getPrincipal();
userDetail.getUsername();

or in Rest Controller

@RequestMapping(value = "/username", method = RequestMethod.GET)
public String currentUserName(Principal principal) {
    return principal.getName();
}

or

@RequestMapping(value = "/username", method = RequestMethod.GET)
public String currentUserName(HttpServletRequest request) {
    Principal principal = request.getUserPrincipal();

    return principal.getName();
}
MyTwoCents
  • 7,284
  • 3
  • 24
  • 52
0

You can do it by creating custom validation.

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {OwnUserValidator.class})
public @interface OwnUser {
String message() default Messages.INVALID_WALLET;

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};
}

//

import org.springframework.beans.factory.annotation.Autowired;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class OwnUserValidator implements ConstraintValidator<OwnUser, String> {

@Override
public void initialize(OwnUser constraintAnnotation) {

}

@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
    String tokenName = THREAD_LOCAL_TOKEN.get();
    if(tokenName.equalsIgnoreCase(value)){
    return true;
    }
    return false;
}
}

then use this @OwnUser annotaion before user field in request body

public class Request implements Serializable{

private static final long serialVersionUID = 1L; 

@OwnUser
private String user;
}

when request call doFilterInternal method here u save token in threadLocal:

public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

public static ThreadLocal<String> THREAD_LOCAL_TOKEN = new ThreadLocal<>();

@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {

    //get token from httpServlet request.
    THREAD_LOCAL_TOKEN.set(nameFromtoken);
    //ur neccessary code
    filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}
GolamMazid Sajib
  • 8,698
  • 6
  • 21
  • 39