All Downloads are FREE. Search and download functionalities are using the official Maven repository.

entry-point.rest-webflux.authorization.authorization-jwt.mustache Maven / Gradle / Ivy

Go to download

Gradle plugin to create a clean application in Java that already works, It follows our best practices!

There is a newer version: 3.20.10
Show newest version
package {{package}}.api.config;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtClaimValidator;
import org.springframework.security.oauth2.jwt.JwtValidators;
import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder;
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.ReactiveJwtAuthenticationConverterAdapter;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.web.reactive.config.WebFluxConfigurer;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
{{^lombok}}
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
{{/lombok}}
{{#lombok}}
import lombok.extern.log4j.Log4j2;
{{/lombok}}

{{#lombok}}
@Log4j2
{{/lombok}}
@Configuration
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class AuthorizationJwt implements WebFluxConfigurer {

    {{^lombok}}
    private static final Logger log = LogManager.getLogger(AuthorizationJwt.class);
    {{/lombok}}
    private final String issuerUri;
    private final String clientId;
    private final String jsonExpRoles;

    private final ObjectMapper mapper;
    private static final String ROLE = "ROLE_";
    private static final String AZP = "azp";

    public AuthorizationJwt(@Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}") String issuerUri,
                         @Value("${spring.security.oauth2.resourceserver.jwt.client-id}") String clientId,
                         @Value("${jwt.json-exp-roles}") String jsonExpRoles,
                         ObjectMapper mapper) {
        this.issuerUri = issuerUri;
        this.clientId = clientId;
        this.jsonExpRoles = jsonExpRoles;
        this.mapper = mapper;
    }

    @Bean
    public SecurityWebFilterChain filterChain(ServerHttpSecurity http) {
        http
            .authorizeExchange(authorize -> authorize.anyExchange().authenticated())
            .oauth2ResourceServer(oauth2 ->
                    oauth2.jwt(jwtSpec ->
                            jwtSpec
                            .jwtDecoder(jwtDecoder())
                            .jwtAuthenticationConverter(grantedAuthoritiesExtractor())
                    )
            );
        return http.build();
    }

    public ReactiveJwtDecoder jwtDecoder() {
        var defaultValidator = JwtValidators.createDefaultWithIssuer(issuerUri);
        var audienceValidator = new JwtClaimValidator(AZP,
                azp -> azp != null && !azp.isEmpty() && azp.equals(clientId));
        var tokenValidator = new DelegatingOAuth2TokenValidator<>(defaultValidator, audienceValidator);
        var jwtDecoder = NimbusReactiveJwtDecoder
                .withIssuerLocation(issuerUri)
                .build();

        jwtDecoder.setJwtValidator(tokenValidator);
        return jwtDecoder;
    }

    public Converter> grantedAuthoritiesExtractor() {
        var jwtConverter = new JwtAuthenticationConverter();
        jwtConverter.setJwtGrantedAuthoritiesConverter(jwt ->
                getRoles(jwt.getClaims(), jsonExpRoles)
                .stream()
                .map(ROLE::concat)
                .map(SimpleGrantedAuthority::new)
                .collect(Collectors.toList()));
        return new ReactiveJwtAuthenticationConverterAdapter(jwtConverter);
    }

    private List getRoles(Map claims, String jsonExpClaim){
        List roles = List.of();
        try {
            var json = mapper.writeValueAsString(claims);
            var chunk = mapper.readTree(json).at(jsonExpClaim);
            return mapper.readerFor(new TypeReference>() {})
                    .readValue(chunk);
        } catch (IOException e) {
            log.error(e.getMessage());
            return roles;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy