|
@@ -16,15 +16,8 @@
|
|
|
|
|
|
package org.springframework.security.oauth2.server.resource.web.access.server;
|
|
|
|
|
|
-import java.util.Arrays;
|
|
|
-import java.util.Collections;
|
|
|
-import java.util.Map;
|
|
|
-
|
|
|
-import org.assertj.core.util.Maps;
|
|
|
import org.junit.Before;
|
|
|
import org.junit.Test;
|
|
|
-import reactor.core.publisher.Mono;
|
|
|
-
|
|
|
import org.springframework.http.HttpStatus;
|
|
|
import org.springframework.mock.http.server.reactive.MockServerHttpResponse;
|
|
|
import org.springframework.security.authentication.TestingAuthenticationToken;
|
|
@@ -32,6 +25,11 @@ import org.springframework.security.core.Authentication;
|
|
|
import org.springframework.security.oauth2.core.AbstractOAuth2Token;
|
|
|
import org.springframework.security.oauth2.server.resource.authentication.AbstractOAuth2TokenAuthenticationToken;
|
|
|
import org.springframework.web.server.ServerWebExchange;
|
|
|
+import reactor.core.publisher.Mono;
|
|
|
+
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.Map;
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
|
import static org.assertj.core.api.Assertions.assertThatCode;
|
|
@@ -78,7 +76,7 @@ public class BearerTokenServerAccessDeniedHandlerTests {
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- public void handleWhenTokenHasNoScopesThenInsufficientScopeError() {
|
|
|
+ public void handleWhenOAuth2AuthenticatedThenStatus403AndAuthHeaderWithInsufficientScopeErrorAttribute() {
|
|
|
|
|
|
Authentication token = new TestingOAuth2TokenAuthenticationToken(Collections.emptyMap());
|
|
|
ServerWebExchange exchange = mock(ServerWebExchange.class);
|
|
@@ -90,121 +88,10 @@ public class BearerTokenServerAccessDeniedHandlerTests {
|
|
|
assertThat(exchange.getResponse().getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
|
|
assertThat(exchange.getResponse().getHeaders().get("WWW-Authenticate")).isEqualTo(
|
|
|
Arrays.asList("Bearer error=\"insufficient_scope\", " +
|
|
|
- "error_description=\"The token provided has insufficient scope [] for this request\", " +
|
|
|
- "error_uri=\"https://tools.ietf.org/html/rfc6750#section-3.1\""));
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- @Test
|
|
|
- public void handleWhenTokenHasScopeAttributeThenInsufficientScopeErrorWithScopes() {
|
|
|
- Map<String, Object> attributes = Maps.newHashMap("scope", "message:read message:write");
|
|
|
- Authentication token = new TestingOAuth2TokenAuthenticationToken(attributes);
|
|
|
- ServerWebExchange exchange = mock(ServerWebExchange.class);
|
|
|
- when(exchange.getPrincipal()).thenReturn(Mono.just(token));
|
|
|
- when(exchange.getResponse()).thenReturn(new MockServerHttpResponse());
|
|
|
-
|
|
|
- this.accessDeniedHandler.handle(exchange, null).block();
|
|
|
-
|
|
|
- assertThat(exchange.getResponse().getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
|
|
- assertThat(exchange.getResponse().getHeaders().get("WWW-Authenticate")).isEqualTo(
|
|
|
- Arrays.asList("Bearer error=\"insufficient_scope\", " +
|
|
|
- "error_description=\"The token provided has insufficient scope [message:read message:write] for this request\", " +
|
|
|
- "error_uri=\"https://tools.ietf.org/html/rfc6750#section-3.1\", " +
|
|
|
- "scope=\"message:read message:write\""));
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- public void handleWhenTokenHasEmptyScopeAttributeThenInsufficientScopeError() {
|
|
|
- Map<String, Object> attributes = Maps.newHashMap("scope", "");
|
|
|
- Authentication token = new TestingOAuth2TokenAuthenticationToken(attributes);
|
|
|
- ServerWebExchange exchange = mock(ServerWebExchange.class);
|
|
|
- when(exchange.getPrincipal()).thenReturn(Mono.just(token));
|
|
|
- when(exchange.getResponse()).thenReturn(new MockServerHttpResponse());
|
|
|
-
|
|
|
- this.accessDeniedHandler.handle(exchange, null).block();
|
|
|
-
|
|
|
- assertThat(exchange.getResponse().getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
|
|
- assertThat(exchange.getResponse().getHeaders().get("WWW-Authenticate")).isEqualTo(
|
|
|
- Arrays.asList("Bearer error=\"insufficient_scope\", " +
|
|
|
- "error_description=\"The token provided has insufficient scope [] for this request\", " +
|
|
|
- "error_uri=\"https://tools.ietf.org/html/rfc6750#section-3.1\""));
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- public void handleWhenTokenHasScpAttributeThenInsufficientScopeErrorWithScopes() {
|
|
|
- Map<String, Object> attributes = Maps.newHashMap("scp", Arrays.asList("message:read", "message:write"));
|
|
|
- Authentication token = new TestingOAuth2TokenAuthenticationToken(attributes);
|
|
|
- ServerWebExchange exchange = mock(ServerWebExchange.class);
|
|
|
- when(exchange.getPrincipal()).thenReturn(Mono.just(token));
|
|
|
- when(exchange.getResponse()).thenReturn(new MockServerHttpResponse());
|
|
|
-
|
|
|
- this.accessDeniedHandler.handle(exchange, null).block();
|
|
|
-
|
|
|
- assertThat(exchange.getResponse().getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
|
|
- assertThat(exchange.getResponse().getHeaders().get("WWW-Authenticate")).isEqualTo(
|
|
|
- Arrays.asList("Bearer error=\"insufficient_scope\", " +
|
|
|
- "error_description=\"The token provided has insufficient scope [message:read message:write] for this request\", " +
|
|
|
- "error_uri=\"https://tools.ietf.org/html/rfc6750#section-3.1\", " +
|
|
|
- "scope=\"message:read message:write\""));
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- public void handleWhenTokenHasEmptyScpAttributeThenInsufficientScopeError() {
|
|
|
-
|
|
|
- Map<String, Object> attributes = Maps.newHashMap("scp", Collections.emptyList());
|
|
|
- Authentication token = new TestingOAuth2TokenAuthenticationToken(attributes);
|
|
|
- ServerWebExchange exchange = mock(ServerWebExchange.class);
|
|
|
- when(exchange.getPrincipal()).thenReturn(Mono.just(token));
|
|
|
- when(exchange.getResponse()).thenReturn(new MockServerHttpResponse());
|
|
|
-
|
|
|
- this.accessDeniedHandler.handle(exchange, null).block();
|
|
|
-
|
|
|
- assertThat(exchange.getResponse().getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
|
|
- assertThat(exchange.getResponse().getHeaders().get("WWW-Authenticate")).isEqualTo(
|
|
|
- Arrays.asList("Bearer error=\"insufficient_scope\", " +
|
|
|
- "error_description=\"The token provided has insufficient scope [] for this request\", " +
|
|
|
+ "error_description=\"The request requires higher privileges than provided by the access token.\", " +
|
|
|
"error_uri=\"https://tools.ietf.org/html/rfc6750#section-3.1\""));
|
|
|
}
|
|
|
|
|
|
- @Test
|
|
|
- public void handleWhenTokenHasBothScopeAndScpAttributesTheInsufficientErrorBasedOnScopeAttribute() {
|
|
|
- Map<String, Object> attributes = Maps.newHashMap("scp", Arrays.asList("message:read", "message:write"));
|
|
|
- attributes.put("scope", "missive:read missive:write");
|
|
|
- Authentication token = new TestingOAuth2TokenAuthenticationToken(attributes);
|
|
|
- ServerWebExchange exchange = mock(ServerWebExchange.class);
|
|
|
- when(exchange.getPrincipal()).thenReturn(Mono.just(token));
|
|
|
- when(exchange.getResponse()).thenReturn(new MockServerHttpResponse());
|
|
|
-
|
|
|
- this.accessDeniedHandler.handle(exchange, null).block();
|
|
|
-
|
|
|
- assertThat(exchange.getResponse().getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
|
|
- assertThat(exchange.getResponse().getHeaders().get("WWW-Authenticate")).isEqualTo(
|
|
|
- Arrays.asList("Bearer error=\"insufficient_scope\", " +
|
|
|
- "error_description=\"The token provided has insufficient scope [missive:read missive:write] for this request\", " +
|
|
|
- "error_uri=\"https://tools.ietf.org/html/rfc6750#section-3.1\", " +
|
|
|
- "scope=\"missive:read missive:write\""));
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- public void handleWhenTokenHasScopeAttributeAndRealmIsSetThenInsufficientScopeErrorWithScopesAndRealm() {
|
|
|
- Map<String, Object> attributes = Maps.newHashMap("scope", "message:read message:write");
|
|
|
- Authentication token = new TestingOAuth2TokenAuthenticationToken(attributes);
|
|
|
- ServerWebExchange exchange = mock(ServerWebExchange.class);
|
|
|
- when(exchange.getPrincipal()).thenReturn(Mono.just(token));
|
|
|
- when(exchange.getResponse()).thenReturn(new MockServerHttpResponse());
|
|
|
-
|
|
|
- this.accessDeniedHandler.setRealmName("test");
|
|
|
- this.accessDeniedHandler.handle(exchange, null).block();
|
|
|
-
|
|
|
- assertThat(exchange.getResponse().getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
|
|
- assertThat(exchange.getResponse().getHeaders().get("WWW-Authenticate"))
|
|
|
- .isEqualTo(Arrays.asList("Bearer realm=\"test\", " +
|
|
|
- "error=\"insufficient_scope\", " +
|
|
|
- "error_description=\"The token provided has insufficient scope [message:read message:write] for this request\", " +
|
|
|
- "error_uri=\"https://tools.ietf.org/html/rfc6750#section-3.1\", " +
|
|
|
- "scope=\"message:read message:write\""));
|
|
|
- }
|
|
|
-
|
|
|
@Test
|
|
|
public void setRealmNameWhenNullRealmNameThenNoExceptionThrown() {
|
|
|
assertThatCode(() -> this.accessDeniedHandler.setRealmName(null))
|