Fixing API access through external APPs
This commit is contained in:
parent
d06aa74029
commit
f62cfbfb66
4 changed files with 57 additions and 19 deletions
|
|
@ -47,10 +47,7 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
|||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
||||
|
|
@ -65,6 +62,7 @@ public class SecurityConfig {
|
|||
@Value("${lcc.allowed_oauth_token_cors:*}") // Default: alle Origins
|
||||
private String oauthTokenCors;
|
||||
|
||||
|
||||
@Bean
|
||||
@Profile("!dev & !test") // Only active when NOT in dev profile
|
||||
public SecurityFilterChain prodSecurityFilterChain(HttpSecurity http, JwtTokenService jwtTokenService) throws Exception {
|
||||
|
|
@ -251,7 +249,25 @@ public class SecurityConfig {
|
|||
|
||||
User user = null;
|
||||
|
||||
String workdayId = oidcUser.getAttribute("workday_id");
|
||||
String workdayId = oidcUser.getAttribute("employeeid");
|
||||
if (workdayId == null) {
|
||||
workdayId = oidcUser.getAttribute("extension_WorkdayID");
|
||||
}
|
||||
if (workdayId == null) {
|
||||
workdayId = oidcUser.getAttribute("workdayWorkerID");
|
||||
}
|
||||
if (workdayId == null) {
|
||||
workdayId = oidcUser.getAttribute("onpremisesimmutableid");
|
||||
}
|
||||
if (workdayId == null) {
|
||||
// Check for any extension attribute containing "workday"
|
||||
Map<String, Object> claims = oidcUser.getIdToken().getClaims();
|
||||
workdayId = claims.entrySet().stream()
|
||||
.filter(e -> e.getKey().toLowerCase().contains("workday"))
|
||||
.map(e -> String.valueOf(e.getValue()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
// Try different ways to get email
|
||||
String email = oidcUser.getEmail();
|
||||
|
|
@ -269,7 +285,7 @@ public class SecurityConfig {
|
|||
if (workdayId != null) {
|
||||
user = userRepository.getByWorkdayId(workdayId);
|
||||
if (user != null) {
|
||||
user.getGroups().forEach(group -> mappedAuthorities.add(new SimpleGrantedAuthority("ROLE_" + group.getName())));
|
||||
user.getGroups().forEach(group -> mappedAuthorities.add(new SimpleGrantedAuthority("ROLE_" + group.getName().toUpperCase())));
|
||||
userId = user.getId();
|
||||
}
|
||||
} else if (email != null) {
|
||||
|
|
@ -311,15 +327,15 @@ public class SecurityConfig {
|
|||
Claims claims = jwtTokenService.parseClaimsWithoutValidation(token);
|
||||
String tokenType = claims.get("token_type", String.class);
|
||||
if ("ext_app".equals(tokenType)) {
|
||||
return null; // using the SelfIssuedJwtFilter
|
||||
return null;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// carry on ...
|
||||
log.debug("Failed to parse token without validation", e);
|
||||
}
|
||||
|
||||
return token; // some other token
|
||||
return token;
|
||||
}
|
||||
return null; // all other requests
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -345,10 +361,13 @@ public class SecurityConfig {
|
|||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, @NotNull HttpServletResponse response,
|
||||
@NotNull FilterChain filterChain) throws ServletException, IOException {
|
||||
// Skip CSRF cookie for token endpoint
|
||||
if (!request.getRequestURI().startsWith("/oauth2/token")) {
|
||||
CsrfToken csrfToken = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
|
||||
if (csrfToken != null) {
|
||||
csrfToken.getToken();
|
||||
}
|
||||
}
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,11 @@ public class SelfIssuedJwtFilter extends OncePerRequestFilter {
|
|||
@NotNull FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
|
||||
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
String token = extractToken(request);
|
||||
|
||||
if (token != null && isSelfIssuedToken(token)) {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ public class GroupController {
|
|||
* @return A ResponseEntity containing the list of groups and pagination headers.
|
||||
*/
|
||||
@GetMapping({"/", ""})
|
||||
@PreAuthorize("hasAnyRole('RIGHT-MANAGMENT', 'SERVICE')")
|
||||
@PreAuthorize("hasAnyRole('RIGHT-MANAGEMENT', 'SERVICE')")
|
||||
public ResponseEntity<List<GroupDTO>> listGroups(@RequestParam(defaultValue = "20") @Min(1) int limit,
|
||||
@RequestParam(defaultValue = "1") @Min(1) int page) {
|
||||
|
||||
|
|
|
|||
|
|
@ -41,11 +41,25 @@ public class JwtTokenService {
|
|||
}
|
||||
|
||||
public Claims parseClaimsWithoutValidation(String token) {
|
||||
return Jwts.parser()
|
||||
.unsecured()
|
||||
.build()
|
||||
.parseUnsecuredClaims(token)
|
||||
.getPayload();
|
||||
try {
|
||||
String[] parts = token.split("\\.");
|
||||
|
||||
String payload = parts[1];
|
||||
byte[] decodedBytes = java.util.Base64.getUrlDecoder().decode(payload);
|
||||
String decodedPayload = new String(decodedBytes, StandardCharsets.UTF_8);
|
||||
|
||||
com.fasterxml.jackson.databind.ObjectMapper mapper =
|
||||
new com.fasterxml.jackson.databind.ObjectMapper();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
java.util.Map<String, Object> claimsMap =
|
||||
mapper.readValue(decodedPayload, java.util.Map.class);
|
||||
|
||||
return Jwts.claims().add(claimsMap).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("Failed to parse JWT claims", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Claims validateToken(String token) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue