Add ":servlet:spring-boot:java:oauth2:resource-server:static"
This commit is contained in:
+105
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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 example;
|
||||
|
||||
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.http.HttpHeaders;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.RequestPostProcessor;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link OAuth2ResourceServerApplication}.
|
||||
*
|
||||
* @author Josh Cummings
|
||||
*/
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
@ActiveProfiles("test")
|
||||
public class OAuth2ResourceServerApplicationITests {
|
||||
|
||||
String noScopesToken = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzdWJqZWN0IiwiaWF0IjoxNTE2MjM5MDIyfQ.eB2c9xtg5wcCZxZ-o-sH4Mx1JGkqAZwH4_WS0UcDbj_nen0NPBj6CqOEPhr_LZDagb4mM6HoAPJywWWG8b_Ylnn5r2gWDzib2mb0kxIuAjnvVBrpzusw4ItTVvP_srv2DrwcisKYiKqU5X_3ka7MSVvKtswdLY3RXeCJ_S2W9go";
|
||||
|
||||
String messageReadToken = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzdWJqZWN0IiwiaWF0IjoxNTE2MjM5MDIyLCJzY29wZSI6Im1lc3NhZ2U6cmVhZCJ9.bsRCpUEaiWnzX4OqNxTBqwUD4vxxtPp-CHKTw7XcrglrvZ2lvYXaiZZbCp-hcPhuzMEzEAFuH6s4GZZOWVIX-wT47GdTz9cfA-Z4QPjS2RxePKphFXgBI3jHEpQo94Qya2fJdV4LvgBmA1uM_RTnYY1UbmeYuHKnXrZoGyV8QQQ";
|
||||
|
||||
@Autowired
|
||||
MockMvc mvc;
|
||||
|
||||
@Test
|
||||
void performWhenValidBearerTokenThenAllows() throws Exception {
|
||||
|
||||
// @formatter:off
|
||||
this.mvc.perform(get("/").with(bearerToken(this.noScopesToken)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(containsString("Hello, subject!")));
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
// -- tests with scopes
|
||||
|
||||
@Test
|
||||
void performWhenValidBearerTokenThenScopedRequestsAlsoWork() throws Exception {
|
||||
|
||||
// @formatter:off
|
||||
this.mvc.perform(get("/message").with(bearerToken(this.messageReadToken)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(containsString("secret message")));
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
void performWhenInsufficientlyScopedBearerTokenThenDeniesScopedMethodAccess() throws Exception {
|
||||
|
||||
// @formatter:off
|
||||
this.mvc.perform(get("/message").with(bearerToken(this.noScopesToken)))
|
||||
.andExpect(status().isForbidden())
|
||||
.andExpect(header().string(HttpHeaders.WWW_AUTHENTICATE,
|
||||
containsString("Bearer error=\"insufficient_scope\"")));
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
private static BearerTokenRequestPostProcessor bearerToken(String token) {
|
||||
return new BearerTokenRequestPostProcessor(token);
|
||||
}
|
||||
|
||||
private static class BearerTokenRequestPostProcessor implements RequestPostProcessor {
|
||||
|
||||
private String token;
|
||||
|
||||
BearerTokenRequestPostProcessor(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) {
|
||||
request.addHeader("Authorization", "Bearer " + this.token);
|
||||
return request;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 example;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* OAuth2 Resource Server Application.
|
||||
*
|
||||
* @author Josh Cummings
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class OAuth2ResourceServerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(OAuth2ResourceServerApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 example;
|
||||
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* An OAuth Controller.
|
||||
*
|
||||
* @author Josh Cummings
|
||||
*/
|
||||
@RestController
|
||||
public class OAuth2ResourceServerController {
|
||||
|
||||
@GetMapping("/")
|
||||
public String index(@AuthenticationPrincipal Jwt jwt) {
|
||||
return String.format("Hello, %s!", jwt.getSubject());
|
||||
}
|
||||
|
||||
@GetMapping("/message")
|
||||
public String message() {
|
||||
return "secret message";
|
||||
}
|
||||
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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 example;
|
||||
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
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.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
|
||||
|
||||
/**
|
||||
* OAuth2 Resource Server Configuration.
|
||||
*
|
||||
* @author Josh Cummings
|
||||
*/
|
||||
@EnableWebSecurity
|
||||
public class OAuth2ResourceServerSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Value("${spring.security.oauth2.resourceserver.jwt.key-value}")
|
||||
RSAPublicKey key;
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
// @formatter:off
|
||||
http
|
||||
.authorizeRequests((requests) -> requests
|
||||
.mvcMatchers("/message/**").hasAuthority("SCOPE_message:read")
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.oauth2ResourceServer((resourceServer) -> resourceServer
|
||||
.jwt((jwt) -> jwt
|
||||
.decoder(jwtDecoder())
|
||||
)
|
||||
);
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Bean
|
||||
JwtDecoder jwtDecoder() {
|
||||
return NimbusJwtDecoder.withPublicKey(this.key).build();
|
||||
}
|
||||
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
spring:
|
||||
security:
|
||||
oauth2:
|
||||
resourceserver:
|
||||
jwt:
|
||||
key-value: classpath:simple.pub
|
||||
@@ -0,0 +1,7 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdlatRjRjogo3WojgGHFHYLugd
|
||||
UWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQs
|
||||
HUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5D
|
||||
o2kQ+X5xK9cipRgEKwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
|
||||
Reference in New Issue
Block a user