diff --git a/samples/boot/minimal/README.md b/samples/boot/minimal/README.md deleted file mode 100644 index 2a7ed4c..0000000 --- a/samples/boot/minimal/README.md +++ /dev/null @@ -1,12 +0,0 @@ -## Minimal Authorization Server Sample - -#### How to run - -``` -./gradlew spring-authorization-server-samples-boot-minimal:bootRun -``` - -``` -curl http://localhost:8080/.well-known/jwk_uris -``` - diff --git a/samples/boot/minimal/spring-security-samples2-boot-minimal.gradle b/samples/boot/minimal/spring-security-samples2-boot-minimal.gradle deleted file mode 100644 index 620835a..0000000 --- a/samples/boot/minimal/spring-security-samples2-boot-minimal.gradle +++ /dev/null @@ -1,16 +0,0 @@ -apply plugin: 'io.spring.convention.spring-sample-boot' - -dependencies { - implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springframework.boot:spring-boot-starter-security' - implementation project(':spring-security-oauth2-authorization-server') - implementation 'com.nimbusds:oauth2-oidc-sdk' - - testImplementation('org.springframework.boot:spring-boot-starter-test') { - exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' - } -} - -test { - useJUnitPlatform() -} diff --git a/samples/boot/minimal/src/main/java/sample/ClientCredentialsAuthenticationFilter.java b/samples/boot/minimal/src/main/java/sample/ClientCredentialsAuthenticationFilter.java deleted file mode 100644 index 5b0b6e4..0000000 --- a/samples/boot/minimal/src/main/java/sample/ClientCredentialsAuthenticationFilter.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2020 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.http.HttpMethod; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.web.filter.OncePerRequestFilter; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.Base64; - -import static java.nio.charset.StandardCharsets.UTF_8; - -/** - * A filter to perform client authentication for the Token Endpoint. - * - * See RFC-6749 2.3.1. - */ -public class ClientCredentialsAuthenticationFilter extends OncePerRequestFilter { - private final AuthenticationManager authenticationManager; - private final RequestMatcher requestMatcher = new AntPathRequestMatcher("/oauth2/token", HttpMethod.POST.name()); - - public ClientCredentialsAuthenticationFilter(AuthenticationManager authenticationManager) { - this.authenticationManager = authenticationManager; - } - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) - throws ServletException, IOException { - - if (this.requestMatcher.matches(request)) { - String[] credentials = extractBasicAuthenticationCredentials(request); - String clientId = credentials[0]; - String clientSecret = credentials[1]; - - OAuth2ClientAuthenticationToken authenticationToken = new OAuth2ClientAuthenticationToken(clientId, clientSecret); - - Authentication authentication = this.authenticationManager.authenticate(authenticationToken); - - SecurityContextHolder.getContext().setAuthentication(authentication); - } - - chain.doFilter(request, response); - } - - private String[] extractBasicAuthenticationCredentials(HttpServletRequest request) { - String header = request.getHeader("Authorization"); - if (header != null && header.toLowerCase().startsWith("basic ")) { - return extractAndDecodeHeader(header, request); - } - throw new BadCredentialsException("Missing basic authentication header"); - } - - // Taken from BasicAuthenticationFilter (spring-security-web) - private String[] extractAndDecodeHeader(String header, HttpServletRequest request) { - - byte[] base64Token = header.substring(6).getBytes(UTF_8); - byte[] decoded; - try { - decoded = Base64.getDecoder().decode(base64Token); - } - catch (IllegalArgumentException e) { - throw new BadCredentialsException("Failed to decode basic authentication token"); - } - - String token = new String(decoded, getCredentialsCharset(request)); - - int delim = token.indexOf(":"); - - if (delim == -1) { - throw new BadCredentialsException("Invalid basic authentication token"); - } - return new String[] { token.substring(0, delim), token.substring(delim + 1) }; - } - - protected Charset getCredentialsCharset(HttpServletRequest httpRequest) { - return UTF_8; - } -} diff --git a/samples/boot/minimal/src/main/java/sample/JwkSetEndpointFilter.java b/samples/boot/minimal/src/main/java/sample/JwkSetEndpointFilter.java deleted file mode 100644 index dc894ed..0000000 --- a/samples/boot/minimal/src/main/java/sample/JwkSetEndpointFilter.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2020 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 com.nimbusds.jose.jwk.JWKSet; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.util.Assert; -import org.springframework.web.filter.OncePerRequestFilter; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.io.Writer; - -import static org.springframework.http.HttpMethod.GET; -import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; - -public class JwkSetEndpointFilter extends OncePerRequestFilter { - static final String DEFAULT_JWK_SET_URI = "/oauth2/jwks"; - private final RequestMatcher requestMatcher = new AntPathRequestMatcher(DEFAULT_JWK_SET_URI, GET.name()); - private final JWKSet jwkSet; - - public JwkSetEndpointFilter(JWKSet jwkSet) { - Assert.notNull(jwkSet, "jwkSet cannot be null"); - this.jwkSet = jwkSet; - } - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { - - if (matchesRequest(request)) { - respond(response); - } else { - filterChain.doFilter(request, response); - } - } - - private void respond(HttpServletResponse response) throws IOException { - response.setContentType(APPLICATION_JSON_VALUE); - try (Writer writer = response.getWriter()) { - writer.write(this.jwkSet.toPublicJWKSet().toJSONObject().toJSONString()); - } - } - - private boolean matchesRequest(HttpServletRequest request) { - return this.requestMatcher.matches(request); - } -} diff --git a/samples/boot/minimal/src/main/java/sample/MinimalAuthorizationServerApplication.java b/samples/boot/minimal/src/main/java/sample/MinimalAuthorizationServerApplication.java deleted file mode 100644 index b607de2..0000000 --- a/samples/boot/minimal/src/main/java/sample/MinimalAuthorizationServerApplication.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2020 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; - -@SpringBootApplication -public class MinimalAuthorizationServerApplication { - - public static void main(String[] args) { - SpringApplication.run(MinimalAuthorizationServerApplication.class, args); - } - -} diff --git a/samples/boot/minimal/src/main/java/sample/SecurityConfig.java b/samples/boot/minimal/src/main/java/sample/SecurityConfig.java deleted file mode 100644 index f1bc2c3..0000000 --- a/samples/boot/minimal/src/main/java/sample/SecurityConfig.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2020 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 com.nimbusds.jose.JOSEException; -import com.nimbusds.jose.jwk.JWK; -import com.nimbusds.jose.jwk.JWKSet; -import com.nimbusds.jose.jwk.KeyUse; -import com.nimbusds.jose.jwk.gen.RSAKeyGenerator; -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.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.web.authentication.logout.LogoutFilter; - -@EnableWebSecurity -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.addFilterBefore(new JwkSetEndpointFilter(generateJwkSet()), LogoutFilter.class); - } - - private JWKSet generateJwkSet() throws JOSEException { - JWK jwk = new RSAKeyGenerator(2048).keyID("minimal-ASA").keyUse(KeyUse.SIGNATURE).generate(); - return new JWKSet(jwk); - } -} diff --git a/samples/boot/minimal/src/test/java/sample/ClientCredentialsAuthenticationFilterTests.java b/samples/boot/minimal/src/test/java/sample/ClientCredentialsAuthenticationFilterTests.java deleted file mode 100644 index c4caf1b..0000000 --- a/samples/boot/minimal/src/test/java/sample/ClientCredentialsAuthenticationFilterTests.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2020 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.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.mock.web.MockFilterChain; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.mock.web.MockServletContext; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken; -import org.springframework.util.Assert; - -import static java.net.URI.create; -import static java.nio.charset.StandardCharsets.UTF_8; -import static java.util.Base64.getEncoder; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; - -public class ClientCredentialsAuthenticationFilterTests { - private static final String CLIENT_ID = "myclientid"; - private static final String CLIENT_SECRET = "myclientsecret"; - private final AuthenticationManager authenticationManager = authentication -> { - Assert.isInstanceOf(OAuth2ClientAuthenticationToken.class, authentication); - OAuth2ClientAuthenticationToken token = (OAuth2ClientAuthenticationToken) authentication; - if (CLIENT_ID.equals(token.getPrincipal()) && CLIENT_SECRET.equals(token.getCredentials())) { - authentication.setAuthenticated(true); - return authentication; - } - throw new BadCredentialsException("Bad credentials"); - }; - private final ClientCredentialsAuthenticationFilter filter = new ClientCredentialsAuthenticationFilter(this.authenticationManager); - - @BeforeEach - public void setup() { - SecurityContextHolder.clearContext(); - } - - @Test - public void doFilterWhenUrlDoesNotMatchThenDontAuthenticate() throws Exception { - MockHttpServletRequest request = post(create("/someotherendpoint")).buildRequest(new MockServletContext()); - request.addHeader("Authorization", basicAuthHeader(CLIENT_ID, CLIENT_SECRET)); - - filter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain()); - - assertThat(SecurityContextHolder.getContext().getAuthentication()).isNull(); - } - - @Test - public void doFilterWhenRequestMatchesThenAuthenticate() throws Exception { - MockHttpServletRequest request = post(create("/oauth2/token")).buildRequest(new MockServletContext()); - request.addHeader("Authorization", basicAuthHeader(CLIENT_ID, CLIENT_SECRET)); - - filter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain()); - - assertThat(SecurityContextHolder.getContext().getAuthentication().isAuthenticated()).isTrue(); - } - - @Test - public void doFilterWhenBasicAuthenticationHeaderIsMissingThenThrowBadCredentialsException() { - MockHttpServletRequest request = post(create("/oauth2/token")).buildRequest(new MockServletContext()); - assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> - filter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain())); - } - - @Test - public void doFilterWhenBasicAuthenticationHeaderHasInvalidSyntaxThenThrowBadCredentialsException() { - MockHttpServletRequest request = post(create("/oauth2/token")).buildRequest(new MockServletContext()); - request.addHeader("Authorization", "Basic invalid"); - - assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> - filter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain())); - } - - @Test - public void doFilterWhenBasicAuthenticationProvidesIncorrectSecretThenThrowBadCredentialsException() { - MockHttpServletRequest request = post(create("/oauth2/token")).buildRequest(new MockServletContext()); - request.addHeader("Authorization", basicAuthHeader(CLIENT_ID, "incorrectsecret")); - - assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> - filter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain())); - } - - @Test - public void doFilterWhenBasicAuthenticationProvidesIncorrectClientIdThenThrowBadCredentialsException() { - MockHttpServletRequest request = post(create("/oauth2/token")).buildRequest(new MockServletContext()); - request.addHeader("Authorization", basicAuthHeader("anotherclientid", CLIENT_SECRET)); - - assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> - filter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain())); - } - - private static String basicAuthHeader(String clientId, String clientSecret) { - return "Basic " + getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes(UTF_8)); - } -} diff --git a/samples/boot/minimal/src/test/java/sample/JwkSetEndpointFilterTests.java b/samples/boot/minimal/src/test/java/sample/JwkSetEndpointFilterTests.java deleted file mode 100644 index 3f4ae0f..0000000 --- a/samples/boot/minimal/src/test/java/sample/JwkSetEndpointFilterTests.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2020 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 com.nimbusds.jose.JOSEException; -import com.nimbusds.jose.jwk.JWK; -import com.nimbusds.jose.jwk.JWKSet; -import com.nimbusds.jose.jwk.KeyUse; -import com.nimbusds.jose.jwk.gen.RSAKeyGenerator; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; -import org.junit.jupiter.api.TestInstance.Lifecycle; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.FilterChain; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.hamcrest.Matchers.is; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.only; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static sample.JwkSetEndpointFilter.DEFAULT_JWK_SET_URI; - -@TestInstance(Lifecycle.PER_CLASS) -public class JwkSetEndpointFilterTests { - private JWK jwk; - private JWKSet jwkSet; - private JwkSetEndpointFilter filter; - private MockMvc mvc; - - @BeforeAll - void setup() throws JOSEException { - this.jwk = new RSAKeyGenerator(2048).keyID("endpoint-test").keyUse(KeyUse.SIGNATURE).generate(); - this.jwkSet = new JWKSet(this.jwk); - this.filter = new JwkSetEndpointFilter(this.jwkSet); - this.mvc = MockMvcBuilders.standaloneSetup(new HelloController()).addFilters(this.filter).alwaysDo(print()).build(); - } - - @Test - void constructorWhenJWKSetNullThenThrowIllegalArgumentException() { - assertThatThrownBy(() -> new JwkSetEndpointFilter(null)) - .isInstanceOf(IllegalArgumentException.class); - } - - @Test - void doFilterWhenRequestMatchesThenProcess() throws Exception { - String requestUri = DEFAULT_JWK_SET_URI; - MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri); - request.setServletPath(requestUri); - - MockHttpServletResponse response = new MockHttpServletResponse(); - FilterChain filterChain = mock(FilterChain.class); - - this.filter.doFilter(request, response, filterChain); - - verifyNoInteractions(filterChain); - } - - @Test - void doFilterWhenRequestDoesNotMatchThenContinueChain() throws Exception { - String requestUri = "/path"; - MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri); - request.setServletPath(requestUri); - - MockHttpServletResponse response = new MockHttpServletResponse(); - FilterChain filterChain = mock(FilterChain.class); - - this.filter.doFilter(request, response, filterChain); - - verify(filterChain, only()).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class)); - } - - @Test - void requestWhenMatchesThenResponseContainsKeys() throws Exception { - this.mvc.perform(get(DEFAULT_JWK_SET_URI)) - .andDo(print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.keys").isArray()) - .andExpect(jsonPath("$.keys").isNotEmpty()) - .andExpect(jsonPath("$.keys[0].kid").value(this.jwk.getKeyID())) - .andExpect(jsonPath("$.keys[0].kty").value(this.jwk.getKeyType().toString())); - } - - @Test - void requestWhenDoesNotMatchThenResponseContainsOther() throws Exception { - this.mvc.perform(get("/hello")) - .andDo(print()) - .andExpect(status().isOk()) - .andExpect(content().string(is("hello"))); - } - - @RestController - static class HelloController { - - @RequestMapping("/hello") - String hello() { - return "hello"; - } - } -} diff --git a/samples/boot/minimal/src/test/java/sample/MinimalAuthorizationServerApplicationTests.java b/samples/boot/minimal/src/test/java/sample/MinimalAuthorizationServerApplicationTests.java deleted file mode 100644 index 58ce909..0000000 --- a/samples/boot/minimal/src/test/java/sample/MinimalAuthorizationServerApplicationTests.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2020 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.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; - -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -public class MinimalAuthorizationServerApplicationTests { - private RestTemplate rest = new RestTemplate(); - - @LocalServerPort - private int serverPort; - - @Test - void requestWhenNotAuthenticatedThenJwkSetEndpointStillAccessible() { - ResponseEntity responseEntity = this.rest.getForEntity( - "http://localhost:" + this.serverPort + JwkSetEndpointFilter.DEFAULT_JWK_SET_URI, String.class); - assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); - } -} diff --git a/samples/boot/oauth2resourceserver/spring-security-samples2-boot-oauth2resourceserver.gradle b/samples/boot/oauth2resourceserver/spring-security-samples2-boot-oauth2resourceserver.gradle deleted file mode 100644 index 32388aa..0000000 --- a/samples/boot/oauth2resourceserver/spring-security-samples2-boot-oauth2resourceserver.gradle +++ /dev/null @@ -1,15 +0,0 @@ -apply plugin: 'io.spring.convention.spring-sample-boot' - -dependencies { - implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springframework.security:spring-security-config' - implementation 'org.springframework.security:spring-security-oauth2-resource-server' - implementation 'org.springframework.security:spring-security-oauth2-jose' - testImplementation('org.springframework.boot:spring-boot-starter-test') { - exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' - } -} - -test { - useJUnitPlatform() -} diff --git a/samples/boot/oauth2resourceserver/src/main/java/sample/ResourceController.java b/samples/boot/oauth2resourceserver/src/main/java/sample/ResourceController.java deleted file mode 100644 index 15ac7d5..0000000 --- a/samples/boot/oauth2resourceserver/src/main/java/sample/ResourceController.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2020 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.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class ResourceController { - - @GetMapping("/") - public String resource() { - return "resource"; - } - -} diff --git a/samples/boot/oauth2resourceserver/src/main/java/sample/ResourceServerApplication.java b/samples/boot/oauth2resourceserver/src/main/java/sample/ResourceServerApplication.java deleted file mode 100644 index ee2c147..0000000 --- a/samples/boot/oauth2resourceserver/src/main/java/sample/ResourceServerApplication.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2020 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; - -@SpringBootApplication -public class ResourceServerApplication { - - public static void main(String[] args) { - SpringApplication.run(ResourceServerApplication.class, args); - } -} diff --git a/samples/boot/oauth2resourceserver/src/main/resources/application.yml b/samples/boot/oauth2resourceserver/src/main/resources/application.yml deleted file mode 100644 index 9a384eb..0000000 --- a/samples/boot/oauth2resourceserver/src/main/resources/application.yml +++ /dev/null @@ -1,6 +0,0 @@ -spring: - security: - oauth2: - resourceserver: - jwt: - jwk-set-uri: https://localhost:8090/oauth2/keys diff --git a/samples/boot/oauth2resourceserver/src/test/java/sample/ResourceControllerTests.java b/samples/boot/oauth2resourceserver/src/test/java/sample/ResourceControllerTests.java deleted file mode 100644 index 5e6a810..0000000 --- a/samples/boot/oauth2resourceserver/src/test/java/sample/ResourceControllerTests.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2020 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 static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.time.Instant; -import java.util.HashMap; -import java.util.Map; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.security.oauth2.jwt.Jwt; -import org.springframework.security.oauth2.jwt.JwtDecoder; -import org.springframework.test.web.servlet.MockMvc; - -@SpringBootTest -@AutoConfigureMockMvc -public class ResourceControllerTests { - - @Autowired - private MockMvc mockMvc; - - @Test - public void shouldReturnOkWithToken() throws Exception { - this.mockMvc.perform(get("/").header("Authorization", "Bearer TOKEN")) - .andExpect(status().isOk()); - } - - @Test - public void shouldReturnUnauthorizedWithoutToken() throws Exception { - this.mockMvc.perform(get("/")) - .andExpect(status().isUnauthorized()); - } - - @TestConfiguration - static class ResourceControllerTestConfiguration { - @Bean - public JwtDecoder jwtDecoder() { - return (token) -> { - Map headers = new HashMap<>(); - headers.put("alg", "RS256"); - headers.put("typ", "JWT"); - - Map claims = new HashMap<>(); - claims.put("sub", "1234567"); - claims.put("name", "John Doe"); - return new Jwt(token, Instant.now(), Instant.now().plusMillis(5000), headers, claims); - }; - } - } -}