package de.towerdefence.server.auth; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.core.oidc.user.OidcUser; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; import org.springframework.security.web.authentication.logout.LogoutHandler; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; import java.util.ArrayList; import java.util.List; import java.util.Map; @Component public class JWT implements LogoutHandler { private static final String REALM_ACCESS_CLAIM = "realm_access"; private static final String ROLES_CLAIM = "roles"; private static final String ROLE_PREFIX = "ROLE_"; private static final String OIDC_LOGOUT_ROUTE = "/protocol/openid-connect/logout"; private static final String OIDC_TOKEN_HINT_QUERY_PARAMETER = "id_token_hin"; @Autowired private RestTemplate template; @Override public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { OidcUser user = (OidcUser) authentication.getPrincipal(); String endSessionEndpoint = user.getIssuer() + OIDC_LOGOUT_ROUTE; UriComponentsBuilder builder = UriComponentsBuilder .fromUriString(endSessionEndpoint) .queryParam(OIDC_TOKEN_HINT_QUERY_PARAMETER, user.getIdToken().getTokenValue()); ResponseEntity logoutResponse = template.getForEntity(builder.toUriString(), String.class); if (logoutResponse.getStatusCode().is2xxSuccessful()) { System.out.println("Logged out successfully"); } else { System.out.println("Failed to logout"); } } public JwtAuthenticationConverter jwtAuthenticationConverter() { JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter(); jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwt -> { List grantedAuthorities = new ArrayList<>(); Map realmAccess = jwt.getClaim(REALM_ACCESS_CLAIM); if (realmAccess == null || !realmAccess.containsKey(ROLES_CLAIM)) { return grantedAuthorities; } Object rolesClaim = realmAccess.get(ROLES_CLAIM); if (!(rolesClaim instanceof List)) { return grantedAuthorities; } for (Object role : (List) rolesClaim) { assert role instanceof String; grantedAuthorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + role)); } return grantedAuthorities; }); return jwtAuthenticationConverter; } }