Skip to content

Commit

Permalink
Merge pull request #234 from OpsMx/bugfix/OP-17106-4-0
Browse files Browse the repository at this point in the history
OP-17106: Added SamlSsoEventPublishConfig to update ApplicationEventPublisher
  • Loading branch information
ramyaravi-opsmx authored Aug 12, 2022
2 parents a62667a + 0990e9f commit 9a119d0
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.opsmx.spinnaker.gate.security.saml;

import java.util.ArrayList;
import java.util.List;
import javax.servlet.Filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.saml.SAMLProcessingFilter;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.security.web.SecurityFilterChain;

@ConditionalOnExpression("${saml.enabled:false}")
@Configuration
@Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SamlSsoEventPublishConfig {

private ApplicationEventPublisher applicationEventPublisher;

@Autowired
@Qualifier("springSecurityFilterChain")
private Filter springSecurityFilterChain;

@Autowired
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}

@Bean
public FilterChainProxy getFilters() {
FilterChainProxy filterChainProxy = (FilterChainProxy) springSecurityFilterChain;
List<SecurityFilterChain> list = filterChainProxy.getFilterChains();

list.stream()
.flatMap(chain -> chain.getFilters().stream())
.filter(filter -> filter.getClass() == FilterChainProxy.class)
.findAny()
.map(FilterChainProxy.class::cast)
.map(FilterChainProxy::getFilterChains)
.orElse(new ArrayList<>())
.stream()
.flatMap(chin -> chin.getFilters().stream())
.filter(filter -> filter.getClass() == SAMLProcessingFilter.class)
.findAny()
.map(SAMLProcessingFilter.class::cast)
.ifPresent(filter -> filter.setApplicationEventPublisher(applicationEventPublisher));
return filterChainProxy;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@
package com.opsmx.spinnaker.gate.audit;

import com.opsmx.spinnaker.gate.enums.AuditEventType;
import com.opsmx.spinnaker.gate.model.AuditData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.security.AbstractAuthenticationAuditListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.event.*;
import org.springframework.stereotype.Component;

Expand All @@ -38,20 +40,36 @@ public void onApplicationEvent(AbstractAuthenticationEvent event) {

try {
log.debug("Authentication audit events received : {}", event);
// OP-17106: If saml event handle differently
if (event.getAuthentication().isAuthenticated()
&& event instanceof InteractiveAuthenticationSuccessEvent) {
log.debug("publishEvent InteractiveAuthenticationSuccessEvent");
handleInteractiveAuthenticationSuccessEvent(event);
return;
}

if (event.getAuthentication().isAuthenticated()
&& event instanceof AuthenticationSuccessEvent) {
log.debug("publishEvent AuthenticationSuccessEvent");
auditHandler.publishEvent(AuditEventType.AUTHENTICATION_SUCCESSFUL_AUDIT, event);

} else if (!event.getAuthentication().isAuthenticated()
&& event instanceof AbstractAuthenticationFailureEvent) {
log.debug("publishEvent AbstractAuthenticationFailureEvent");
auditHandler.publishEvent(AuditEventType.AUTHENTICATION_FAILURE_AUDIT, event);

} else if (event instanceof LogoutSuccessEvent) {
log.debug("publishEvent LogoutSuccessEvent");
auditHandler.publishEvent(AuditEventType.SUCCESSFUL_USER_LOGOUT_AUDIT, event);
}

} catch (Exception e) {
log.error("Exception occured while capturing audit events : {}", e);
}
}

private void handleInteractiveAuthenticationSuccessEvent(AbstractAuthenticationEvent event) {
AbstractAuthenticationToken auth = (AbstractAuthenticationToken) event.getAuthentication();
String name = auth.getName();
AuditData data = new AuditData(name);
auditHandler.publishEvent(AuditEventType.AUTHENTICATION_SUCCESSFUL_AUDIT, data);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2022 OpsMx
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.opsmx.spinnaker.gate.model;

import lombok.Data;

@Data
public class AuditData {
private Source source;

public AuditData(String name) {
this.source = new Source(name);
}

@Data
public class Source {
private String name;

public Source(String name) {
this.name = name;
}
}
}

0 comments on commit 9a119d0

Please sign in to comment.