+ * Supports optional injection of spring security entities, allowing Waffle to act as an interface towards an identity + * provider(the AD). + *
+ * + * Below mentioned entities are verified to be set before invoked, inherited entities are not. + * + *AuthenticationManager
allows for the service provider to authorize the principal.authenticationSuccessHandler
allows for the service provider to further populate the
+ * {@link org.springframework.security.core.Authentication Authentication} object.AuthenticationFailureHandler
is called if the AuthenticationManager throws an
+ * {@link org.springframework.security.core.AuthenticationException AuthenticationException}.AccessDeniedHandler
is called if the AuthenticationManager throws an
+ * {@link org.springframework.security.access.AccessDeniedException AccessDeniedException}.+ * {@code + *+ */ +public class DelegatingNegotiateSecurityFilter extends NegotiateSecurityFilter { + private static final Logger LOGGER = LoggerFactory.getLogger(NegotiateSecurityFilter.class); + + private AuthenticationManager authenticationManager; + private AuthenticationSuccessHandler authenticationSuccessHandler; + private AuthenticationFailureHandler authenticationFailureHandler; + private AccessDeniedHandler accessDeniedHandler; + + /** + * @return the accessDeniedHandler + */ + public AccessDeniedHandler getAccessDeniedHandler() { + return accessDeniedHandler; + } + + /** + * @param accessDeniedHandler + * the accessDeniedHandler to set + */ + public void setAccessDeniedHandler(final AccessDeniedHandler accessDeniedHandler) { + this.accessDeniedHandler = accessDeniedHandler; + } + + /** + * @return the authenticationFailureHandler + */ + public AuthenticationFailureHandler getAuthenticationFailureHandler() { + return authenticationFailureHandler; + } + + /** + * @param authenticationFailureHandler + * the authenticationFailureHandler to set + */ + public void setAuthenticationFailureHandler(final AuthenticationFailureHandler authenticationFailureHandler) { + this.authenticationFailureHandler = authenticationFailureHandler; + } + + public DelegatingNegotiateSecurityFilter() { + super(); + LOGGER.debug("[waffle.spring.NegotiateSecurityFilter] loaded"); + } + + @Override + protected boolean setAuthentication(final HttpServletRequest request, final HttpServletResponse response, + final Authentication authentication) { + try { + if (authenticationManager != null) { + logger.debug("Delegating to custom authenticationmanager"); + final Authentication customAuthentication = authenticationManager.authenticate(authentication); + SecurityContextHolder.getContext().setAuthentication(customAuthentication); + } + if (authenticationSuccessHandler != null) { + try { + authenticationSuccessHandler.onAuthenticationSuccess(request, response, authentication); + } catch (final IOException e) { + logger.warn("Error calling authenticationSuccessHandler: " + e.getMessage()); + return false; + } catch (final ServletException e) { + logger.warn("Error calling authenticationSuccessHandler: " + e.getMessage()); + return false; + } + } + } catch (final AuthenticationException e) { + + logger.warn("Error authenticating user in custom authenticationmanager: " + e.getMessage()); + sendAuthenticationFailed(request, response, e); + return false; + } catch (final AccessDeniedException e) { + logger.warn("Error authorizing user in custom authenticationmanager: " + e.getMessage()); + sendAccessDenied(request, response, e); + return false; + } + return true; + } + + @Override + public void afterPropertiesSet() throws ServletException { + super.afterPropertiesSet(); + + if (this.getProvider() == null) { + throw new ServletException("Missing NegotiateSecurityFilter.Provider"); + } + } + + /** + * Forward to authenticationFailureHandler. + * + * @param response + * HTTP Response + * @param close + * Close connection. + */ + private void sendAuthenticationFailed(final HttpServletRequest request, final HttpServletResponse response, + final AuthenticationException ae) { + if (authenticationFailureHandler != null) { + try { + authenticationFailureHandler.onAuthenticationFailure(request, response, ae); + return; + } catch (final IOException e) { + LOGGER.warn("IOException invoking authenticationFailureHandler: " + e.getMessage()); + } catch (final ServletException e) { + LOGGER.warn("ServletException invoking authenticationFailureHandler: " + e.getMessage()); + } + } + super.sendUnauthorized(response, true); + } + + /** + * Forward to accessDeniedHandler. + * + * @param response + * HTTP Response + * @param close + * Close connection. + */ + private void sendAccessDenied(final HttpServletRequest request, final HttpServletResponse response, + final AccessDeniedException ae) { + if (accessDeniedHandler != null) { + try { + accessDeniedHandler.handle(request, response, ae); + return; + } catch (final IOException e) { + LOGGER.warn("IOException invoking accessDeniedHandler: " + e.getMessage()); + } catch (final ServletException e) { + LOGGER.warn("ServletException invoking accessDeniedHandler: " + e.getMessage()); + } + } + // fallback + sendUnauthorized(response, true); + } + + /** + * @return the authenticationSuccessHandler + */ + public AuthenticationSuccessHandler getAuthenticationSuccessHandler() { + return authenticationSuccessHandler; + } + + /** + * @param authenticationSuccessHandler + * the authenticationSuccessHandler to set + */ + public void setAuthenticationSuccessHandler(final AuthenticationSuccessHandler authenticationSuccessHandler) { + this.authenticationSuccessHandler = authenticationSuccessHandler; + } + + /** + * @return the authenticationManager + */ + public AuthenticationManager getAuthenticationManager() { + return authenticationManager; + } + + /** + * @param authenticationManager + * the authenticationManager to set + */ + public void setAuthenticationManager(final AuthenticationManager authenticationManager) { + this.authenticationManager = authenticationManager; + } + +} diff --git a/Source/JNA/waffle-spring-security3/src/main/java/waffle/spring/NegotiateSecurityFilter.java b/Source/JNA/waffle-spring-security3/src/main/java/waffle/spring/NegotiateSecurityFilter.java index 4374d62417..31a85f8fb1 100644 --- a/Source/JNA/waffle-spring-security3/src/main/java/waffle/spring/NegotiateSecurityFilter.java +++ b/Source/JNA/waffle-spring-security3/src/main/java/waffle/spring/NegotiateSecurityFilter.java @@ -106,7 +106,9 @@ public void doFilter(final ServletRequest req, final ServletResponse res, final final Authentication authentication = new WindowsAuthenticationToken(principal, this.grantedAuthorityFactory, this.defaultGrantedAuthority); - SecurityContextHolder.getContext().setAuthentication(authentication); + if (!setAuthentication(request, response, authentication)) { + return; + } LOGGER.info("successfully logged in user: {}", windowsIdentity.getFqn()); @@ -118,6 +120,18 @@ public void doFilter(final ServletRequest req, final ServletResponse res, final chain.doFilter(request, response); } + /* + * Invoked when authentication towards ad was succesful to populate securitycontext Override to add service provider + * authorization checks. + * + * @return if security context was set. + */ + protected boolean setAuthentication(final HttpServletRequest request, final HttpServletResponse response, + final Authentication authentication) { + SecurityContextHolder.getContext().setAuthentication(authentication); + return true; + } + @Override public void afterPropertiesSet() throws ServletException { super.afterPropertiesSet(); @@ -135,7 +149,7 @@ public void afterPropertiesSet() throws ServletException { * @param close * Close connection. */ - private void sendUnauthorized(final HttpServletResponse response, final boolean close) { + protected void sendUnauthorized(final HttpServletResponse response, final boolean close) { try { this.provider.sendUnauthorized(response); if (close) { diff --git a/Source/JNA/waffle-spring-security4/src/main/java/waffle/spring/DelegatingNegotiateSecurityFilter.java b/Source/JNA/waffle-spring-security4/src/main/java/waffle/spring/DelegatingNegotiateSecurityFilter.java new file mode 100644 index 0000000000..a405e40f81 --- /dev/null +++ b/Source/JNA/waffle-spring-security4/src/main/java/waffle/spring/DelegatingNegotiateSecurityFilter.java @@ -0,0 +1,245 @@ +/** + * Waffle (https://github.com/dblock/waffle) + * + * Copyright (c) 2010 - 2014 Application Security, Inc. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Application Security, Inc. + */ +/** + * + */ +package waffle.spring; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; + +/** + * + * + *+ * + * + * } + *+ * + * + * + * + * + * + * + *+ *
+ * Supports optional injection of spring security entities, allowing Waffle to act as an interface towards an identity + * provider(the AD). + *
+ * + * Below mentioned entities are verified to be set before invoked, inherited entities are not. + * + *AuthenticationManager
allows for the service provider to authorize the principal.authenticationSuccessHandler
allows for the service provider to further populate the
+ * {@link org.springframework.security.core.Authentication Authentication} object.AuthenticationFailureHandler
is called if the AuthenticationManager throws an
+ * {@link org.springframework.security.core.AuthenticationException AuthenticationException}.AccessDeniedHandler
is called if the AuthenticationManager throws an
+ * {@link org.springframework.security.access.AccessDeniedException AccessDeniedException}.+ * {@code + *+ */ +public class DelegatingNegotiateSecurityFilter extends NegotiateSecurityFilter { + private static final Logger LOGGER = LoggerFactory.getLogger(NegotiateSecurityFilter.class); + + private AuthenticationManager authenticationManager; + private AuthenticationSuccessHandler authenticationSuccessHandler; + private AuthenticationFailureHandler authenticationFailureHandler; + private AccessDeniedHandler accessDeniedHandler; + + /** + * @return the accessDeniedHandler + */ + public AccessDeniedHandler getAccessDeniedHandler() { + return accessDeniedHandler; + } + + /** + * @param accessDeniedHandler + * the accessDeniedHandler to set + */ + public void setAccessDeniedHandler(final AccessDeniedHandler accessDeniedHandler) { + this.accessDeniedHandler = accessDeniedHandler; + } + + /** + * @return the authenticationFailureHandler + */ + public AuthenticationFailureHandler getAuthenticationFailureHandler() { + return authenticationFailureHandler; + } + + /** + * @param authenticationFailureHandler + * the authenticationFailureHandler to set + */ + public void setAuthenticationFailureHandler(final AuthenticationFailureHandler authenticationFailureHandler) { + this.authenticationFailureHandler = authenticationFailureHandler; + } + + public DelegatingNegotiateSecurityFilter() { + super(); + LOGGER.debug("[waffle.spring.NegotiateSecurityFilter] loaded"); + } + + @Override + protected boolean setAuthentication(final HttpServletRequest request, final HttpServletResponse response, + final Authentication authentication) { + try { + if (authenticationManager != null) { + logger.debug("Delegating to custom authenticationmanager"); + final Authentication customAuthentication = authenticationManager.authenticate(authentication); + SecurityContextHolder.getContext().setAuthentication(customAuthentication); + } + if (authenticationSuccessHandler != null) { + try { + authenticationSuccessHandler.onAuthenticationSuccess(request, response, authentication); + } catch (final IOException e) { + logger.warn("Error calling authenticationSuccessHandler: " + e.getMessage()); + return false; + } catch (final ServletException e) { + logger.warn("Error calling authenticationSuccessHandler: " + e.getMessage()); + return false; + } + } + } catch (final AuthenticationException e) { + + logger.warn("Error authenticating user in custom authenticationmanager: " + e.getMessage()); + sendAuthenticationFailed(request, response, e); + return false; + } catch (final AccessDeniedException e) { + logger.warn("Error authorizing user in custom authenticationmanager: " + e.getMessage()); + sendAccessDenied(request, response, e); + return false; + } + return true; + } + + @Override + public void afterPropertiesSet() throws ServletException { + super.afterPropertiesSet(); + + if (this.getProvider() == null) { + throw new ServletException("Missing NegotiateSecurityFilter.Provider"); + } + } + + /** + * Forward to authenticationFailureHandler. + * + * @param response + * HTTP Response + * @param close + * Close connection. + */ + private void sendAuthenticationFailed(final HttpServletRequest request, final HttpServletResponse response, + final AuthenticationException ae) { + if (authenticationFailureHandler != null) { + try { + authenticationFailureHandler.onAuthenticationFailure(request, response, ae); + return; + } catch (final IOException e) { + LOGGER.warn("IOException invoking authenticationFailureHandler: " + e.getMessage()); + } catch (final ServletException e) { + LOGGER.warn("ServletException invoking authenticationFailureHandler: " + e.getMessage()); + } + } + super.sendUnauthorized(response, true); + } + + /** + * Forward to accessDeniedHandler. + * + * @param response + * HTTP Response + * @param close + * Close connection. + */ + private void sendAccessDenied(final HttpServletRequest request, final HttpServletResponse response, + final AccessDeniedException ae) { + if (accessDeniedHandler != null) { + try { + accessDeniedHandler.handle(request, response, ae); + return; + } catch (final IOException e) { + LOGGER.warn("IOException invoking accessDeniedHandler: " + e.getMessage()); + } catch (final ServletException e) { + LOGGER.warn("ServletException invoking accessDeniedHandler: " + e.getMessage()); + } + } + // fallback + sendUnauthorized(response, true); + } + + /** + * @return the authenticationSuccessHandler + */ + public AuthenticationSuccessHandler getAuthenticationSuccessHandler() { + return authenticationSuccessHandler; + } + + /** + * @param authenticationSuccessHandler + * the authenticationSuccessHandler to set + */ + public void setAuthenticationSuccessHandler(final AuthenticationSuccessHandler authenticationSuccessHandler) { + this.authenticationSuccessHandler = authenticationSuccessHandler; + } + + /** + * @return the authenticationManager + */ + public AuthenticationManager getAuthenticationManager() { + return authenticationManager; + } + + /** + * @param authenticationManager + * the authenticationManager to set + */ + public void setAuthenticationManager(final AuthenticationManager authenticationManager) { + this.authenticationManager = authenticationManager; + } + +} diff --git a/Source/JNA/waffle-spring-security4/src/main/java/waffle/spring/NegotiateSecurityFilter.java b/Source/JNA/waffle-spring-security4/src/main/java/waffle/spring/NegotiateSecurityFilter.java index 4374d62417..31a85f8fb1 100644 --- a/Source/JNA/waffle-spring-security4/src/main/java/waffle/spring/NegotiateSecurityFilter.java +++ b/Source/JNA/waffle-spring-security4/src/main/java/waffle/spring/NegotiateSecurityFilter.java @@ -106,7 +106,9 @@ public void doFilter(final ServletRequest req, final ServletResponse res, final final Authentication authentication = new WindowsAuthenticationToken(principal, this.grantedAuthorityFactory, this.defaultGrantedAuthority); - SecurityContextHolder.getContext().setAuthentication(authentication); + if (!setAuthentication(request, response, authentication)) { + return; + } LOGGER.info("successfully logged in user: {}", windowsIdentity.getFqn()); @@ -118,6 +120,18 @@ public void doFilter(final ServletRequest req, final ServletResponse res, final chain.doFilter(request, response); } + /* + * Invoked when authentication towards ad was succesful to populate securitycontext Override to add service provider + * authorization checks. + * + * @return if security context was set. + */ + protected boolean setAuthentication(final HttpServletRequest request, final HttpServletResponse response, + final Authentication authentication) { + SecurityContextHolder.getContext().setAuthentication(authentication); + return true; + } + @Override public void afterPropertiesSet() throws ServletException { super.afterPropertiesSet(); @@ -135,7 +149,7 @@ public void afterPropertiesSet() throws ServletException { * @param close * Close connection. */ - private void sendUnauthorized(final HttpServletResponse response, final boolean close) { + protected void sendUnauthorized(final HttpServletResponse response, final boolean close) { try { this.provider.sendUnauthorized(response); if (close) {+ * + * + * } + *+ * + * + * + * + * + * + * + *+ *