added keycloak
This commit is contained in:
19
pom.xml
19
pom.xml
@@ -37,7 +37,24 @@
|
|||||||
<artifactId>postgresql</artifactId>
|
<artifactId>postgresql</artifactId>
|
||||||
<version>42.7.3</version>
|
<version>42.7.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package de.anxietyprime.swajodel.security;
|
||||||
|
|
||||||
|
import org.springframework.core.convert.converter.Converter;
|
||||||
|
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.jwt.JwtClaimNames;
|
||||||
|
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
||||||
|
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class JwtConverter implements Converter<Jwt, AbstractAuthenticationToken> {
|
||||||
|
|
||||||
|
private final JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
|
||||||
|
|
||||||
|
private final JwtConverterProperties properties;
|
||||||
|
|
||||||
|
public JwtConverter(JwtConverterProperties properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AbstractAuthenticationToken convert(Jwt jwt) {
|
||||||
|
Collection<GrantedAuthority> authorities = Stream.concat(
|
||||||
|
jwtGrantedAuthoritiesConverter.convert(jwt).stream(),
|
||||||
|
extractResourceRoles(jwt).stream()).collect(Collectors.toSet());
|
||||||
|
return new JwtAuthenticationToken(jwt, authorities, getPrincipalClaimName(jwt));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getPrincipalClaimName(Jwt jwt) {
|
||||||
|
String claimName = JwtClaimNames.SUB;
|
||||||
|
if (properties.getPrincipalAttribute() != null) {
|
||||||
|
claimName = properties.getPrincipalAttribute();
|
||||||
|
}
|
||||||
|
return jwt.getClaim(claimName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Collection<? extends GrantedAuthority> extractResourceRoles(Jwt jwt) {
|
||||||
|
Map<String, Object> resourceAccess = jwt.getClaim("resource_access");
|
||||||
|
Map<String, Object> resource;
|
||||||
|
Collection<String> resourceRoles;
|
||||||
|
|
||||||
|
if (resourceAccess == null
|
||||||
|
|| (resource = (Map<String, Object>) resourceAccess.get(properties.getResourceId())) == null
|
||||||
|
|| (resourceRoles = (Collection<String>) resource.get("roles")) == null) {
|
||||||
|
return Set.of();
|
||||||
|
}
|
||||||
|
return resourceRoles.stream()
|
||||||
|
.map(role -> new SimpleGrantedAuthority("ROLE_" + role))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package de.anxietyprime.swajodel.security;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Validated
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "jwt.auth.converter")
|
||||||
|
|
||||||
|
|
||||||
|
public class JwtConverterProperties {
|
||||||
|
|
||||||
|
private String resourceId;
|
||||||
|
private String principalAttribute;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package de.anxietyprime.swajodel.security;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
public class SecurityConfig {
|
||||||
|
|
||||||
|
public static final String ADMIN = "admin";
|
||||||
|
public static final String USER = "user";
|
||||||
|
private final JwtConverter jwtConverter;
|
||||||
|
@Bean
|
||||||
|
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||||
|
http.authorizeHttpRequests((authz) ->
|
||||||
|
authz.requestMatchers(HttpMethod.GET, "/messages/").permitAll()
|
||||||
|
.anyRequest().authenticated());
|
||||||
|
|
||||||
|
http.sessionManagement(sess -> sess.sessionCreationPolicy(
|
||||||
|
SessionCreationPolicy.STATELESS));
|
||||||
|
http.oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtConverter)));
|
||||||
|
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1 +1,5 @@
|
|||||||
spring.application.name=SWA-Jodel
|
spring.application.name=SWA-Jodel
|
||||||
|
|
||||||
|
# Security Configuration
|
||||||
|
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://keycloak.anxietyprime.de/realms/Jodel
|
||||||
|
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=${spring.security.oauth2.resourceserver.jwt.issuer-uri}/protocol/openid-connect/certs
|
||||||
|
|||||||
Reference in New Issue
Block a user