Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more hints for map properties config #27665

Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public class AadAuthenticationProperties implements InitializingBean {
/**
* Add additional parameters to the Authorization URL.
*/
private Map<String, Object> authenticateAdditionalParameters;
private final Map<String, Object> authenticateAdditionalParameters = new HashMap<>();

/**
* Connection Timeout for the JWKSet Remote URL call.
Expand Down Expand Up @@ -116,7 +116,7 @@ public class AadAuthenticationProperties implements InitializingBean {
/**
* The OAuth2 authorization clients.
*/
private Map<String, AuthorizationClientProperties> authorizationClients = new HashMap<>();
private final Map<String, AuthorizationClientProperties> authorizationClients = new HashMap<>();

/**
* Type of the AAD application.
Expand Down Expand Up @@ -320,15 +320,6 @@ public Map<String, Object> getAuthenticateAdditionalParameters() {
return authenticateAdditionalParameters;
}

/**
* Sets the additional authenticate parameters.
*
* @param authenticateAdditionalParameters the additional authenticate parameters
*/
public void setAuthenticateAdditionalParameters(Map<String, Object> authenticateAdditionalParameters) {
this.authenticateAdditionalParameters = authenticateAdditionalParameters;
}

/**
* Gets the JWT connect timeout.
*
Expand Down Expand Up @@ -475,15 +466,6 @@ public Map<String, AuthorizationClientProperties> getAuthorizationClients() {
return authorizationClients;
}

/**
* Sets the authorization clients.
*
* @param authorizationClients the authorization clients
*/
public void setAuthorizationClients(Map<String, AuthorizationClientProperties> authorizationClients) {
this.authorizationClients = authorizationClients;
}

/**
* Whether the group is allowed.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public class AadB2cProperties implements InitializingBean {
/**
* Additional parameters for authentication.
*/
private Map<String, Object> authenticateAdditionalParameters;
private final Map<String, Object> authenticateAdditionalParameters = new HashMap<>();

/**
* User name attribute name.
Expand Down Expand Up @@ -111,7 +111,7 @@ public class AadB2cProperties implements InitializingBean {
/**
* Specify client configuration.
*/
private Map<String, AuthorizationClientProperties> authorizationClients = new HashMap<>();
private final Map<String, AuthorizationClientProperties> authorizationClients = new HashMap<>();

@Override
public void afterPropertiesSet() {
Expand Down Expand Up @@ -283,15 +283,6 @@ public Map<String, Object> getAuthenticateAdditionalParameters() {
return authenticateAdditionalParameters;
}

/**
* Sets the additional authenticate parameters.
*
* @param authenticateAdditionalParameters the additional authenticate parameters
*/
public void setAuthenticateAdditionalParameters(Map<String, Object> authenticateAdditionalParameters) {
this.authenticateAdditionalParameters = authenticateAdditionalParameters;
}

/**
* Gets the username attribute name.
*
Expand Down Expand Up @@ -417,13 +408,4 @@ public AadB2cProfileProperties getProfile() {
public Map<String, AuthorizationClientProperties> getAuthorizationClients() {
return authorizationClients;
}

/**
* Sets the authorization clients.
*
* @param authorizationClients the authorization clients
*/
public void setAuthorizationClients(Map<String, AuthorizationClientProperties> authorizationClients) {
this.authorizationClients = authorizationClients;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.util.CollectionUtils;

import java.time.Duration;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.azure.spring.cloud.service.implementation.core.PropertiesValidator.validateNamespace;

/**
* Azure Event Hubs related properties.
*/
Expand Down Expand Up @@ -108,7 +108,14 @@ public Processor buildProcessorProperties() {
propertyMapper.from(this.processor.getConsumerGroup()).to(properties::setConsumerGroup);

propertyMapper.from(this.processor.trackLastEnqueuedEventProperties).to(properties::setTrackLastEnqueuedEventProperties);
propertyMapper.from(this.processor.initialPartitionEventPosition).to(properties::setInitialPartitionEventPosition);
propertyMapper.from(this.processor.initialPartitionEventPosition).when(c -> !CollectionUtils.isEmpty(c))
.to(m -> {
Map<String, Processor.StartPosition> eventPositionMap = m.entrySet()
.stream()
.filter(entry -> entry.getValue() != null)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
properties.getInitialPartitionEventPosition().putAll(eventPositionMap);
});
propertyMapper.from(this.processor.batch.getMaxSize()).to(properties.batch::setMaxSize);
propertyMapper.from(this.processor.batch.getMaxWaitTime()).to(properties.batch::setMaxWaitTime);
propertyMapper.from(this.processor.loadBalancing.getStrategy()).to(properties.loadBalancing::setStrategy);
Expand Down Expand Up @@ -194,7 +201,7 @@ public static class Processor extends Consumer implements EventProcessorClientPr
* Map event position to use for each partition if a checkpoint for the partition does not exist in
* CheckpointStore.
*/
private Map<String, StartPosition> initialPartitionEventPosition = new HashMap<>();
private final Map<String, StartPosition> initialPartitionEventPosition = new HashMap<>();
saragluna marked this conversation as resolved.
Show resolved Hide resolved

private final EventBatch batch = new EventBatch();
private final LoadBalancing loadBalancing = new LoadBalancing();
Expand All @@ -212,10 +219,6 @@ public Map<String, StartPosition> getInitialPartitionEventPosition() {
return initialPartitionEventPosition;
}

public void setInitialPartitionEventPosition(Map<String, StartPosition> initialPartitionEventPosition) {
this.initialPartitionEventPosition = initialPartitionEventPosition;
}

public EventBatch getBatch() {
return batch;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -984,5 +984,69 @@
"name": "spring.jms.servicebus.pool.use-anonymous-producers",
"description": "Whether to use only one anonymous 'MessageProducer' instance. Set it to false to create one 'MessageProducer' every time one is required."
}
],
"hints": [
{
"name": "spring.cloud.azure.active-directory.resource-server.claim-to-authority-prefix-map.keys",
"values": [
{
"value": "scp",
"description": "The prefix for the authority started with 'SCOPE_'."
},
{
"value": "roles",
"description": "The prefix for the authority started with 'APPROLE_'."
}
],
"providers": [
{
"name": "any"
}
]
},
{
"name": "spring.cloud.azure.active-directory.authenticate-additional-parameters.keys",
"values": [
{
"value": "domain_hint",
"description": "If included, the app skips the email-based discovery process that user goes through on the sign-in page, leading to a slightly more streamlined user experience."
},
{
"value": "login_hint",
"description": "You can use this parameter to pre-fill the username and email address field of the sign-in page for the user."
},
{
"value": "prompt",
"description": "Indicates the type of user interaction that is required. Valid values are login, none, consent, and select_account."
}
],
"providers": [
{
"name": "any"
}
]
},
{
"name": "spring.cloud.azure.active-directory.b2c.authenticate-additional-parameters.keys",
"values": [
{
"value": "domain_hint",
"description": "If included, the app skips the email-based discovery process that user goes through on the sign-in page, leading to a slightly more streamlined user experience."
},
{
"value": "login_hint",
"description": "You can use this parameter to pre-fill the username and email address field of the sign-in page for the user."
},
{
"value": "prompt",
"description": "Indicates the type of user interaction that is required. Valid values are login, none, consent, and select_account."
}
],
"providers": [
{
"name": "any"
}
]
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,42 @@

import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.Map;

import static com.azure.spring.cloud.autoconfigure.aad.implementation.WebApplicationContextRunnerUtils.oauthClientRunner;
import static com.azure.spring.cloud.autoconfigure.aad.implementation.WebApplicationContextRunnerUtils.resourceServerContextRunner;
import static com.azure.spring.cloud.autoconfigure.aad.implementation.WebApplicationContextRunnerUtils.resourceServerWithOboContextRunner;
import static com.azure.spring.cloud.autoconfigure.aad.implementation.WebApplicationContextRunnerUtils.webApplicationContextRunner;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

class AadAuthenticationPropertiesTests {

@Test
void mapPropertiesSetting() {
webApplicationContextRunner()
.withPropertyValues(
"spring.cloud.azure.active-directory.authorization-clients.test.authorizationGrantType = authorization_code",
"spring.cloud.azure.active-directory.authorization-clients.test.scopes = test1,test2",
"spring.cloud.azure.active-directory.authenticate-additional-parameters.prompt = login"
)
.run(context -> {
AadAuthenticationProperties properties = context.getBean(AadAuthenticationProperties.class);

Map<String, AuthorizationClientProperties> authorizationClients = properties.getAuthorizationClients();
assertTrue(authorizationClients.containsKey("test"));
assertTrue(authorizationClients.get("test").getScopes().containsAll(Arrays.asList("test1", "test2")));
assertEquals(authorizationClients.get("test").getAuthorizationGrantType(), AadAuthorizationGrantType.AUTHORIZATION_CODE);

Map<String, Object> authenticateAdditionalParameters = properties.getAuthenticateAdditionalParameters();
assertEquals(authenticateAdditionalParameters.size(), 1);
assertTrue(authenticateAdditionalParameters.containsKey("prompt"));
assertEquals(authenticateAdditionalParameters.get("prompt"), "login");
});
}

@Test
void webAppWithOboWithExceptionTest() {
webApplicationContextRunner()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
// Licensed under the MIT License.
package com.azure.spring.cloud.autoconfigure.aadb2c.implementation;

import com.azure.spring.cloud.autoconfigure.aad.properties.AadAuthorizationGrantType;
import com.azure.spring.cloud.autoconfigure.aadb2c.AadB2cAuthorizationRequestResolver;
import com.azure.spring.cloud.autoconfigure.aadb2c.AadB2cLogoutSuccessHandler;
import com.azure.spring.cloud.autoconfigure.aadb2c.AadB2cAutoConfiguration;
import com.azure.spring.cloud.autoconfigure.aadb2c.properties.AadB2cProperties;
import com.azure.spring.cloud.autoconfigure.aadb2c.AadB2cResourceServerAutoConfiguration;
import com.azure.spring.cloud.autoconfigure.aadb2c.properties.AuthorizationClientProperties;
import com.azure.spring.cloud.autoconfigure.context.AzureGlobalPropertiesAutoConfiguration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
Expand All @@ -25,6 +27,7 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
Expand All @@ -37,6 +40,31 @@ class AadB2cAutoConfigurationTests extends AbstractAadB2cOAuth2ClientTestConfigu

private static final String SERVLET_WEB_APPLICATION_CLASS = "org.springframework.web.context.support.GenericWebApplicationContext";

@Test
void mapPropertiesSetting() {
getDefaultContextRunner()
.withPropertyValues(
"spring.cloud.azure.active-directory.b2c.enabled=true",
"spring.cloud.azure.active-directory.b2c.authorization-clients.test.authorizationGrantType = client_credentials",
"spring.cloud.azure.active-directory.b2c.authorization-clients.test.scopes = test1,test2"
)
.run(context -> {
AadB2cProperties properties = context.getBean(AadB2cProperties.class);

Map<String, AuthorizationClientProperties> authorizationClients = properties.getAuthorizationClients();
assertTrue(authorizationClients.containsKey("test"));
assertTrue(authorizationClients.get("test").getScopes().containsAll(Arrays.asList("test1", "test2")));
assertEquals(authorizationClients.get("test").getAuthorizationGrantType(), AadAuthorizationGrantType.CLIENT_CREDENTIALS);

Map<String, Object> authenticateAdditionalParameters = properties.getAuthenticateAdditionalParameters();
assertEquals(authenticateAdditionalParameters.size(), 2);
assertTrue(authenticateAdditionalParameters.containsKey("login-hint"));
assertTrue(authenticateAdditionalParameters.containsKey("prompt"));
assertEquals(authenticateAdditionalParameters.get("login-hint"), AadB2cConstants.TEST_LOGIN_HINT);
assertEquals(authenticateAdditionalParameters.get("prompt"), AadB2cConstants.TEST_PROMPT);
});
}

@Override
WebApplicationContextRunner getDefaultContextRunner() {
return new WebApplicationContextRunner()
Expand Down