fix: corrected formatter error
All checks were successful
Format / formatting (push) Successful in 7s
CI / build (push) Successful in 11s

This commit is contained in:
Pierre Tellier 2025-02-18 16:59:19 +01:00
parent 730aa5f450
commit 820757c836
2 changed files with 45 additions and 41 deletions

View File

@ -3,13 +3,12 @@ package enseirb.myinpulse.api;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.management.relation.RoleNotFoundException;
import java.security.Principal;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.security.Principal;
import javax.management.relation.RoleNotFoundException;
@SpringBootApplication @SpringBootApplication
@RestController @RestController
@ -26,7 +25,6 @@ public class GetUserInfo {
@GetMapping("/unauth/random") @GetMapping("/unauth/random")
public boolean rand(@RequestHeader("Authorization") String token) throws RoleNotFoundException { public boolean rand(@RequestHeader("Authorization") String token) throws RoleNotFoundException {
System.err.println(token); System.err.println(token);
System.err.println("HELLO");
return Math.random() > 0.5; return Math.random() > 0.5;
} }

View File

@ -4,6 +4,8 @@
*/ */
package enseirb.myinpulse.security; package enseirb.myinpulse.security;
import static java.util.stream.Collectors.toSet;
import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.Converter;
import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
@ -18,41 +20,35 @@ import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import static java.util.stream.Collectors.toSet;
public class KeycloakJwtRolesConverter implements Converter<Jwt, AbstractAuthenticationToken> { public class KeycloakJwtRolesConverter implements Converter<Jwt, AbstractAuthenticationToken> {
/** /** Prefix used for realm level roles. */
* Prefix used for realm level roles.
*/
public static final String PREFIX_REALM_ROLE = "ROLE_REALM_"; public static final String PREFIX_REALM_ROLE = "ROLE_REALM_";
/**
* Prefix used in combination with the resource (client) name for resource level roles. /** Prefix used in combination with the resource (client) name for resource level roles. */
*/
public static final String PREFIX_RESOURCE_ROLE = "ROLE_"; public static final String PREFIX_RESOURCE_ROLE = "ROLE_";
/** /** Name of the claim containing the realm level roles */
* Name of the claim containing the realm level roles
*/
private static final String CLAIM_REALM_ACCESS = "realm_access"; private static final String CLAIM_REALM_ACCESS = "realm_access";
/**
* Name of the claim containing the resources (clients) the user has access to. /** Name of the claim containing the resources (clients) the user has access to. */
*/
private static final String CLAIM_RESOURCE_ACCESS = "resource_access"; private static final String CLAIM_RESOURCE_ACCESS = "resource_access";
/**
* Name of the claim containing roles. (Applicable to realm and resource level.) /** Name of the claim containing roles. (Applicable to realm and resource level.) */
*/
private static final String CLAIM_ROLES = "roles"; private static final String CLAIM_ROLES = "roles";
@Override @Override
public AbstractAuthenticationToken convert(Jwt source) { public AbstractAuthenticationToken convert(Jwt source) {
return new JwtAuthenticationToken(source, Stream.concat(new JwtGrantedAuthoritiesConverter().convert(source) return new JwtAuthenticationToken(
.stream(), tokenRolesExtractor(source).stream()) source,
.collect(toSet())); Stream.concat(
new JwtGrantedAuthoritiesConverter().convert(source).stream(),
tokenRolesExtractor(source).stream())
.collect(toSet()));
} }
/** /**
* Extracts the realm and resource level roles from a JWT token distinguishing between them using prefixes. * Extracts the realm and resource level roles from a JWT token distinguishing between them
* using prefixes.
*/ */
public Collection<GrantedAuthority> tokenRolesExtractor(Jwt jwt) { public Collection<GrantedAuthority> tokenRolesExtractor(Jwt jwt) {
// Collection that will hold the extracted roles // Collection that will hold the extracted roles
@ -69,33 +65,43 @@ public class KeycloakJwtRolesConverter implements Converter<Jwt, AbstractAuthent
// Check if any roles are present // Check if any roles are present
if (roles != null && !roles.isEmpty()) { if (roles != null && !roles.isEmpty()) {
// Iterate of the roles and add them to the granted authorities // Iterate of the roles and add them to the granted authorities
Collection<GrantedAuthority> realmRoles = roles.stream() Collection<GrantedAuthority> realmRoles =
// Prefix all realm roles with "ROLE_realm_" roles.stream()
.map(role -> new SimpleGrantedAuthority(PREFIX_REALM_ROLE + role)) // Prefix all realm roles with "ROLE_realm_"
.collect(Collectors.toList()); .map(role -> new SimpleGrantedAuthority(PREFIX_REALM_ROLE + role))
.collect(Collectors.toList());
grantedAuthorities.addAll(realmRoles); grantedAuthorities.addAll(realmRoles);
} }
} }
// Resource (client) roles // Resource (client) roles
// A user might have access to multiple resources all containing their own roles. Therefore, it is a map of // A user might have access to multiple resources all containing their own roles. Therefore,
// it is a map of
// resource each possibly containing a "roles" property. // resource each possibly containing a "roles" property.
Map<String, Map<String, Collection<String>>> resourceAccess = jwt.getClaim(CLAIM_RESOURCE_ACCESS); Map<String, Map<String, Collection<String>>> resourceAccess =
jwt.getClaim(CLAIM_RESOURCE_ACCESS);
// Check if resources are assigned // Check if resources are assigned
if (resourceAccess != null && !resourceAccess.isEmpty()) { if (resourceAccess != null && !resourceAccess.isEmpty()) {
// Iterate of all the resources // Iterate of all the resources
resourceAccess.forEach((resource, resourceClaims) -> { resourceAccess.forEach(
// Iterate of the "roles" claim inside the resource claims (resource, resourceClaims) -> {
resourceClaims.get(CLAIM_ROLES).forEach( // Iterate of the "roles" claim inside the resource claims
// Add the role to the granted authority prefixed with ROLE_ and the name of the resource resourceClaims
role -> grantedAuthorities.add(new SimpleGrantedAuthority(PREFIX_RESOURCE_ROLE + resource + "_" + role)) .get(CLAIM_ROLES)
); .forEach(
}); // Add the role to the granted authority prefixed with ROLE_
// and the name of the resource
role ->
grantedAuthorities.add(
new SimpleGrantedAuthority(
PREFIX_RESOURCE_ROLE
+ resource
+ "_"
+ role)));
});
} }
return grantedAuthorities; return grantedAuthorities;
} }
} }