I have multiple clients registered for my oauth2 auth server. lets say user1 have roles such as ROLE_A
, ROLE_B
for client1, same user has roes such as ROLE_C
, ROLE_D
for client2. now when the user logins either using client1 or client2 he is able to see all the four roles ie. ROLE_A
, ROLE_B
, ROLE_C
and ROLE_D
.
My requirement was when the user1 logins to client1 it should return only the roles ROLE_A
and ROLE_B
. when he logins using client2 it should return only ROLE_C
and ROLE_D
For achieving this, what I planned is within the authenticate function, I need to get the clientId. so using the clientId and the username I can find the corresponding roles allocated to the user from the db (client-user-roles-mapping table). .But the issue is I don't know how to get the clientId within the authenticate function
@Override
public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
String userName = ((String) authentication.getPrincipal()).toLowerCase();
String password = (String) authentication.getCredentials();
if (userName != null && authentication.getCredentials() != null) {
String clientId = // HERE HOW TO GET THE CLIENT ID
Set<String> userRoles = authRepository.getUserRoleDetails(userName.toLowerCase(), clientId);
Collection<SimpleGrantedAuthority> authorities = fillUserAuthorities(userRoles);
Authentication token = new UsernamePasswordAuthenticationToken(userName, StringUtils.EMPTY, authorities);
return token;
} else {
throw new BadCredentialsException("Authentication Failed!!!");
}
} else {
throw new BadCredentialsException("Username or Password cannot be empty!!!");
}
}
Can anyone please help me on this
UPDATE 1
CustomAuthenticationProvider.java
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
private final Logger log = LoggerFactory.getLogger(getClass());
@Autowired
private LDAPAuthenticationProvider ldapAuthentication;
@Autowired
private AuthRepository authRepository;
public CustomAuthenticationProvider() {
super();
}
@Override
public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
String userName = ((String) authentication.getPrincipal()).toLowerCase();
String password = (String) authentication.getCredentials();
if (userName != null && authentication.getCredentials() != null) {
String clientId = // HERE HOW TO GET THE CLIENT ID
Set<String> userRoles = authRepository.getUserRoleDetails(userName.toLowerCase(), clientId);
Collection<SimpleGrantedAuthority> authorities = fillUserAuthorities(userRoles);
Authentication token = new UsernamePasswordAuthenticationToken(userName, StringUtils.EMPTY, authorities);
return token;
} else {
throw new BadCredentialsException("Authentication Failed!!!");
}
} else {
throw new BadCredentialsException("Username or Password cannot be empty!!!");
}
}
public boolean invokeAuthentication(String username, String password, Boolean isClientValidation) {
try {
Map<String, Object> userDetails = ldapAuthentication.authenticateUser(username, password);
if(Boolean.parseBoolean(userDetails.get("success").toString())) {
return true;
}
} catch (Exception exception) {
log.error("Exception in invokeAuthentication::: " + exception.getMessage());
}
return false;
}
@Override
public boolean supports(Class<? extends Object> authentication) {
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
}
private Collection<SimpleGrantedAuthority> fillUserAuthorities(Set<String> roles) {
Collection<SimpleGrantedAuthority> authorties = new ArrayList<SimpleGrantedAuthority>();
for(String role : roles) {
authorties.add(new SimpleGrantedAuthority(role));
}
return authorties;
}
}
Here is you code after modification
@Override
public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
String userName = ((String) authentication.getPrincipal()).toLowerCase();
String password = (String) authentication.getCredentials();
if (userName != null && authentication.getCredentials() != null) {
String clientId = getClientId();
// validate client ID before use
Set<String> userRoles = authRepository.getUserRoleDetails(userName.toLowerCase(), clientId);
Collection<SimpleGrantedAuthority> authorities = fillUserAuthorities(userRoles);
Authentication token = new UsernamePasswordAuthenticationToken(userName, StringUtils.EMPTY, authorities);
return token;
} else {
throw new BadCredentialsException("Authentication Failed!!!");
}
} else {
throw new BadCredentialsException("Username or Password cannot be empty!!!");
}
private String getClientId(){
final HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
final String authorizationHeaderValue = request.getHeader("Authorization");
final String base64AuthorizationHeader = Optional.ofNullable(authorizationHeaderValue)
.map(headerValue->headerValue.substring("Basic ".length())).orElse("");
if(StringUtils.isNotEmpty(base64AuthorizationHeader)){
String decodedAuthorizationHeader = new String(Base64.getDecoder().decode(base64AuthorizationHeader), Charset.forName("UTF-8"));
return decodedAuthorizationHeader.split(":")[0];
}
return "";
}
more info about RequestContextHolder
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With