AADAuthenticationFilterAutoConfiguration.java
Publish date: 2024-06-17
AADAuthenticationFilterAutoConfiguration.java// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. package com.azure.spring.autoconfigure.aad; import com.azure.spring.telemetry.TelemetrySender; import com.nimbusds.jose.jwk.source.DefaultJWKSetCache; import com.nimbusds.jose.jwk.source.JWKSetCache; import com.nimbusds.jose.util.DefaultResourceRetriever; import com.nimbusds.jose.util.ResourceRetriever; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnResource; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.util.ClassUtils; import javax.annotation.PostConstruct; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; import static com.azure.spring.telemetry.TelemetryData.SERVICE_NAME; import static com.azure.spring.telemetry.TelemetryData.getClassPackageSimpleName; /** * {@link EnableAutoConfiguration Auto-configuration} for Azure Active Authentication filters. * <p> * The configuration will not be activated if no {@literal azure.activedirectory.client-id} property provided. * <p> * A stateless filter {@link AADAppRoleStatelessAuthenticationFilter} will be auto-configured by specifying {@literal * azure.activedirectory.session-stateless=true}. Otherwise, {@link AADAuthenticationFilter} will be configured. */ @Configuration @ConditionalOnWebApplication @ConditionalOnResource(resources = "classpath:aad.enable.config") @ConditionalOnProperty(prefix = AADAuthenticationFilterAutoConfiguration.PROPERTY_PREFIX, value = { "client-id" }) @EnableConfigurationProperties({ AADAuthenticationProperties.class, ServiceEndpointsProperties.class }) @PropertySource(value = "classpath:service-endpoints.properties") public class AADAuthenticationFilterAutoConfiguration { public static final String PROPERTY_PREFIX = "azure.activedirectory"; private static final Logger LOG = LoggerFactory.getLogger(AADAuthenticationProperties.class); private final AADAuthenticationProperties aadAuthenticationProperties; private final ServiceEndpointsProperties serviceEndpointsProperties; public AADAuthenticationFilterAutoConfiguration(AADAuthenticationProperties aadAuthenticationProperties, ServiceEndpointsProperties serviceEndpointsProperties) { this.aadAuthenticationProperties = aadAuthenticationProperties; this.serviceEndpointsProperties = serviceEndpointsProperties; } /** * Declare AADAuthenticationFilter bean. * * @return AADAuthenticationFilter bean */ @Bean @ConditionalOnMissingBean(AADAuthenticationFilter.class) @ConditionalOnExpression("${azure.activedirectory.session-stateless:false} == false") // client-id and client-secret used to: get graphApiToken -> groups @ConditionalOnProperty(prefix = PROPERTY_PREFIX, value = { "client-id", "client-secret" }) public AADAuthenticationFilter azureADJwtTokenFilter() { LOG.info("AzureADJwtTokenFilter Constructor."); return new AADAuthenticationFilter( aadAuthenticationProperties, serviceEndpointsProperties, getJWTResourceRetriever(), getJWKSetCache() ); } @Bean @ConditionalOnMissingBean(AADAppRoleStatelessAuthenticationFilter.class) @ConditionalOnExpression("${azure.activedirectory.session-stateless:false} == true") // client-id used to: userPrincipalManager.getValidator @ConditionalOnProperty(prefix = PROPERTY_PREFIX, value = { "client-id" }) public AADAppRoleStatelessAuthenticationFilter azureADStatelessAuthFilter(ResourceRetriever resourceRetriever) { LOG.info("Creating AzureADStatelessAuthFilter bean."); return new AADAppRoleStatelessAuthenticationFilter( new UserPrincipalManager( serviceEndpointsProperties, aadAuthenticationProperties, resourceRetriever, true ) ); } @Bean @ConditionalOnMissingBean(ResourceRetriever.class) public ResourceRetriever getJWTResourceRetriever() { return new DefaultResourceRetriever( aadAuthenticationProperties.getJwtConnectTimeout(), aadAuthenticationProperties.getJwtReadTimeout(), aadAuthenticationProperties.getJwtSizeLimit() ); } @Bean @ConditionalOnMissingBean(JWKSetCache.class) public JWKSetCache getJWKSetCache() { long lifespan = aadAuthenticationProperties.getJwkSetCacheLifespan(); long refreshTime = aadAuthenticationProperties.getJwkSetCacheRefreshTime(); return new DefaultJWKSetCache(lifespan, refreshTime, TimeUnit.MILLISECONDS); } @PostConstruct private void sendTelemetry() { if (aadAuthenticationProperties.isAllowTelemetry()) { final Map<String, String> events = new HashMap<>(); final TelemetrySender sender = new TelemetrySender(); events.put(SERVICE_NAME, getClassPackageSimpleName(AADAuthenticationFilterAutoConfiguration.class)); sender.send(ClassUtils.getUserClass(getClass()).getSimpleName(), events); } } } ncG1vNJzZmiZqqq%2Fpr%2FDpJirrJmbrqTA0meZpaeSY7CwvsRnrqKmlKTEtHrNnqtomaqqv6Z50p2iZp6fp3qrrdWaZq2do6l6pLvVnqman5VkrrvB0Z5krKiinruoecGopq1nk6S6b63ZrqmeZqOlv6q6xmeYrqyfmLyvssigrKudXpaupXugent6raSdsq%2FAyJyYraGfo5OquNOeqXqtpKSQsLrFop6uqpGptrC6jaOYr5lencGuuA%3D%3D