From 9f1a6e386f15f9325537d7f4d7749d1db533c03a Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Fri, 28 Apr 2023 14:22:13 -0400 Subject: [PATCH] Merge device-grant-authorizationserver into featured-authorizationserver Issue gh-1189 --- .../gradle.properties | 1 - ...es-device-grant-authorizationserver.gradle | 29 --- ...ceGrantAuthorizationServerApplication.java | 32 --- .../java/sample/config/SecurityConfig.java | 237 ------------------ .../src/main/resources/application.yml | 6 - .../DeviceClientAuthenticationProvider.java | 0 .../DeviceClientAuthenticationToken.java | 0 .../config/AuthorizationServerConfig.java | 58 ++++- .../java/sample/web/DeviceController.java | 2 +- .../sample/web/DeviceErrorController.java | 0 .../DeviceClientAuthenticationConverter.java | 1 + .../resources/static/assets/css/style.css | 0 .../resources/templates/access-denied.html | 0 .../main/resources/templates/activate.html | 0 .../main/resources/templates/activated.html | 0 .../src/main/resources/templates/error.html | 0 16 files changed, 55 insertions(+), 311 deletions(-) delete mode 100644 samples/device-grant-authorizationserver/gradle.properties delete mode 100644 samples/device-grant-authorizationserver/samples-device-grant-authorizationserver.gradle delete mode 100644 samples/device-grant-authorizationserver/src/main/java/sample/DeviceGrantAuthorizationServerApplication.java delete mode 100644 samples/device-grant-authorizationserver/src/main/java/sample/config/SecurityConfig.java delete mode 100644 samples/device-grant-authorizationserver/src/main/resources/application.yml rename samples/{device-grant-authorizationserver => featured-authorizationserver}/src/main/java/sample/authentication/DeviceClientAuthenticationProvider.java (100%) rename samples/{device-grant-authorizationserver => featured-authorizationserver}/src/main/java/sample/authentication/DeviceClientAuthenticationToken.java (100%) rename samples/{device-grant-authorizationserver => featured-authorizationserver}/src/main/java/sample/web/DeviceController.java (98%) rename samples/{device-grant-authorizationserver => featured-authorizationserver}/src/main/java/sample/web/DeviceErrorController.java (100%) rename samples/{device-grant-authorizationserver => featured-authorizationserver}/src/main/java/sample/web/authentication/DeviceClientAuthenticationConverter.java (99%) rename samples/{device-grant-authorizationserver => featured-authorizationserver}/src/main/resources/static/assets/css/style.css (100%) rename samples/{device-grant-authorizationserver => featured-authorizationserver}/src/main/resources/templates/access-denied.html (100%) rename samples/{device-grant-authorizationserver => featured-authorizationserver}/src/main/resources/templates/activate.html (100%) rename samples/{device-grant-authorizationserver => featured-authorizationserver}/src/main/resources/templates/activated.html (100%) rename samples/{device-grant-authorizationserver => featured-authorizationserver}/src/main/resources/templates/error.html (100%) diff --git a/samples/device-grant-authorizationserver/gradle.properties b/samples/device-grant-authorizationserver/gradle.properties deleted file mode 100644 index 3d071be6..00000000 --- a/samples/device-grant-authorizationserver/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -spring-security.version=6.1.0-RC1 diff --git a/samples/device-grant-authorizationserver/samples-device-grant-authorizationserver.gradle b/samples/device-grant-authorizationserver/samples-device-grant-authorizationserver.gradle deleted file mode 100644 index cc860e04..00000000 --- a/samples/device-grant-authorizationserver/samples-device-grant-authorizationserver.gradle +++ /dev/null @@ -1,29 +0,0 @@ -plugins { - id "org.springframework.boot" version "3.0.0" - id "io.spring.dependency-management" version "1.0.11.RELEASE" - id "java" -} - -group = project.rootProject.group -version = project.rootProject.version -sourceCompatibility = "17" - -repositories { - mavenCentral() - maven { url = "https://repo.spring.io/milestone" } -} - -dependencies { - implementation "org.springframework.boot:spring-boot-starter-web" - implementation "org.springframework.boot:spring-boot-starter-security" - implementation "org.springframework.boot:spring-boot-starter-jdbc" - implementation project(":spring-security-oauth2-authorization-server") - implementation "org.springframework.boot:spring-boot-starter-thymeleaf" - implementation "org.webjars:webjars-locator-core" - implementation "org.webjars:bootstrap:3.4.1" - implementation "org.webjars:jquery:3.4.1" - runtimeOnly "com.h2database:h2" - - testImplementation "org.springframework.boot:spring-boot-starter-test" - testImplementation "org.springframework.security:spring-security-test" -} diff --git a/samples/device-grant-authorizationserver/src/main/java/sample/DeviceGrantAuthorizationServerApplication.java b/samples/device-grant-authorizationserver/src/main/java/sample/DeviceGrantAuthorizationServerApplication.java deleted file mode 100644 index 88df7321..00000000 --- a/samples/device-grant-authorizationserver/src/main/java/sample/DeviceGrantAuthorizationServerApplication.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2020-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package sample; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -/** - * @author Steve Riesenberg - * @since 1.1 - */ -@SpringBootApplication -public class DeviceGrantAuthorizationServerApplication { - - public static void main(String[] args) { - SpringApplication.run(DeviceGrantAuthorizationServerApplication.class, args); - } - -} diff --git a/samples/device-grant-authorizationserver/src/main/java/sample/config/SecurityConfig.java b/samples/device-grant-authorizationserver/src/main/java/sample/config/SecurityConfig.java deleted file mode 100644 index 23a2e0c3..00000000 --- a/samples/device-grant-authorizationserver/src/main/java/sample/config/SecurityConfig.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright 2020-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package sample.config; - -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.interfaces.RSAPrivateKey; -import java.security.interfaces.RSAPublicKey; -import java.util.UUID; - -import com.nimbusds.jose.jwk.JWKSet; -import com.nimbusds.jose.jwk.RSAKey; -import com.nimbusds.jose.jwk.source.ImmutableJWKSet; -import com.nimbusds.jose.jwk.source.JWKSource; -import com.nimbusds.jose.proc.SecurityContext; -import sample.authentication.DeviceClientAuthenticationProvider; -import sample.web.authentication.DeviceClientAuthenticationConverter; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; -import org.springframework.security.config.Customizer; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.oauth2.core.AuthorizationGrantType; -import org.springframework.security.oauth2.core.ClientAuthenticationMethod; -import org.springframework.security.oauth2.core.oidc.OidcScopes; -import org.springframework.security.oauth2.jwt.JwtDecoder; -import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService; -import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; -import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; -import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; -import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; -import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; -import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer; -import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; -import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; -import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; - -/** - * @author Steve Riesenberg - * @since 1.1 - */ -@Configuration(proxyBeanMethods = false) -@EnableWebSecurity -public class SecurityConfig { - - @Bean - @Order(1) - public SecurityFilterChain authorizationServerSecurityFilterChain( - HttpSecurity http, RegisteredClientRepository registeredClientRepository, - AuthorizationServerSettings authorizationServerSettings) throws Exception { - OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); - - /* - * This sample demonstrates the use of a public client that does not - * store credentials or authenticate with the authorization server. - * - * The following components show how to customize the authorization - * server to allow for device clients to perform requests to the - * OAuth 2.0 Device Authorization Endpoint and Token Endpoint without - * a clientId/clientSecret. - * - * CAUTION: These endpoints will not require any authentication, and can - * be accessed by any client that has a valid clientId. - * - * It is therefore RECOMMENDED to carefully monitor the use of these - * endpoints and employ any additional protections as needed, which is - * outside the scope of this sample. - */ - DeviceClientAuthenticationConverter deviceClientAuthenticationConverter = - new DeviceClientAuthenticationConverter( - authorizationServerSettings.getDeviceAuthorizationEndpoint()); - DeviceClientAuthenticationProvider deviceClientAuthenticationProvider = - new DeviceClientAuthenticationProvider(registeredClientRepository); - - // @formatter:off - http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) - .deviceAuthorizationEndpoint((deviceAuthorizationEndpoint) -> deviceAuthorizationEndpoint - .verificationUri("/activate") - ) - .clientAuthentication((clientAuthentication) -> clientAuthentication - .authenticationConverter(deviceClientAuthenticationConverter) - .authenticationProvider(deviceClientAuthenticationProvider) - ) - .oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0 - // @formatter:on - - // @formatter:off - http - .exceptionHandling((exceptions) -> exceptions - .authenticationEntryPoint( - new LoginUrlAuthenticationEntryPoint("/login")) - ) - .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); - // @formatter:on - - return http.build(); - } - - @Bean - @Order(2) - public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { - // @formatter:off - http - .authorizeHttpRequests((authorize) -> authorize - .anyRequest().authenticated() - ) - .formLogin(Customizer.withDefaults()); - // @formatter:on - - return http.build(); - } - - @Bean - public UserDetailsService userDetailsService() { - // @formatter:off - UserDetails userDetails = User.withDefaultPasswordEncoder() - .username("user1") - .password("password") - .roles("USER") - .build(); - // @formatter:on - - return new InMemoryUserDetailsManager(userDetails); - } - - @Bean - public RegisteredClientRepository registeredClientRepository() { - RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString()) - .clientId("messaging-client") - .clientSecret("{noop}secret") - .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) - .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) - .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) - .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) - .redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc") - .redirectUri("http://127.0.0.1:8080/authorized") - .scope(OidcScopes.OPENID) - .scope(OidcScopes.PROFILE) - .scope("message.read") - .scope("message.write") - .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build()) - .build(); - - RegisteredClient deviceClient = RegisteredClient.withId(UUID.randomUUID().toString()) - .clientId("device-messaging-client") - .clientAuthenticationMethod(ClientAuthenticationMethod.NONE) - .authorizationGrantType(AuthorizationGrantType.DEVICE_CODE) - .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) - .scope("message.read") - .scope("message.write") - .build(); - - return new InMemoryRegisteredClientRepository(registeredClient, deviceClient); - } - - @Bean - public OAuth2AuthorizationService authorizationService(JdbcTemplate jdbcTemplate, - RegisteredClientRepository registeredClientRepository) { - return new JdbcOAuth2AuthorizationService(jdbcTemplate, registeredClientRepository); - } - - @Bean - public JWKSource jwkSource() { - KeyPair keyPair = generateRsaKey(); - RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); - RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); - RSAKey rsaKey = new RSAKey.Builder(publicKey) - .privateKey(privateKey) - .keyID(UUID.randomUUID().toString()) - .build(); - JWKSet jwkSet = new JWKSet(rsaKey); - return new ImmutableJWKSet<>(jwkSet); - } - - private static KeyPair generateRsaKey() { - KeyPair keyPair; - try { - KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); - keyPairGenerator.initialize(2048); - keyPair = keyPairGenerator.generateKeyPair(); - } - catch (Exception ex) { - throw new IllegalStateException(ex); - } - return keyPair; - } - - @Bean - public JwtDecoder jwtDecoder(JWKSource jwkSource) { - return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource); - } - - @Bean - public AuthorizationServerSettings authorizationServerSettings() { - return AuthorizationServerSettings.builder().build(); - } - - @Bean - public EmbeddedDatabase embeddedDatabase() { - // @formatter:off - return new EmbeddedDatabaseBuilder() - .generateUniqueName(true) - .setType(EmbeddedDatabaseType.H2) - .setScriptEncoding("UTF-8") - .addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql") - .addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-consent-schema.sql") - .addScript("org/springframework/security/oauth2/server/authorization/client/oauth2-registered-client-schema.sql") - .build(); - // @formatter:on - } - -} diff --git a/samples/device-grant-authorizationserver/src/main/resources/application.yml b/samples/device-grant-authorizationserver/src/main/resources/application.yml deleted file mode 100644 index 8865684c..00000000 --- a/samples/device-grant-authorizationserver/src/main/resources/application.yml +++ /dev/null @@ -1,6 +0,0 @@ -server: - port: 9000 - -logging: - level: - org.springframework.security: trace diff --git a/samples/device-grant-authorizationserver/src/main/java/sample/authentication/DeviceClientAuthenticationProvider.java b/samples/featured-authorizationserver/src/main/java/sample/authentication/DeviceClientAuthenticationProvider.java similarity index 100% rename from samples/device-grant-authorizationserver/src/main/java/sample/authentication/DeviceClientAuthenticationProvider.java rename to samples/featured-authorizationserver/src/main/java/sample/authentication/DeviceClientAuthenticationProvider.java diff --git a/samples/device-grant-authorizationserver/src/main/java/sample/authentication/DeviceClientAuthenticationToken.java b/samples/featured-authorizationserver/src/main/java/sample/authentication/DeviceClientAuthenticationToken.java similarity index 100% rename from samples/device-grant-authorizationserver/src/main/java/sample/authentication/DeviceClientAuthenticationToken.java rename to samples/featured-authorizationserver/src/main/java/sample/authentication/DeviceClientAuthenticationToken.java diff --git a/samples/featured-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java b/samples/featured-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java index 0e991844..60865ad1 100644 --- a/samples/featured-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java +++ b/samples/featured-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java @@ -21,9 +21,11 @@ import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; +import sample.authentication.DeviceClientAuthenticationProvider; import sample.jose.Jwks; import sample.security.FederatedIdentityConfigurer; import sample.security.FederatedIdentityIdTokenCustomizer; +import sample.web.authentication.DeviceClientAuthenticationConverter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -67,12 +69,48 @@ public class AuthorizationServerConfig { @Bean @Order(Ordered.HIGHEST_PRECEDENCE) - public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { + public SecurityFilterChain authorizationServerSecurityFilterChain( + HttpSecurity http, RegisteredClientRepository registeredClientRepository, + AuthorizationServerSettings authorizationServerSettings) throws Exception { + OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); + + /* + * This sample demonstrates the use of a public client that does not + * store credentials or authenticate with the authorization server. + * + * The following components show how to customize the authorization + * server to allow for device clients to perform requests to the + * OAuth 2.0 Device Authorization Endpoint and Token Endpoint without + * a clientId/clientSecret. + * + * CAUTION: These endpoints will not require any authentication, and can + * be accessed by any client that has a valid clientId. + * + * It is therefore RECOMMENDED to carefully monitor the use of these + * endpoints and employ any additional protections as needed, which is + * outside the scope of this sample. + */ + DeviceClientAuthenticationConverter deviceClientAuthenticationConverter = + new DeviceClientAuthenticationConverter( + authorizationServerSettings.getDeviceAuthorizationEndpoint()); + DeviceClientAuthenticationProvider deviceClientAuthenticationProvider = + new DeviceClientAuthenticationProvider(registeredClientRepository); + + // @formatter:off http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) - .authorizationEndpoint(authorizationEndpoint -> - authorizationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI)) - .oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0 + .deviceAuthorizationEndpoint(deviceAuthorizationEndpoint -> + deviceAuthorizationEndpoint.verificationUri("/activate") + ) + .clientAuthentication(clientAuthentication -> + clientAuthentication + .authenticationConverter(deviceClientAuthenticationConverter) + .authenticationProvider(deviceClientAuthenticationProvider) + ) + .authorizationEndpoint(authorizationEndpoint -> + authorizationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI)) + .oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0 + // @formatter:on // @formatter:off http @@ -106,9 +144,19 @@ public class AuthorizationServerConfig { .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build()) .build(); - // Save registered client in db as if in-memory + RegisteredClient deviceClient = RegisteredClient.withId(UUID.randomUUID().toString()) + .clientId("device-messaging-client") + .clientAuthenticationMethod(ClientAuthenticationMethod.NONE) + .authorizationGrantType(AuthorizationGrantType.DEVICE_CODE) + .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) + .scope("message.read") + .scope("message.write") + .build(); + + // Save registered client's in db as if in-memory JdbcRegisteredClientRepository registeredClientRepository = new JdbcRegisteredClientRepository(jdbcTemplate); registeredClientRepository.save(registeredClient); + registeredClientRepository.save(deviceClient); return registeredClientRepository; } diff --git a/samples/device-grant-authorizationserver/src/main/java/sample/web/DeviceController.java b/samples/featured-authorizationserver/src/main/java/sample/web/DeviceController.java similarity index 98% rename from samples/device-grant-authorizationserver/src/main/java/sample/web/DeviceController.java rename to samples/featured-authorizationserver/src/main/java/sample/web/DeviceController.java index 418f241c..fae0429e 100644 --- a/samples/device-grant-authorizationserver/src/main/java/sample/web/DeviceController.java +++ b/samples/featured-authorizationserver/src/main/java/sample/web/DeviceController.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package sample.web; import org.springframework.stereotype.Controller; @@ -22,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestParam; /** * @author Steve Riesenberg + * @since 1.1 */ @Controller public class DeviceController { diff --git a/samples/device-grant-authorizationserver/src/main/java/sample/web/DeviceErrorController.java b/samples/featured-authorizationserver/src/main/java/sample/web/DeviceErrorController.java similarity index 100% rename from samples/device-grant-authorizationserver/src/main/java/sample/web/DeviceErrorController.java rename to samples/featured-authorizationserver/src/main/java/sample/web/DeviceErrorController.java diff --git a/samples/device-grant-authorizationserver/src/main/java/sample/web/authentication/DeviceClientAuthenticationConverter.java b/samples/featured-authorizationserver/src/main/java/sample/web/authentication/DeviceClientAuthenticationConverter.java similarity index 99% rename from samples/device-grant-authorizationserver/src/main/java/sample/web/authentication/DeviceClientAuthenticationConverter.java rename to samples/featured-authorizationserver/src/main/java/sample/web/authentication/DeviceClientAuthenticationConverter.java index 14dd3e5f..aa1cbfef 100644 --- a/samples/device-grant-authorizationserver/src/main/java/sample/web/authentication/DeviceClientAuthenticationConverter.java +++ b/samples/featured-authorizationserver/src/main/java/sample/web/authentication/DeviceClientAuthenticationConverter.java @@ -16,6 +16,7 @@ package sample.web.authentication; import jakarta.servlet.http.HttpServletRequest; + import sample.authentication.DeviceClientAuthenticationToken; import org.springframework.http.HttpMethod; diff --git a/samples/device-grant-authorizationserver/src/main/resources/static/assets/css/style.css b/samples/featured-authorizationserver/src/main/resources/static/assets/css/style.css similarity index 100% rename from samples/device-grant-authorizationserver/src/main/resources/static/assets/css/style.css rename to samples/featured-authorizationserver/src/main/resources/static/assets/css/style.css diff --git a/samples/device-grant-authorizationserver/src/main/resources/templates/access-denied.html b/samples/featured-authorizationserver/src/main/resources/templates/access-denied.html similarity index 100% rename from samples/device-grant-authorizationserver/src/main/resources/templates/access-denied.html rename to samples/featured-authorizationserver/src/main/resources/templates/access-denied.html diff --git a/samples/device-grant-authorizationserver/src/main/resources/templates/activate.html b/samples/featured-authorizationserver/src/main/resources/templates/activate.html similarity index 100% rename from samples/device-grant-authorizationserver/src/main/resources/templates/activate.html rename to samples/featured-authorizationserver/src/main/resources/templates/activate.html diff --git a/samples/device-grant-authorizationserver/src/main/resources/templates/activated.html b/samples/featured-authorizationserver/src/main/resources/templates/activated.html similarity index 100% rename from samples/device-grant-authorizationserver/src/main/resources/templates/activated.html rename to samples/featured-authorizationserver/src/main/resources/templates/activated.html diff --git a/samples/device-grant-authorizationserver/src/main/resources/templates/error.html b/samples/featured-authorizationserver/src/main/resources/templates/error.html similarity index 100% rename from samples/device-grant-authorizationserver/src/main/resources/templates/error.html rename to samples/featured-authorizationserver/src/main/resources/templates/error.html