Skip to content

Commit

Permalink
disable creating of session for rest and actuator channels
Browse files Browse the repository at this point in the history
  • Loading branch information
skublik committed Jun 16, 2020
1 parent eb43ca3 commit c4e1dbe
Show file tree
Hide file tree
Showing 12 changed files with 350 additions and 133 deletions.
Expand Up @@ -8,9 +8,14 @@

import javax.servlet.DispatcherType;

import com.evolveum.midpoint.web.security.SessionAndRequestScopeImpl;

import org.apache.wicket.Application;
import org.apache.wicket.protocol.http.WicketFilter;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration;
Expand Down Expand Up @@ -139,4 +144,14 @@ public ErrorPageRegistrar errorPageRegistrar() {
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}

@Bean
public static BeanFactoryPostProcessor beanFactoryPostProcessor() {
return new BeanFactoryPostProcessor() {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException {
factory.registerScope("sessionAndRequest", new SessionAndRequestScopeImpl());
}
};
}
}
@@ -1,117 +1,121 @@
/*
* Copyright (c) 2010-2013 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.web.security;

import com.evolveum.midpoint.audit.api.AuditEventRecord;
import com.evolveum.midpoint.audit.api.AuditEventStage;
import com.evolveum.midpoint.audit.api.AuditEventType;
import com.evolveum.midpoint.audit.api.AuditService;
import com.evolveum.midpoint.gui.api.GuiConstants;
import com.evolveum.midpoint.gui.api.util.WebComponentUtil;
import com.evolveum.midpoint.model.api.authentication.MidpointAuthentication;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResultStatus;
import com.evolveum.midpoint.security.api.MidPointPrincipal;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.task.api.TaskManager;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.web.security.util.SecurityUtils;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
* @author lazyman
*/
public class AuditedLogoutHandler extends SimpleUrlLogoutSuccessHandler {

private static final Trace LOGGER = TraceManager.getTrace(AuditedLogoutHandler.class);

@Autowired
private TaskManager taskManager;
@Autowired
private AuditService auditService;

boolean useDefaultUrl = false;

private boolean useDefaultUrl() {
return useDefaultUrl;
}

@Override
public void setDefaultTargetUrl(String defaultTargetUrl) {
super.setDefaultTargetUrl(defaultTargetUrl);
this.useDefaultUrl = true;
}

@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException {

String targetUrl;
if (useDefaultUrl()) {
targetUrl = getDefaultTargetUrl();
} else {
targetUrl = GuiConstants.DEFAULT_PATH_AFTER_LOGOUT;
}

if (authentication instanceof MidpointAuthentication) {
MidpointAuthentication mpAuthentication = (MidpointAuthentication) authentication;
if (mpAuthentication.getAuthenticationChannel() != null) {
targetUrl = mpAuthentication.getAuthenticationChannel().getPathAfterLogout();
}
}

if (response.isCommitted()) {
LOGGER.debug("Response has already been committed. Unable to redirect to " + targetUrl);
} else {
getRedirectStrategy().sendRedirect(request, response, targetUrl);
}

auditEvent(request, authentication);
}

private void auditEvent(HttpServletRequest request, Authentication authentication) {
MidPointPrincipal principal = SecurityUtils.getPrincipalUser(authentication);
PrismObject<? extends FocusType> user = principal != null ? principal.getFocus().asPrismObject() : null;

String channel = SchemaConstants.CHANNEL_GUI_USER_URI;
if (authentication instanceof MidpointAuthentication
&& ((MidpointAuthentication) authentication).getAuthenticationChannel() != null) {
channel = ((MidpointAuthentication) authentication).getAuthenticationChannel().getChannelId();
}

Task task = taskManager.createTaskInstance();
task.setOwner(user);
task.setChannel(channel);

AuditEventRecord record = new AuditEventRecord(AuditEventType.TERMINATE_SESSION, AuditEventStage.REQUEST);
record.setInitiator(user);
record.setParameter(WebComponentUtil.getName(user, false));

record.setChannel(channel);
record.setTimestamp(System.currentTimeMillis());
record.setOutcome(OperationResultStatus.SUCCESS);

// probably not needed, as audit service would take care of it; but it doesn't hurt so let's keep it here
record.setHostIdentifier(request.getLocalName());
record.setRemoteHostAddress(request.getLocalAddr());
record.setNodeIdentifier(taskManager.getNodeId());
record.setSessionIdentifier(request.getRequestedSessionId());

auditService.audit(record, task);
}
}
/*
* Copyright (c) 2010-2013 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.web.security;

import com.evolveum.midpoint.audit.api.AuditEventRecord;
import com.evolveum.midpoint.audit.api.AuditEventStage;
import com.evolveum.midpoint.audit.api.AuditEventType;
import com.evolveum.midpoint.audit.api.AuditService;
import com.evolveum.midpoint.gui.api.GuiConstants;
import com.evolveum.midpoint.gui.api.util.WebComponentUtil;
import com.evolveum.midpoint.model.api.authentication.MidpointAuthentication;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResultStatus;
import com.evolveum.midpoint.security.api.MidPointPrincipal;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.task.api.TaskManager;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.web.security.util.SecurityUtils;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
* @author lazyman
*/
public class AuditedLogoutHandler extends SimpleUrlLogoutSuccessHandler {

private static final Trace LOGGER = TraceManager.getTrace(AuditedLogoutHandler.class);

@Autowired
private TaskManager taskManager;
@Autowired
private AuditService auditService;

boolean useDefaultUrl = false;

private boolean useDefaultUrl() {
return useDefaultUrl;
}

@Override
public void setDefaultTargetUrl(String defaultTargetUrl) {
super.setDefaultTargetUrl(defaultTargetUrl);
this.useDefaultUrl = true;
}

@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException {

String targetUrl;
if (useDefaultUrl()) {
targetUrl = getDefaultTargetUrl();
} else {
targetUrl = GuiConstants.DEFAULT_PATH_AFTER_LOGOUT;
}

if (authentication instanceof MidpointAuthentication) {
MidpointAuthentication mpAuthentication = (MidpointAuthentication) authentication;
if (mpAuthentication.getAuthenticationChannel() != null) {
targetUrl = mpAuthentication.getAuthenticationChannel().getPathAfterLogout();
}
}

if (response.isCommitted()) {
LOGGER.debug("Response has already been committed. Unable to redirect to " + targetUrl);
} else {
getRedirectStrategy().sendRedirect(request, response, targetUrl);
}

auditEvent(request, authentication);
}

private void auditEvent(HttpServletRequest request, Authentication authentication) {
MidPointPrincipal principal = SecurityUtils.getPrincipalUser(authentication);
PrismObject<? extends FocusType> user = principal != null ? principal.getFocus().asPrismObject() : null;

String channel = SchemaConstants.CHANNEL_GUI_USER_URI;
String sessionId = request.getRequestedSessionId();
if (authentication instanceof MidpointAuthentication
&& ((MidpointAuthentication) authentication).getAuthenticationChannel() != null) {
channel = ((MidpointAuthentication) authentication).getAuthenticationChannel().getChannelId();
if (((MidpointAuthentication) authentication).getSessionId() != null) {
sessionId = ((MidpointAuthentication) authentication).getSessionId();
}
}

Task task = taskManager.createTaskInstance();
task.setOwner(user);
task.setChannel(channel);

AuditEventRecord record = new AuditEventRecord(AuditEventType.TERMINATE_SESSION, AuditEventStage.REQUEST);
record.setInitiator(user);
record.setParameter(WebComponentUtil.getName(user, false));

record.setChannel(channel);
record.setTimestamp(System.currentTimeMillis());
record.setOutcome(OperationResultStatus.SUCCESS);

// probably not needed, as audit service would take care of it; but it doesn't hurt so let's keep it here
record.setHostIdentifier(request.getLocalName());
record.setRemoteHostAddress(request.getLocalAddr());
record.setNodeIdentifier(taskManager.getNodeId());
record.setSessionIdentifier(sessionId);

auditService.audit(record, task);
}
}
Expand Up @@ -11,27 +11,30 @@
import java.util.UUID;

