@Override public <T extends Principal> Mono<T> getPrincipal() { return this.delegate.getPrincipal(); }
@Override public Mono<? extends Principal> principal() { return this.exchange.getPrincipal(); }
@Override public Mono<? extends Principal> principal() { return this.exchange.getPrincipal(); }
@SuppressWarnings("unchecked") @Override public <T extends Principal> Mono<T> getPrincipal() { return (this.principalMono != null ? (Mono<T>) this.principalMono : getDelegate().getPrincipal()); } }
@Override public <T extends Principal> Mono<T> getPrincipal() { return getDelegate().getPrincipal(); }
@SuppressWarnings("unchecked") @Override public <T extends Principal> Mono<T> getPrincipal() { return (this.principalMono != null ? (Mono<T>) this.principalMono : getDelegate().getPrincipal()); } }
@Override public <T extends Principal> Mono<T> getPrincipal() { return getDelegate().getPrincipal(); }
@Override public Mono<Object> resolveArgument( MethodParameter parameter, BindingContext context, ServerWebExchange exchange) { Mono<Principal> principal = exchange.getPrincipal(); ReactiveAdapter adapter = getAdapterRegistry().getAdapter(parameter.getParameterType()); return (adapter != null ? Mono.just(adapter.fromPublisher(principal)) : Mono.from(principal)); }
@Override public Mono<String> resolve(ServerWebExchange exchange) { return exchange.getPrincipal().map(Principal::getName).switchIfEmpty(Mono.empty()); } }
private HandshakeInfo createHandshakeInfo(ServerWebExchange exchange, ServerHttpRequest request, @Nullable String protocol, Map<String, Object> attributes) { URI uri = request.getURI(); // Copy request headers, as they might be pooled and recycled by // the server implementation once the handshake HTTP exchange is done. HttpHeaders headers = new HttpHeaders(); headers.addAll(request.getHeaders()); Mono<Principal> principal = exchange.getPrincipal(); String logPrefix = exchange.getLogPrefix(); InetSocketAddress remoteAddress = request.getRemoteAddress(); return new HandshakeInfo(uri, headers, principal, protocol, remoteAddress, attributes, logPrefix); }
@Override public Mono<Void> handle(ServerWebExchange exchange, AccessDeniedException denied) { Map<String, String> parameters = new LinkedHashMap<>(); if (this.realmName != null) { parameters.put("realm", this.realmName); } return exchange.getPrincipal() .filter(AbstractOAuth2TokenAuthenticationToken.class::isInstance) .cast(AbstractOAuth2TokenAuthenticationToken.class) .map(token -> errorMessageParameters(token, parameters)) .switchIfEmpty(Mono.just(parameters)) .flatMap(params -> respond(exchange, params)); }
@Test public void handleWhenNotOAuth2AuthenticatedThenStatus403() { Authentication token = new TestingAuthenticationToken("user", "pass"); 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")); }
@Test public void handleWhenTokenHasNoScopesThenInsufficientScopeError() { Authentication token = new TestingOAuth2TokenAuthenticationToken(Collections.emptyMap()); 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 handleWhenNotOAuth2AuthenticatedAndRealmSetThenStatus403AndAuthHeaderWithRealm() { Authentication token = new TestingAuthenticationToken("user", "pass"); 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\"")); }
@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_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 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 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 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\"")); }