From 5aa36f5696c05e4f56a0b00d447bafbab26ab936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Kov=C3=A1=C5=99=C3=ADk?= Date: Tue, 25 Jul 2017 17:12:23 +0200 Subject: [PATCH] WIP --- .../admin/config/AdminSecurityConfig.java | 68 ++++++++++++++++--- .../openhub/web/common/WebProps.java | 2 + .../src/main/resources/application.properties | 8 ++- 3 files changed, 64 insertions(+), 14 deletions(-) diff --git a/web-admin/src/main/java/org/openhubframework/openhub/admin/config/AdminSecurityConfig.java b/web-admin/src/main/java/org/openhubframework/openhub/admin/config/AdminSecurityConfig.java index 7dbb688e..7ac14edf 100644 --- a/web-admin/src/main/java/org/openhubframework/openhub/admin/config/AdminSecurityConfig.java +++ b/web-admin/src/main/java/org/openhubframework/openhub/admin/config/AdminSecurityConfig.java @@ -19,17 +19,32 @@ import static org.openhubframework.openhub.api.route.RouteConstants.WEB_URI_PREFIX; import static org.openhubframework.openhub.web.config.GlobalSecurityConfig.DEFAULT_PATH_PATTERN; +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.openhubframework.openhub.api.common.Constraints; +import org.openhubframework.openhub.api.configuration.ConfigurableValue; +import org.openhubframework.openhub.api.configuration.ConfigurationItem; +import org.openhubframework.openhub.web.common.WebProps; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.openhubframework.openhub.api.route.RouteConstants; import org.openhubframework.openhub.web.config.GlobalSecurityConfig; import org.openhubframework.openhub.web.config.WebSecurityConfig; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; +import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler; +import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; /** @@ -53,6 +68,9 @@ public class AdminSecurityConfig extends WebSecurityConfigurerAdapter { @Order(UiSecurityConfig.ORDER) public static class UiSecurityConfig extends AdminSecurityConfig { + @ConfigurableValue(key = WebProps.SESSION_CONCURRENCY_LIMIT) + private ConfigurationItem sessionConcurrencyLimit; + /** * Order of this {@link UiSecurityConfig}. Must be processed after * {@link WebSecurityConfig.WsSecurityConfig}. @@ -62,14 +80,10 @@ public static class UiSecurityConfig extends AdminSecurityConfig { private static final String LOGIN_PAGE_URL = WEB_URI_PREFIX + "login"; private static final String[] COOKIES_TO_DELETE = new String[]{"JSESSIONID"}; - @Override - public void configure(WebSecurity web) throws Exception { - // ignore security check for static resources - web.ignoring().antMatchers("/webjars/**", "/js/**", "/img/**", "/css/**"); - } - @Override protected void configure(HttpSecurity http) throws Exception { + Constraints.notNull(sessionConcurrencyLimit.getValue(), "the sessionConcurrencyLimit must be configured."); + // @formatter:off http.csrf().disable() // HTTP with disabled CSRF .authorizeRequests() //Authorize Request Configuration @@ -77,6 +91,8 @@ protected void configure(HttpSecurity http) throws Exception { .permitAll() .antMatchers(WEB_URI_PREFIX + "login/**") .permitAll() + .antMatchers(WEB_URI_PREFIX + "mgmt/info") + .permitAll() .antMatchers(WEB_URI_PREFIX + DEFAULT_PATH_PATTERN) .hasRole(GlobalSecurityConfig.AuthRole.WEB.name()) .antMatchers(WEB_URI_PREFIX + "**/*") @@ -87,7 +103,7 @@ protected void configure(HttpSecurity http) throws Exception { .formLogin() .loginPage(LOGIN_PAGE_URL) .loginProcessingUrl(LOGIN_PAGE_URL) - .defaultSuccessUrl(WEB_URI_PREFIX + "console") + .successHandler(authenticationSuccessHandler()) .failureUrl(WEB_URI_PREFIX + "login?error") .permitAll() .and() @@ -96,14 +112,44 @@ protected void configure(HttpSecurity http) throws Exception { .invalidateHttpSession(true) .deleteCookies(COOKIES_TO_DELETE) .logoutUrl(WEB_URI_PREFIX + "logout") - .logoutSuccessUrl(WEB_URI_PREFIX + "homepage") + .logoutSuccessHandler(logoutSuccessHandler()) + .and() + .exceptionHandling() + .authenticationEntryPoint(unauthorizedEntryPoint()) .and() .sessionManagement() - .maximumSessions(1) - .expiredUrl(LOGIN_PAGE_URL + "?expired"); + .maximumSessions(sessionConcurrencyLimit.getValue()) + .expiredUrl(LOGIN_PAGE_URL + "?expired") + ; // @formatter:on } } + + + // simple authenticationSuccessHandler, results in 200 OK response. + private static AuthenticationSuccessHandler authenticationSuccessHandler() { + return new SimpleUrlAuthenticationSuccessHandler() { + public void onAuthenticationSuccess(HttpServletRequest request, + HttpServletResponse response, Authentication authentication) + throws IOException, ServletException { + clearAuthenticationAttributes(request); + } + }; + } + + // logout successHandler, returns 200 OK response. + private static LogoutSuccessHandler logoutSuccessHandler() { + return new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK); + } + + // unauthorized entry point, return 401. + private static AuthenticationEntryPoint unauthorizedEntryPoint() { + return (request, response, authException) -> { + if (authException != null) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + } + }; + } } diff --git a/web-admin/src/main/java/org/openhubframework/openhub/web/common/WebProps.java b/web-admin/src/main/java/org/openhubframework/openhub/web/common/WebProps.java index 48c67abe..b8d755ae 100644 --- a/web-admin/src/main/java/org/openhubframework/openhub/web/common/WebProps.java +++ b/web-admin/src/main/java/org/openhubframework/openhub/web/common/WebProps.java @@ -29,6 +29,8 @@ public final class WebProps { public static final String MESSAGES_LIMIT = OpenHubPropertyConstants.PREFIX + "admin.console.messages.limit"; + public static final String SESSION_CONCURRENCY_LIMIT = OpenHubPropertyConstants.PREFIX + "admin.console.session-concurrency.limit"; + private WebProps() { // to prevent instantiation } diff --git a/web-admin/src/main/resources/application.properties b/web-admin/src/main/resources/application.properties index 14cb7f72..6de35a36 100644 --- a/web-admin/src/main/resources/application.properties +++ b/web-admin/src/main/resources/application.properties @@ -154,7 +154,6 @@ endpoints.loggers.path=/loggers jolokia.config.debug=true #jolokia.config.*= # See Jolokia manual - # =============================== # = MANAGEMENT HTTP SERVER # =============================== @@ -229,7 +228,7 @@ spring.mvc.static-path-pattern=/console/** #spring.resources.chain.strategy.fixed.enabled=false # Enable the fixed Version Strategy. #spring.resources.chain.strategy.fixed.paths=/** # Comma-separated list of patterns to apply to the Version Strategy. #spring.resources.chain.strategy.fixed.version= # Version string to use for the Version Strategy. - # Locations of static resources. +# Locations of static resources. spring.resources.static-locations=classpath:/META-INF/resources/console/ @@ -407,4 +406,7 @@ ohf.admin.console.config.menu.external-links.items[0].enabled = ${javamelody.ena ohf.admin.console.config.menu.changes.enabled = true # Messages api configuration -ohf.admin.console.messages.limit = 100 \ No newline at end of file +ohf.admin.console.messages.limit = 100 + +# Logged user session concurrency limit +ohf.admin.console.session-concurrency.limit = 2 \ No newline at end of file