import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.schema.SchemaRegistry;

import com.evolveum.midpoint.web.security.util.SecurityUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
import org.springframework.security.config.annotation.ObjectPostProcessor;
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.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter;
import org.springframework.security.web.session.HttpSessionEventPublisher;

Expand All @@ -43,7 +46,8 @@
import com.evolveum.midpoint.web.security.filter.MidpointAnonymousAuthenticationFilter;
import com.evolveum.midpoint.web.security.filter.configurers.AuthFilterConfigurer;

import org.springframework.web.context.annotation.SessionScope;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* @author skublik
Expand Down Expand Up @@ -111,6 +115,14 @@ public AuthenticationEntryPoint authenticationEntryPoint() {
return new WicketLoginUrlAuthenticationEntryPoint("/login");
}

@Bean
@SessionAndRequestScope
@Override
protected MidpointAuthenticationManager authenticationManager() throws Exception {
List<AuthenticationProvider> providers = new ArrayList<AuthenticationProvider>();
return new MidpointProviderManager(providers);
}

@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
Expand Down Expand Up @@ -146,18 +158,29 @@ protected void configure(HttpSecurity http) throws Exception {
.securityContext();
http.apply(new AuthFilterConfigurer());

createSessionContextRepository(http);

http.sessionManagement()
.maximumSessions(-1)
.sessionRegistry(sessionRegistry)
.maxSessionsPreventsLogin(true);
}

@Bean
@SessionScope
@Override
protected MidpointAuthenticationManager authenticationManager() throws Exception {
List<AuthenticationProvider> providers = new ArrayList<AuthenticationProvider>();
return new MidpointProviderManager(providers);
private void createSessionContextRepository(HttpSecurity http) {
HttpSessionSecurityContextRepository httpSecurityRepository = new HttpSessionSecurityContextRepository() {
@Override
public void saveContext(SecurityContext context, HttpServletRequest request, HttpServletResponse response) {
if(!SecurityUtils.isRestOrActuatorChannel(request)) {
super.saveContext(context, request, response);
}
}
};
httpSecurityRepository.setDisableUrlRewriting(true);
AuthenticationTrustResolver trustResolver = http.getSharedObject(AuthenticationTrustResolver.class);
if (trustResolver != null) {
httpSecurityRepository.setTrustResolver(trustResolver);
}
http.setSharedObject(SecurityContextRepository.class, httpSecurityRepository);
}

// TODO not used, don't delete because of possible future implementation authentication module
Expand Down
Expand Up @@ -6,12 +6,22 @@
*/
package com.evolveum.midpoint.web.security;

import com.evolveum.midpoint.security.api.SecurityUtil;

import com.evolveum.midpoint.web.security.util.SecurityUtils;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* @author skublik
*/
Expand All @@ -25,6 +35,10 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) thro
CsrfFilter csrfFilter = (CsrfFilter) bean;
csrfFilter.setAccessDeniedHandler(new MidpointAccessDeniedHandler());
}
if (bean instanceof RegisterSessionAuthenticationStrategy) {
RegisterSessionAuthenticationStrategy strategy = (RegisterSessionAuthenticationStrategy) bean;
return new MidpointRegisterSessionAuthenticationStrategy(strategy);
}
return bean;
}

Expand Down

0 comments on commit c4e1dbe

Please sign in to comment.