diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/OidcUserManagementAutoConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/OidcUserManagementAutoConfiguration.java index 46d372fef..907751a36 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/OidcUserManagementAutoConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/OidcUserManagementAutoConfiguration.java @@ -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.SavedRequestAwareAuthenticationSuccessHandler; 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; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import org.springframework.web.client.RestTemplate; @@ -86,11 +88,20 @@ public class OidcUserManagementAutoConfiguration { 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 */ @Bean - @ConditionalOnMissingBean public AuthenticationSuccessHandler oidcAuthenticationSuccessHandler() { return new OidcAuthenticationSuccessHandler(); } @@ -99,7 +110,6 @@ public class OidcUserManagementAutoConfiguration { * @return the OpenID Connect logout handler */ @Bean - @ConditionalOnMissingBean public LogoutHandler oidcLogoutHandler() { return new OidcLogoutHandler(); } diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java index 84ffb994d..35395c21c 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java @@ -22,6 +22,12 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 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. @@ -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 @ConditionalOnMissingBean @@ -82,4 +88,33 @@ public class SecurityAutoConfiguration { 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; + } + } diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java index 2f6f4d5d4..655a8bc1c 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java @@ -86,7 +86,7 @@ import org.springframework.security.web.authentication.AnonymousAuthenticationFi import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; 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.www.BasicAuthenticationEntryPoint; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; @@ -236,12 +236,12 @@ public class SecurityManagedConfiguration { LOG.info( "******************\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", Arrays.asList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS))); - anoymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource); + anonymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource); httpSec.requestMatchers().antMatchers(DDI_ANT_MATCHERS).and().securityContext().disable().anonymous() - .authenticationFilter(anoymousFilter); + .authenticationFilter(anonymousFilter); } else { httpSec.addFilter(securityHeaderFilter).addFilter(securityTokenFilter) @@ -358,12 +358,12 @@ public class SecurityManagedConfiguration { LOG.info( "******************\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", 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() - .authenticationFilter(anoymousFilter); + .authenticationFilter(anonymousFilter); } else { 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 @EnableWebSecurity @@ -608,15 +608,19 @@ public class SecurityManagedConfiguration { private final VaadinUrlAuthenticationSuccessHandler handler; - @Autowired(required = false) - private AuthenticationSuccessHandler oidcAuthenticationSuccessHandler; - - @Autowired(required = false) - private LogoutHandler oidcLogoutHandler; - @Autowired(required = false) private OAuth2UserService oidcUserService; + @Autowired(required = false) + private AuthenticationSuccessHandler authenticationSuccessHandler; + + @Autowired + private LogoutHandler logoutHandler; + + @Autowired + private LogoutSuccessHandler logoutSuccessHandler; + + public UISecurityConfigurationAdapter(final VaadinRedirectStrategy redirectStrategy) { handler = new TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler(); handler.setRedirectStrategy(redirectStrategy); @@ -673,7 +677,7 @@ public class SecurityManagedConfiguration { /** * Listener to redirect to login page after session timeout. Close the * vaadin session, because it's is not possible to redirect in - * atmospehere. + * atmosphere. * * @return the servlet listener. */ @@ -685,14 +689,13 @@ public class SecurityManagedConfiguration { @Override protected void configure(final HttpSecurity http) throws Exception { - final boolean enableOidc = oidcUserService != null && oidcAuthenticationSuccessHandler != null - && oidcLogoutHandler != null; + final boolean enableOidc = oidcUserService != null && authenticationSuccessHandler != null; // workaround regex: we need to exclude the URL /UI/HEARTBEAT here // because we bound the vaadin application to /UI and not to root, // described in vaadin-forum: // https://vaadin.com/forum#!/thread/3200565. - HttpSecurity httpSec = null; + HttpSecurity httpSec; if (enableOidc) { httpSec = http.regexMatcher("(?!.*HEARTBEAT)^.*\\/(UI|oauth2).*$"); } else { @@ -713,27 +716,23 @@ public class SecurityManagedConfiguration { httpSec.headers().contentSecurityPolicy(hawkbitSecurityProperties.getContentSecurityPolicy()); } - if (enableOidc) { - httpSec.authorizeRequests().antMatchers("/UI/login/**").permitAll().antMatchers("/UI/UIDL/**") - .permitAll().anyRequest().authenticated().and() - // 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"); + // UI + httpSec.authorizeRequests().antMatchers("/UI/login/**", "/UI/UIDL/**").permitAll() + .anyRequest().authenticated(); - httpSec - // UI - .authorizeRequests().antMatchers("/UI/login/**").permitAll().antMatchers("/UI/UIDL/**") - .permitAll().anyRequest().authenticated().and() - // UI login / logout - .exceptionHandling() - .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/UI/login/#/")).and().logout() - .logoutUrl("/UI/logout").logoutSuccessHandler(simpleUrlLogoutSuccessHandler); + if (enableOidc) { + // OIDC + httpSec.oauth2Login().userInfoEndpoint().oidcUserService(oidcUserService).and() + .successHandler(authenticationSuccessHandler).and().oauth2Client(); + } else { + // UI login / Basic auth + httpSec.exceptionHandling().authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/UI/login")); } + + // UI logout + httpSec.logout().logoutUrl("/UI/logout*").addLogoutHandler(logoutHandler) + .logoutSuccessHandler(logoutSuccessHandler); + } @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 { @@ -817,4 +816,5 @@ class AuthenticationSuccessTenantMetadataCreationFilter implements Filter { public void destroy() { // not needed } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java index a5d818bf7..7b9135ddd 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java @@ -15,7 +15,6 @@ package org.eclipse.hawkbit.ui.menu; import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; import org.eclipse.hawkbit.HawkbitServerProperties;