diff --git a/samples/boot/oauth2resourceserver/spring-authorization-server-samples-boot-oauth2resourceserver.gradle b/samples/boot/oauth2resourceserver/spring-authorization-server-samples-boot-oauth2resourceserver.gradle new file mode 100644 index 0000000..32388aa --- /dev/null +++ b/samples/boot/oauth2resourceserver/spring-authorization-server-samples-boot-oauth2resourceserver.gradle @@ -0,0 +1,15 @@ +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 new file mode 100644 index 0000000..15ac7d5 --- /dev/null +++ b/samples/boot/oauth2resourceserver/src/main/java/sample/ResourceController.java @@ -0,0 +1,29 @@ +/* + * 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 new file mode 100644 index 0000000..ee2c147 --- /dev/null +++ b/samples/boot/oauth2resourceserver/src/main/java/sample/ResourceServerApplication.java @@ -0,0 +1,27 @@ +/* + * 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 new file mode 100644 index 0000000..9a384eb --- /dev/null +++ b/samples/boot/oauth2resourceserver/src/main/resources/application.yml @@ -0,0 +1,6 @@ +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 new file mode 100644 index 0000000..5e6a810 --- /dev/null +++ b/samples/boot/oauth2resourceserver/src/test/java/sample/ResourceControllerTests.java @@ -0,0 +1,70 @@ +/* + * 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); + }; + } + } +}