Configure logoutHandler and logoutSuccessHandler as Beans (#938)
* Keep the given query parameter when redirecting the login url Signed-off-by: Natalia Kislicyn <natalia.kislicyn@bosch-si.com> * Make logout endpoint configurable via properties; Undo query parameter acceptance when redirecting the login url Signed-off-by: Natalia Kislicyn <natalia.kislicyn@bosch-si.com> * make logout base variable non static Signed-off-by: Natalia Kislicyn <natalia.kislicyn@bosch-si.com> * Redo query parameter acceptance when redirecting the login url Signed-off-by: Natalia Kislicyn <natalia.kislicyn@bosch-si.com> * Remove tenant redirection in RedirectController Signed-off-by: Natalia Kislicyn <natalia.kislicyn@bosch-si.com> * Configure logoutHandler and logoutSuccessHandler with Beans Signed-off-by: Natalia Kislicyn <natalia.kislicyn@bosch-si.com> * Undo logout endpoint configuration via properties; Signed-off-by: Natalia Kislicyn <natalia.kislicyn@bosch-si.com> * remove authenticationEntryPoint configuration; fix review issues Signed-off-by: Natalia Kislicyn <natalia.kislicyn@bosch-si.com> * adopt review comments Signed-off-by: Natalia Kislicyn <natalia.kislicyn@bosch-si.com>
This commit is contained in:
@@ -61,7 +61,9 @@ import org.springframework.security.oauth2.server.resource.authentication.JwtAut
|
|||||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
||||||
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
|
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
|
||||||
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
||||||
|
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
||||||
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
|
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
|
||||||
|
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
@@ -86,11 +88,20 @@ public class OidcUserManagementAutoConfiguration {
|
|||||||
return new JwtAuthoritiesOidcUserService(extractor);
|
return new JwtAuthoritiesOidcUserService(extractor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the logout success handler for OpenID Connect
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public LogoutSuccessHandler oidcLogoutSuccessHandler() {
|
||||||
|
SimpleUrlLogoutSuccessHandler logoutSuccessHandler = new SimpleUrlLogoutSuccessHandler();
|
||||||
|
logoutSuccessHandler.setDefaultTargetUrl("/");
|
||||||
|
return logoutSuccessHandler;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the OpenID Connect authentication success handler
|
* @return the OpenID Connect authentication success handler
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
|
||||||
public AuthenticationSuccessHandler oidcAuthenticationSuccessHandler() {
|
public AuthenticationSuccessHandler oidcAuthenticationSuccessHandler() {
|
||||||
return new OidcAuthenticationSuccessHandler();
|
return new OidcAuthenticationSuccessHandler();
|
||||||
}
|
}
|
||||||
@@ -99,7 +110,6 @@ public class OidcUserManagementAutoConfiguration {
|
|||||||
* @return the OpenID Connect logout handler
|
* @return the OpenID Connect logout handler
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
|
||||||
public LogoutHandler oidcLogoutHandler() {
|
public LogoutHandler oidcLogoutHandler() {
|
||||||
return new OidcLogoutHandler();
|
return new OidcLogoutHandler();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.data.domain.AuditorAware;
|
import org.springframework.data.domain.AuditorAware;
|
||||||
|
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
||||||
|
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
|
||||||
|
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
||||||
|
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
||||||
|
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
|
||||||
|
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link EnableAutoConfiguration Auto-configuration} for security.
|
* {@link EnableAutoConfiguration Auto-configuration} for security.
|
||||||
@@ -52,9 +58,9 @@ public class SecurityAutoConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the auditore aware.
|
* Creates the auditor aware.
|
||||||
*
|
*
|
||||||
* @return the spring security auditore aware
|
* @return the spring security auditor aware
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
@@ -82,4 +88,33 @@ public class SecurityAutoConfiguration {
|
|||||||
return new SecurityTokenGenerator();
|
return new SecurityTokenGenerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link AuthenticationSuccessHandler} bean
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public AuthenticationSuccessHandler authenticationSuccessHandler() {
|
||||||
|
return new SimpleUrlAuthenticationSuccessHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link LogoutHandler} bean
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public LogoutHandler logoutHandler() {
|
||||||
|
return new SecurityContextLogoutHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link LogoutSuccessHandler} bean
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public LogoutSuccessHandler logoutSuccessHandler() {
|
||||||
|
final SimpleUrlLogoutSuccessHandler simpleUrlLogoutSuccessHandler = new SimpleUrlLogoutSuccessHandler();
|
||||||
|
simpleUrlLogoutSuccessHandler.setTargetUrlParameter("login");
|
||||||
|
return simpleUrlLogoutSuccessHandler;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ import org.springframework.security.web.authentication.AnonymousAuthenticationFi
|
|||||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
||||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||||
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
||||||
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
|
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
||||||
import org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter;
|
import org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter;
|
||||||
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
|
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
|
||||||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
||||||
@@ -236,12 +236,12 @@ public class SecurityManagedConfiguration {
|
|||||||
LOG.info(
|
LOG.info(
|
||||||
"******************\n** Anonymous controller security enabled, should only be used for developing purposes **\n******************");
|
"******************\n** Anonymous controller security enabled, should only be used for developing purposes **\n******************");
|
||||||
|
|
||||||
final AnonymousAuthenticationFilter anoymousFilter = new AnonymousAuthenticationFilter(
|
final AnonymousAuthenticationFilter anonymousFilter = new AnonymousAuthenticationFilter(
|
||||||
"controllerAnonymousFilter", "anonymous",
|
"controllerAnonymousFilter", "anonymous",
|
||||||
Arrays.asList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS)));
|
Arrays.asList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS)));
|
||||||
anoymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
|
anonymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
|
||||||
httpSec.requestMatchers().antMatchers(DDI_ANT_MATCHERS).and().securityContext().disable().anonymous()
|
httpSec.requestMatchers().antMatchers(DDI_ANT_MATCHERS).and().securityContext().disable().anonymous()
|
||||||
.authenticationFilter(anoymousFilter);
|
.authenticationFilter(anonymousFilter);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
httpSec.addFilter(securityHeaderFilter).addFilter(securityTokenFilter)
|
httpSec.addFilter(securityHeaderFilter).addFilter(securityTokenFilter)
|
||||||
@@ -358,12 +358,12 @@ public class SecurityManagedConfiguration {
|
|||||||
LOG.info(
|
LOG.info(
|
||||||
"******************\n** Anonymous controller security enabled, should only be used for developing purposes **\n******************");
|
"******************\n** Anonymous controller security enabled, should only be used for developing purposes **\n******************");
|
||||||
|
|
||||||
final AnonymousAuthenticationFilter anoymousFilter = new AnonymousAuthenticationFilter(
|
final AnonymousAuthenticationFilter anonymousFilter = new AnonymousAuthenticationFilter(
|
||||||
"controllerAnonymousFilter", "anonymous",
|
"controllerAnonymousFilter", "anonymous",
|
||||||
Arrays.asList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS)));
|
Arrays.asList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS)));
|
||||||
anoymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
|
anonymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
|
||||||
httpSec.requestMatchers().antMatchers(DDI_DL_ANT_MATCHER).and().securityContext().disable().anonymous()
|
httpSec.requestMatchers().antMatchers(DDI_DL_ANT_MATCHER).and().securityContext().disable().anonymous()
|
||||||
.authenticationFilter(anoymousFilter);
|
.authenticationFilter(anonymousFilter);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
httpSec.addFilter(securityHeaderFilter).addFilter(securityTokenFilter)
|
httpSec.addFilter(securityHeaderFilter).addFilter(securityTokenFilter)
|
||||||
@@ -421,7 +421,7 @@ public class SecurityManagedConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Websecruity config to handle and filter the download ids.
|
* A Websecurity config to handle and filter the download ids.
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@@ -608,15 +608,19 @@ public class SecurityManagedConfiguration {
|
|||||||
|
|
||||||
private final VaadinUrlAuthenticationSuccessHandler handler;
|
private final VaadinUrlAuthenticationSuccessHandler handler;
|
||||||
|
|
||||||
@Autowired(required = false)
|
|
||||||
private AuthenticationSuccessHandler oidcAuthenticationSuccessHandler;
|
|
||||||
|
|
||||||
@Autowired(required = false)
|
|
||||||
private LogoutHandler oidcLogoutHandler;
|
|
||||||
|
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;
|
private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private AuthenticationSuccessHandler authenticationSuccessHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private LogoutHandler logoutHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private LogoutSuccessHandler logoutSuccessHandler;
|
||||||
|
|
||||||
|
|
||||||
public UISecurityConfigurationAdapter(final VaadinRedirectStrategy redirectStrategy) {
|
public UISecurityConfigurationAdapter(final VaadinRedirectStrategy redirectStrategy) {
|
||||||
handler = new TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler();
|
handler = new TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler();
|
||||||
handler.setRedirectStrategy(redirectStrategy);
|
handler.setRedirectStrategy(redirectStrategy);
|
||||||
@@ -673,7 +677,7 @@ public class SecurityManagedConfiguration {
|
|||||||
/**
|
/**
|
||||||
* Listener to redirect to login page after session timeout. Close the
|
* Listener to redirect to login page after session timeout. Close the
|
||||||
* vaadin session, because it's is not possible to redirect in
|
* vaadin session, because it's is not possible to redirect in
|
||||||
* atmospehere.
|
* atmosphere.
|
||||||
*
|
*
|
||||||
* @return the servlet listener.
|
* @return the servlet listener.
|
||||||
*/
|
*/
|
||||||
@@ -685,14 +689,13 @@ public class SecurityManagedConfiguration {
|
|||||||
@Override
|
@Override
|
||||||
protected void configure(final HttpSecurity http) throws Exception {
|
protected void configure(final HttpSecurity http) throws Exception {
|
||||||
|
|
||||||
final boolean enableOidc = oidcUserService != null && oidcAuthenticationSuccessHandler != null
|
final boolean enableOidc = oidcUserService != null && authenticationSuccessHandler != null;
|
||||||
&& oidcLogoutHandler != null;
|
|
||||||
|
|
||||||
// workaround regex: we need to exclude the URL /UI/HEARTBEAT here
|
// workaround regex: we need to exclude the URL /UI/HEARTBEAT here
|
||||||
// because we bound the vaadin application to /UI and not to root,
|
// because we bound the vaadin application to /UI and not to root,
|
||||||
// described in vaadin-forum:
|
// described in vaadin-forum:
|
||||||
// https://vaadin.com/forum#!/thread/3200565.
|
// https://vaadin.com/forum#!/thread/3200565.
|
||||||
HttpSecurity httpSec = null;
|
HttpSecurity httpSec;
|
||||||
if (enableOidc) {
|
if (enableOidc) {
|
||||||
httpSec = http.regexMatcher("(?!.*HEARTBEAT)^.*\\/(UI|oauth2).*$");
|
httpSec = http.regexMatcher("(?!.*HEARTBEAT)^.*\\/(UI|oauth2).*$");
|
||||||
} else {
|
} else {
|
||||||
@@ -713,27 +716,23 @@ public class SecurityManagedConfiguration {
|
|||||||
httpSec.headers().contentSecurityPolicy(hawkbitSecurityProperties.getContentSecurityPolicy());
|
httpSec.headers().contentSecurityPolicy(hawkbitSecurityProperties.getContentSecurityPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enableOidc) {
|
// UI
|
||||||
httpSec.authorizeRequests().antMatchers("/UI/login/**").permitAll().antMatchers("/UI/UIDL/**")
|
httpSec.authorizeRequests().antMatchers("/UI/login/**", "/UI/UIDL/**").permitAll()
|
||||||
.permitAll().anyRequest().authenticated().and()
|
.anyRequest().authenticated();
|
||||||
// OIDC
|
|
||||||
.oauth2Login().userInfoEndpoint().oidcUserService(oidcUserService).and()
|
|
||||||
.successHandler(oidcAuthenticationSuccessHandler).and().oauth2Client().and()
|
|
||||||
// logout
|
|
||||||
.logout().logoutUrl("/UI/logout").addLogoutHandler(oidcLogoutHandler).logoutSuccessUrl("/");
|
|
||||||
} else {
|
|
||||||
final SimpleUrlLogoutSuccessHandler simpleUrlLogoutSuccessHandler = new SimpleUrlLogoutSuccessHandler();
|
|
||||||
simpleUrlLogoutSuccessHandler.setTargetUrlParameter("login");
|
|
||||||
|
|
||||||
httpSec
|
if (enableOidc) {
|
||||||
// UI
|
// OIDC
|
||||||
.authorizeRequests().antMatchers("/UI/login/**").permitAll().antMatchers("/UI/UIDL/**")
|
httpSec.oauth2Login().userInfoEndpoint().oidcUserService(oidcUserService).and()
|
||||||
.permitAll().anyRequest().authenticated().and()
|
.successHandler(authenticationSuccessHandler).and().oauth2Client();
|
||||||
// UI login / logout
|
} else {
|
||||||
.exceptionHandling()
|
// UI login / Basic auth
|
||||||
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/UI/login/#/")).and().logout()
|
httpSec.exceptionHandling().authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/UI/login"));
|
||||||
.logoutUrl("/UI/logout").logoutSuccessHandler(simpleUrlLogoutSuccessHandler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UI logout
|
||||||
|
httpSec.logout().logoutUrl("/UI/logout*").addLogoutHandler(logoutHandler)
|
||||||
|
.logoutSuccessHandler(logoutSuccessHandler);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -780,7 +779,7 @@ class TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler extends
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sevletfilter to create metadata after successful authentication over RESTful.
|
* Servletfilter to create metadata after successful authentication over RESTful.
|
||||||
*/
|
*/
|
||||||
class AuthenticationSuccessTenantMetadataCreationFilter implements Filter {
|
class AuthenticationSuccessTenantMetadataCreationFilter implements Filter {
|
||||||
|
|
||||||
@@ -817,4 +816,5 @@ class AuthenticationSuccessTenantMetadataCreationFilter implements Filter {
|
|||||||
public void destroy() {
|
public void destroy() {
|
||||||
// not needed
|
// not needed
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ package org.eclipse.hawkbit.ui.menu;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.HawkbitServerProperties;
|
import org.eclipse.hawkbit.HawkbitServerProperties;
|
||||||
|
|||||||
Reference in New Issue
Block a user