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

implement aad authn and authz #17325

Merged
merged 12 commits into from
Nov 11, 2020
9 changes: 9 additions & 0 deletions sdk/spring/azure-spring-boot-test-aad/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
</dependencies>

<properties>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
package com.azure.test.aad.auth;

import com.azure.spring.aad.implementation.AzureClientRegistrationRepository;
import com.azure.spring.aad.implementation.DefaultClient;
import com.azure.spring.aad.implementation.IdentityEndpoints;
import com.azure.test.utils.AppRunner;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;

import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class AppAutoConfigTest {

@Test
public void clientRegistered() {
try (AppRunner appRunner = createApp()) {
appRunner.start();

ClientRegistrationRepository clientRegistrationRepository =
appRunner.getBean(ClientRegistrationRepository.class);
ClientRegistration azureClientRegistration = clientRegistrationRepository.findByRegistrationId("azure");

assertNotNull(azureClientRegistration);
assertEquals("fake-client-id", azureClientRegistration.getClientId());
assertEquals("fake-client-secret", azureClientRegistration.getClientSecret());

IdentityEndpoints identityEndpoints = new IdentityEndpoints();
assertEquals(
identityEndpoints.authorizationEndpoint("fake-tenant-id"),
azureClientRegistration.getProviderDetails().getAuthorizationUri()
);
assertEquals(
identityEndpoints.tokenEndpoint("fake-tenant-id"),
azureClientRegistration.getProviderDetails().getTokenUri()
);
assertEquals(
identityEndpoints.jwkSetEndpoint("fake-tenant-id"),
azureClientRegistration.getProviderDetails().getJwkSetUri()
);
assertEquals(
"{baseUrl}/login/oauth2/code/{registrationId}",
azureClientRegistration.getRedirectUriTemplate()
);
assertDefaultScopes(azureClientRegistration, "openid", "profile");
}
}

@Test
public void clientRequiresPermissionRegistered() {
try (AppRunner appRunner = createApp()) {
appRunner.property("azure.activedirectory.authorization.graph.scope", "Calendars.Read");
appRunner.start();

ClientRegistrationRepository clientRegistrationRepository =
appRunner.getBean(ClientRegistrationRepository.class);
ClientRegistration azureClientRegistration = clientRegistrationRepository.findByRegistrationId("azure");
ClientRegistration graphClientRegistration = clientRegistrationRepository.findByRegistrationId("graph");

assertNotNull(azureClientRegistration);
assertDefaultScopes(azureClientRegistration, "openid", "profile", "offline_access", "Calendars.Read");

assertNotNull(graphClientRegistration);
assertDefaultScopes(graphClientRegistration, "Calendars.Read");
}
}

@Test
public void clientRequiresMultiPermissions() {
try (AppRunner appRunner = createApp()) {
appRunner.property("azure.activedirectory.authorization.graph.scope", "Calendars.Read");
appRunner.property(
"azure.activedirectory.authorization.arm.scope",
"https://management.core.windows.net/user_impersonation"
);
appRunner.start();

ClientRegistrationRepository clientRegistrationRepository =
appRunner.getBean(ClientRegistrationRepository.class);
ClientRegistration azureClientRegistration = clientRegistrationRepository.findByRegistrationId("azure");
ClientRegistration graphClientRegistration = clientRegistrationRepository.findByRegistrationId("graph");

assertNotNull(azureClientRegistration);
assertDefaultScopes(
azureClientRegistration,
"openid",
"profile",
"offline_access",
"Calendars.Read",
"https://management.core.windows.net/user_impersonation"
);

assertNotNull(graphClientRegistration);
assertDefaultScopes(graphClientRegistration, "Calendars.Read");
}
}

@Test
public void clientRequiresPermissionInDefaultClient() {
try (AppRunner appRunner = createApp()) {
appRunner.property("azure.activedirectory.authorization.azure.scope", "Calendars.Read");
appRunner.start();

ClientRegistrationRepository clientRegistrationRepository =
appRunner.getBean(ClientRegistrationRepository.class);
ClientRegistration azureClientRegistration = clientRegistrationRepository.findByRegistrationId("azure");

assertNotNull(azureClientRegistration);
assertDefaultScopes(
azureClientRegistration,
"openid", "profile", "offline_access", "Calendars.Read"
);
}
}

@Test
public void aadAwareClientRepository() {
try (AppRunner appRunner = createApp()) {
appRunner.property("azure.activedirectory.authorization.graph.scope", "Calendars.Read");
appRunner.start();

AzureClientRegistrationRepository azureClientRegistrationRepository =
(AzureClientRegistrationRepository) appRunner.getBean(ClientRegistrationRepository.class);
ClientRegistration azureClientRegistration =
azureClientRegistrationRepository.findByRegistrationId("azure");
ClientRegistration graphClientRegistration =
azureClientRegistrationRepository.findByRegistrationId("graph");

assertDefaultScopes(
azureClientRegistrationRepository.defaultClient(),
"openid", "profile", "offline_access"
);
assertEquals(azureClientRegistrationRepository.defaultClient().getClientRegistration(), azureClientRegistration);

assertFalse(azureClientRegistrationRepository.isAuthorizedClient(azureClientRegistration));
assertTrue(azureClientRegistrationRepository.isAuthorizedClient(graphClientRegistration));
assertFalse(azureClientRegistrationRepository.isAuthorizedClient("azure"));
assertTrue(azureClientRegistrationRepository.isAuthorizedClient("graph"));

List<ClientRegistration> clientRegistrations = collectClients(azureClientRegistrationRepository);
assertEquals(1, clientRegistrations.size());
assertEquals("azure", clientRegistrations.get(0).getRegistrationId());
}
}

@Test
public void defaultClientWithAuthzScope() {
try (AppRunner appRunner = createApp()) {
appRunner.property("azure.activedirectory.authorization.azure.scope", "Calendars.Read");
appRunner.start();

AzureClientRegistrationRepository azureClientRegistrationRepository =
appRunner.getBean(AzureClientRegistrationRepository.class);
assertDefaultScopes(
azureClientRegistrationRepository.defaultClient(),
"openid", "profile", "offline_access", "Calendars.Read"
);
}
}

@Test
public void customizeUri() {
try (AppRunner appRunner = createApp()) {
appRunner.property("azure.activedirectory.uri", "http://localhost/");
appRunner.start();

AzureClientRegistrationRepository azureClientRegistrationRepository =
appRunner.getBean(AzureClientRegistrationRepository.class);
ClientRegistration azureClientRegistration =
azureClientRegistrationRepository.findByRegistrationId("azure");

IdentityEndpoints endpoints = new IdentityEndpoints("http://localhost/");
assertEquals(
endpoints.authorizationEndpoint("fake-tenant-id"),
azureClientRegistration.getProviderDetails().getAuthorizationUri()
);
assertEquals(
endpoints.tokenEndpoint("fake-tenant-id"),
azureClientRegistration.getProviderDetails().getTokenUri()
);
assertEquals(
endpoints.jwkSetEndpoint("fake-tenant-id"),
azureClientRegistration.getProviderDetails().getJwkSetUri()
);
}
}

private AppRunner createApp() {
AppRunner result = new AppRunner(DumbApp.class);
result.property("azure.activedirectory.tenant-id", "fake-tenant-id");
result.property("azure.activedirectory.client-id", "fake-client-id");
result.property("azure.activedirectory.client-secret", "fake-client-secret");
result.property("azure.activedirectory.user-group.allowed-groups", "group1");
return result;
}

private void assertDefaultScopes(ClientRegistration client, String ... scopes) {
assertEquals(scopes.length, client.getScopes().size());
for (String s : scopes) {
assertTrue(client.getScopes().contains(s));
}
}

private void assertDefaultScopes(DefaultClient client, String ... expected) {
assertEquals(expected.length, client.getScopeList().size());
for (String e : expected) {
assertTrue(client.getScopeList().contains(e));
}
}

private List<ClientRegistration> collectClients(Iterable<ClientRegistration> iterable) {
List<ClientRegistration> result = new ArrayList<>();
iterable.forEach(result::add);
return result;
}

@Configuration
@EnableAutoConfiguration
@EnableWebSecurity
public static class DumbApp {}
}
Loading