package de.szut.lf8_starter.security; import java.util.*; import java.util.stream.Collectors; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.http.HttpMethod; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; import org.springframework.security.core.session.SessionRegistry; import org.springframework.security.core.session.SessionRegistryImpl; import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority; import org.springframework.security.oauth2.core.user.OAuth2UserAuthority; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; import org.springframework.security.web.session.HttpSessionEventPublisher; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @Configuration @EnableWebSecurity class KeycloakSecurityConfig { private static final String GROUPS = "groups"; private static final String REALM_ACCESS_CLAIM = "realm_access"; private static final String ROLES_CLAIM = "roles"; private final KeycloakLogoutHandler keycloakLogoutHandler; KeycloakSecurityConfig(KeycloakLogoutHandler keycloakLogoutHandler) { this.keycloakLogoutHandler = keycloakLogoutHandler; } @Bean public SessionRegistry sessionRegistry() { return new SessionRegistryImpl(); } @Bean protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { return new RegisterSessionAuthenticationStrategy(sessionRegistry()); } @Bean public HttpSessionEventPublisher httpSessionEventPublisher() { return new HttpSessionEventPublisher(); } @Bean public SecurityFilterChain resourceServerFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(auth -> auth .requestMatchers(new AntPathRequestMatcher("/welcome")) .permitAll() .requestMatchers( new AntPathRequestMatcher("/swagger"), new AntPathRequestMatcher("/swagger-ui/**"), new AntPathRequestMatcher("/v3/api-docs/**")) .permitAll() .requestMatchers(new AntPathRequestMatcher("/hello/**")) .hasRole("user") .requestMatchers(new AntPathRequestMatcher("/roles")) .authenticated() .requestMatchers(new AntPathRequestMatcher("/")) .permitAll() .anyRequest() .authenticated()).oauth2ResourceServer(spec -> spec.jwt(Customizer.withDefaults())); return http.build(); } @Bean 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)) { List roles = (List) realmAccess.get(ROLES_CLAIM); for (String role : roles) { grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_" + role)); } } return grantedAuthorities; }); return jwtAuthenticationConverter; } }