1.1.55.1. fejezet, SpringBoot3 JWT integráció
Beküldte pzoli - 2024, október 6 - 7:56du
JWT alapú konfiguráció
SecurityConfig
package hu.infokristaly.keycloakauthenticatoin.security; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 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.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity @EnableMethodSecurity public class SecurityConfig { @Autowired private JwtAuthConverter jwtAuthenticationConverter; @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.csrf(t->t.disable()); http.authorizeRequests(authorize->{ authorize .requestMatchers(HttpMethod.GET,"/client/public/list").permitAll() // GET kérés azonosító nélkül elérhető .anyRequest().authenticated(); }); http.oauth2ResourceServer(t->{ t.jwt(configure -> configure.jwtAuthenticationConverter(jwtAuthenticationConverter)); }); http.sessionManagement(t->{ t.sessionCreationPolicy(SessionCreationPolicy.STATELESS); }); return http.build(); } }
Egyedi JwtAuthConverter
package hu.infokristaly.keycloakauthenticatoin.security; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; import org.springframework.stereotype.Component; import org.springframework.core.convert.converter.Converter; import java.util.*; @Component public class JwtAuthConverter implements Converter<Jwt, AbstractAuthenticationToken> { @Override public AbstractAuthenticationToken convert(Jwt jwt) { Collection<GrantedAuthority> roles = extractAuthorities(jwt); return new JwtAuthenticationToken(jwt, roles); } private Collection<GrantedAuthority> extractAuthorities(Jwt jwt) { if(jwt.getClaims().containsKey("resource_access")) { Map<String, Object> resourceAccess = jwt.getClaim("resource_access"); Map<String, Object> client = (Map<String, Object>) resourceAccess.get("forras-admin"); ObjectMapper mapper = new ObjectMapper(); List<String> keycloakRoles = mapper.convertValue(client.get("roles"), new TypeReference<List<String>>(){}); List<GrantedAuthority> roles = new ArrayList<>(); for(String keycloakRole : keycloakRoles) { roles.add(new SimpleGrantedAuthority(keycloakRole.toUpperCase(Locale.ROOT))); } return roles; } return new ArrayList<>(); } }
Beépített JwtAuthenticationConverter konfigurálása
Ehhez Client scope-ot kell felvenni (Client scopes/ create (name = roles), [roles client scope] / mappers / Configure new mapper / User Client Role (name = roles, Token Claim Name = roles))
package hu.infokristaly.keycloakauthenticatoin.security; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter; import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity @EnableMethodSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.csrf(t->t.disable()); http.authorizeRequests(authorize->{ authorize .anyRequest().authenticated(); }); http.oauth2ResourceServer(t->{ t.jwt(Customizer.withDefaults()); }); http.sessionManagement(t->{ t.sessionCreationPolicy(SessionCreationPolicy.STATELESS); }); return http.build(); } @Bean public DefaultMethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler() { DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler(); expressionHandler.setDefaultRolePrefix(""); return expressionHandler; } @Bean public JwtAuthenticationConverter jwtAuthenticationConverter() { JwtAuthenticationConverter c = new JwtAuthenticationConverter(); JwtGrantedAuthoritiesConverter cv = new JwtGrantedAuthoritiesConverter(); cv.setAuthorityPrefix(""); cv.setAuthoritiesClaimName("roles"); c.setJwtGrantedAuthoritiesConverter(cv); return c; } }
MethodSecurity
package hu.infokristaly.keycloakauthenticatoin.controller; import hu.infokristaly.keycloakauthenticatoin.entity.Doctor; import hu.infokristaly.keycloakauthenticatoin.repository.DoctorRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController @RequestMapping("/doctor") public class DoctorController { @Autowired DoctorRepository doctorRepository; @GetMapping("/list") @PreAuthorize("hasRole('USER') or hasRole('MANAGER')") public List<Doctor> getAllDoctors() { return doctorRepository.findAll(); } }
UserController
@RestController @RequestMapping("/user") public class UserController { @GetMapping(path = "/info") public HashMap index() { Jwt user = (Jwt)SecurityContextHolder.getContext().getAuthentication().getPrincipal(); return new HashMap(){{ put("hello", user.getClaimAsStringList("name")); put("your email is", user.getClaimAsStringList("email")); }}; } }
application.properties beállítások
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://server.me.local:8080/realms/infokristaly
- A hozzászóláshoz be kell jelentkezni