private ServerAuthenticationEntryPoint getAuthenticationEntryPoint() { if (this.authenticationEntryPoint != null || this.defaultEntryPoints.isEmpty()) { return this.authenticationEntryPoint; } if (this.defaultEntryPoints.size() == 1) { return this.defaultEntryPoints.get(0).getEntryPoint(); } DelegatingServerAuthenticationEntryPoint result = new DelegatingServerAuthenticationEntryPoint(this.defaultEntryPoints); result.setDefaultEntryPoint(this.defaultEntryPoints.get(this.defaultEntryPoints.size() - 1).getEntryPoint()); return result; }
private void registerDefaultAuthenticationEntryPoint(ServerHttpSecurity http) { if (http.exceptionHandling != null) { http.defaultEntryPoints.add( new DelegateEntry( this.bearerTokenServerWebExchangeMatcher, OAuth2ResourceServerSpec.this.entryPoint ) ); } }
protected void configure(ServerHttpSecurity http) { MediaTypeServerWebExchangeMatcher restMatcher = new MediaTypeServerWebExchangeMatcher( MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_XML, MediaType.MULTIPART_FORM_DATA, MediaType.TEXT_XML); restMatcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL)); ServerHttpSecurity.this.defaultEntryPoints.add(new DelegateEntry(restMatcher, this.entryPoint)); AuthenticationWebFilter authenticationFilter = new AuthenticationWebFilter( this.authenticationManager); authenticationFilter.setAuthenticationFailureHandler(new ServerAuthenticationEntryPointFailureHandler(this.entryPoint)); authenticationFilter.setAuthenticationConverter(new ServerHttpBasicAuthenticationConverter()); if (this.securityContextRepository != null) { authenticationFilter.setSecurityContextRepository(this.securityContextRepository); } http.addFilterAt(authenticationFilter, SecurityWebFiltersOrder.HTTP_BASIC); }
protected void configure(ServerHttpSecurity http) { if (this.authenticationEntryPoint == null) { this.isEntryPointExplicit = false; loginPage("/login"); } else { this.isEntryPointExplicit = true; } if (http.requestCache != null) { ServerRequestCache requestCache = http.requestCache.requestCache; this.defaultSuccessHandler.setRequestCache(requestCache); if (this.defaultEntryPoint != null) { this.defaultEntryPoint.setRequestCache(requestCache); } } MediaTypeServerWebExchangeMatcher htmlMatcher = new MediaTypeServerWebExchangeMatcher( MediaType.TEXT_HTML); htmlMatcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL)); ServerHttpSecurity.this.defaultEntryPoints.add(0, new DelegateEntry(htmlMatcher, this.authenticationEntryPoint)); AuthenticationWebFilter authenticationFilter = new AuthenticationWebFilter( this.authenticationManager); authenticationFilter.setRequiresAuthenticationMatcher(this.requiresAuthenticationMatcher); authenticationFilter.setAuthenticationFailureHandler(this.authenticationFailureHandler); authenticationFilter.setAuthenticationConverter(new ServerFormLoginAuthenticationConverter()); authenticationFilter.setAuthenticationSuccessHandler(this.authenticationSuccessHandler); authenticationFilter.setSecurityContextRepository(this.securityContextRepository); http.addFilterAt(authenticationFilter, SecurityWebFiltersOrder.FORM_LOGIN); }
protected void configure(ServerHttpSecurity http) { ReactiveClientRegistrationRepository clientRegistrationRepository = getClientRegistrationRepository(); ServerOAuth2AuthorizedClientRepository authorizedClientRepository = getAuthorizedClientRepository(); OAuth2AuthorizationRequestRedirectWebFilter oauthRedirectFilter = getRedirectWebFilter(); ReactiveAuthenticationManager manager = getAuthenticationManager(); AuthenticationWebFilter authenticationFilter = new OAuth2LoginAuthenticationWebFilter(manager, authorizedClientRepository); authenticationFilter.setRequiresAuthenticationMatcher(getAuthenticationMatcher()); authenticationFilter.setServerAuthenticationConverter(getAuthenticationConverter(clientRegistrationRepository)); RedirectServerAuthenticationSuccessHandler redirectHandler = new RedirectServerAuthenticationSuccessHandler(); authenticationFilter.setAuthenticationSuccessHandler(redirectHandler); authenticationFilter.setAuthenticationFailureHandler(new ServerAuthenticationFailureHandler() { @Override public Mono<Void> onAuthenticationFailure(WebFilterExchange webFilterExchange, AuthenticationException exception) { return Mono.error(exception); } }); authenticationFilter.setSecurityContextRepository(new WebSessionServerSecurityContextRepository()); MediaTypeServerWebExchangeMatcher htmlMatcher = new MediaTypeServerWebExchangeMatcher( MediaType.TEXT_HTML); htmlMatcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL)); Map<String, String> urlToText = http.oauth2Login.getLinks(); if (urlToText.size() == 1) { http.defaultEntryPoints.add(new DelegateEntry(htmlMatcher, new RedirectServerAuthenticationEntryPoint(urlToText.keySet().iterator().next()))); } else { http.defaultEntryPoints.add(new DelegateEntry(htmlMatcher, new RedirectServerAuthenticationEntryPoint("/login"))); } http.addFilterAt(oauthRedirectFilter, SecurityWebFiltersOrder.HTTP_BASIC); http.addFilterAt(authenticationFilter, SecurityWebFiltersOrder.AUTHENTICATION); }
this.addFilterAt(new SecurityContextServerWebExchangeWebFilter(), SecurityWebFiltersOrder.SECURITY_CONTEXT_SERVER_WEB_EXCHANGE); if (this.authorizeExchange != null) { ServerAuthenticationEntryPoint authenticationEntryPoint = getAuthenticationEntryPoint(); ExceptionTranslationWebFilter exceptionTranslationWebFilter = new ExceptionTranslationWebFilter(); if (authenticationEntryPoint != null) { exceptionTranslationWebFilter.setAuthenticationEntryPoint( authenticationEntryPoint); exceptionTranslationWebFilter.setAccessDeniedHandler( accessDeniedHandler); }); sortedWebFilters.add(0, new ServerWebExchangeReactorContextWebFilter()); return new MatcherSecurityWebFilterChain(getSecurityMatcher(), sortedWebFilters);
@Bean(SPRING_SECURITY_WEBFILTERCHAINFILTER_BEAN_NAME) @Order(value = WEB_FILTER_CHAIN_FILTER_ORDER) public WebFilterChainProxy springSecurityWebFilterChainFilter() { return new WebFilterChainProxy(getSecurityWebFilterChains()); }
@Override protected Mono<Void> onAuthenticationSuccess(Authentication authentication, WebFilterExchange webFilterExchange) { OAuth2LoginAuthenticationToken authenticationResult = (OAuth2LoginAuthenticationToken) authentication; OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient( authenticationResult.getClientRegistration(), authenticationResult.getName(), authenticationResult.getAccessToken(), authenticationResult.getRefreshToken()); OAuth2AuthenticationToken result = new OAuth2AuthenticationToken( authenticationResult.getPrincipal(), authenticationResult.getAuthorities(), authenticationResult.getClientRegistration().getRegistrationId()); return this.authorizedClientRepository.saveAuthorizedClient(authorizedClient, authenticationResult, webFilterExchange.getExchange()) .then(super.onAuthenticationSuccess(result, webFilterExchange)); } }
@Test public void requestCacheNoOp() { SecurityWebFilterChain securityWebFilter = this.http .authorizeExchange() .anyExchange().authenticated() .and() .formLogin().and() .requestCache() .requestCache(NoOpServerRequestCache.getInstance()) .and() .build(); WebTestClient webTestClient = WebTestClient .bindToController(new SecuredPageController(), new WebTestClientBuilder.Http200RestController()) .webFilter(new WebFilterChainProxy(securityWebFilter)) .build(); WebDriver driver = WebTestClientHtmlUnitDriverBuilder .webTestClientSetup(webTestClient) .build(); DefaultLoginPage loginPage = SecuredPage.to(driver, DefaultLoginPage.class) .assertAt(); HomePage securedPage = loginPage.loginForm() .username("user") .password("password") .submit(HomePage.class); securedPage.assertAt(); }
private Mono<Void> authenticate(ServerWebExchange exchange, WebFilterChain chain, Authentication token) { WebFilterExchange webFilterExchange = new WebFilterExchange(exchange, chain); return this.authenticationManager.authenticate(token) .switchIfEmpty(Mono.defer(() -> Mono.error(new IllegalStateException("No provider found for " + token.getClass())))) .flatMap(authentication -> onAuthenticationSuccess(authentication, webFilterExchange)) .onErrorResume(AuthenticationException.class, e -> this.authenticationFailureHandler .onAuthenticationFailure(webFilterExchange, e)); }
private Mono<Void> onAuthenticationSuccess(Authentication authentication, WebFilterExchange webFilterExchange) { OAuth2AuthorizationCodeAuthenticationToken authenticationResult = (OAuth2AuthorizationCodeAuthenticationToken) authentication; OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient( authenticationResult.getClientRegistration(), authenticationResult.getName(), authenticationResult.getAccessToken(), authenticationResult.getRefreshToken()); return this.authenticationSuccessHandler .onAuthenticationSuccess(webFilterExchange, authentication) .then(ReactiveSecurityContextHolder.getContext() .map(SecurityContext::getAuthentication) .defaultIfEmpty(this.anonymousToken) .flatMap(principal -> this.authorizedClientRepository.saveAuthorizedClient(authorizedClient, principal, webFilterExchange.getExchange())) ); } }
private <T extends WebFilter> Optional<T> getWebFilter(SecurityWebFilterChain filterChain, Class<T> filterClass) { return (Optional<T>) filterChain.getWebFilters() .filter(Objects::nonNull) .filter(filter -> filter.getClass().isAssignableFrom(filterClass)) .singleOrEmpty() .blockOptional(); }
@Before public void setup() { this.filter = new OAuth2LoginAuthenticationWebFilter(this.authenticationManager, this.authorizedClientRepository); this.webFilterExchange = new WebFilterExchange(MockServerWebExchange.from(MockServerHttpRequest.get("/")), new DefaultWebFilterChain(exchange -> exchange.getResponse().setComplete())); when(this.authorizedClientRepository.saveAuthorizedClient(any(), any(), any())) .thenReturn(Mono.empty()); }
private Mono<Void> sendRedirectForAuthorization(ServerWebExchange exchange, OAuth2AuthorizationRequest authorizationRequest) { return Mono.defer(() -> { Mono<Void> saveAuthorizationRequest = Mono.empty(); if (AuthorizationGrantType.AUTHORIZATION_CODE.equals(authorizationRequest.getGrantType())) { saveAuthorizationRequest = this.authorizationRequestRepository .saveAuthorizationRequest(authorizationRequest, exchange); } URI redirectUri = UriComponentsBuilder .fromUriString(authorizationRequest.getAuthorizationRequestUri()) .build(true).toUri(); return saveAuthorizationRequest .then(this.authorizationRedirectStrategy.sendRedirect(exchange, redirectUri)); }); } }
private WebTestClient buildClient() { WebFilterChainProxy springSecurityFilterChain = new WebFilterChainProxy( this.http.build()); return WebTestClientBuilder.bindToWebFilters(springSecurityFilterChain).build(); }
@Test @SuppressWarnings("unchecked") public void addFilterAfterIsApplied(){ SecurityWebFilterChain securityWebFilterChain = this.http.addFilterAfter(new TestWebFilter(), SecurityWebFiltersOrder.SECURITY_CONTEXT_SERVER_WEB_EXCHANGE).build(); List filters = securityWebFilterChain.getWebFilters().map(WebFilter::getClass).collectList().block(); assertThat(filters).isNotNull() .isNotEmpty() .containsSequence(SecurityContextServerWebExchangeWebFilter.class, TestWebFilter.class); }
@Test public void buildWhenServerWebExchangeFromContextThenFound() { SecurityWebFilterChain filter = this.http.build(); WebTestClient client = WebTestClient.bindToController(new SubscriberContextController()) .webFilter(new WebFilterChainProxy(filter)) .build(); client.get().uri("/foo/bar") .exchange() .expectBody(String.class).isEqualTo("/foo/bar"); }
@Test @SuppressWarnings("unchecked") public void addFilterBeforeIsApplied(){ SecurityWebFilterChain securityWebFilterChain = this.http.addFilterBefore(new TestWebFilter(), SecurityWebFiltersOrder.SECURITY_CONTEXT_SERVER_WEB_EXCHANGE).build(); List filters = securityWebFilterChain.getWebFilters().map(WebFilter::getClass).collectList().block(); assertThat(filters).isNotNull() .isNotEmpty() .containsSequence(TestWebFilter.class, SecurityContextServerWebExchangeWebFilter.class); }
@Test public void defaultFormLoginRequestCache() { SecurityWebFilterChain securityWebFilter = this.http .authorizeExchange() .anyExchange().authenticated() .and() .formLogin().and() .build(); WebTestClient webTestClient = WebTestClient .bindToController(new SecuredPageController(), new WebTestClientBuilder.Http200RestController()) .webFilter(new WebFilterChainProxy(securityWebFilter)) .build(); WebDriver driver = WebTestClientHtmlUnitDriverBuilder .webTestClientSetup(webTestClient) .build(); DefaultLoginPage loginPage = SecuredPage.to(driver, DefaultLoginPage.class) .assertAt(); SecuredPage securedPage = loginPage.loginForm() .username("user") .password("password") .submit(SecuredPage.class); securedPage.assertAt(); }
@Test public void customLoginPage() { SecurityWebFilterChain securityWebFilter = this.http .authorizeExchange() .pathMatchers("/login").permitAll() .anyExchange().authenticated() .and() .formLogin() .loginPage("/login") .and() .build(); WebTestClient webTestClient = WebTestClient .bindToController(new CustomLoginPageController(), new WebTestClientBuilder.Http200RestController()) .webFilter(new WebFilterChainProxy(securityWebFilter)) .build(); WebDriver driver = WebTestClientHtmlUnitDriverBuilder .webTestClientSetup(webTestClient) .build(); CustomLoginPage loginPage = HomePage.to(driver, CustomLoginPage.class) .assertAt(); HomePage homePage = loginPage.loginForm() .username("user") .password("password") .submit(HomePage.class); homePage.assertAt(); }