use of org.codice.ddf.security.handler.api.HandlerResult in project ddf by codice.
the class AssertionConsumerService method login.
private boolean login(org.opensaml.saml.saml2.core.Response samlResponse) {
if (!request.isSecure()) {
return false;
}
Map<String, Cookie> cookieMap = HttpUtils.getCookieMap(request);
if (cookieMap.containsKey("JSESSIONID") && sessionFactory != null) {
sessionFactory.getOrCreateSession(request).invalidate();
}
HandlerResult handlerResult = new HandlerResultImpl();
SimplePrincipalCollection simplePrincipalCollection = new SimplePrincipalCollection();
simplePrincipalCollection.add(new SecurityAssertionSaml(samlResponse.getAssertions().get(0).getDOM()), "default");
SAMLAuthenticationToken samlToken = new SAMLAuthenticationToken(null, simplePrincipalCollection, request.getRemoteAddr());
handlerResult.setToken(samlToken);
handlerResult.setStatus(HandlerResult.Status.COMPLETED);
if (handlerResult.getStatus() != HandlerResult.Status.COMPLETED) {
LOGGER.debug("Failed to handle SAML assertion.");
return false;
}
if (handlerResult.getToken() instanceof BaseAuthenticationToken) {
((BaseAuthenticationToken) handlerResult.getToken()).setAllowGuest(contextPolicyManager.getGuestAccess());
}
request.setAttribute(AUTHENTICATION_TOKEN_KEY, handlerResult);
request.removeAttribute(ContextPolicy.NO_AUTH_POLICY);
try {
LOGGER.trace("Trying to login with provided SAML assertion.");
loginFilter.doFilter(request, null, (servletRequest, servletResponse) -> {
});
} catch (IOException | AuthenticationException e) {
LOGGER.debug("Failed to apply login filter to SAML assertion", e);
return false;
}
return true;
}
use of org.codice.ddf.security.handler.api.HandlerResult in project ddf by codice.
the class IdpHandler method doPaosRequest.
private HandlerResult doPaosRequest(ServletRequest request, ServletResponse response) {
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
HandlerResult handlerResult = new HandlerResultImpl(HandlerResult.Status.REDIRECTED, null);
handlerResult.setSource(SOURCE);
String paosHeader = ((HttpServletRequest) request).getHeader(PAOS);
// some of these options aren't currently used, leaving these here as a marker for what
// isn't implemented
boolean wantChannelBind = paosHeader.contains("urn:oasis:names:tc:SAML:protocol:ext:channel-binding");
boolean wantHok = paosHeader.contains("urn:oasis:names:tc:SAML:2.0:cm:holder-of-key");
boolean wantSigned = paosHeader.contains("urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp:2.0:WantAuthnRequestsSigned");
boolean wantDelegation = paosHeader.contains("urn:oasis:names:tc:SAML:2.0:conditions:delegation");
LOGGER.trace("ECP Client requested: channel bind {}, holder of key {}, signatures {}, delegation {}", wantChannelBind, wantHok, wantSigned, wantDelegation);
LOGGER.trace("Configuring SAML Response for POST.");
Document doc = DOMUtils.createDocument();
doc.appendChild(doc.createElement("root"));
LOGGER.trace("Signing SAML POST Response.");
String authnRequest;
String paosRequest;
String ecpRequest;
String ecpRelayState;
try {
IDPSSODescriptor idpssoDescriptor = idpMetadata.getDescriptor();
if (idpssoDescriptor == null) {
throw new AuthenticationFailureException(IDP_METADATA_MISSING);
}
authnRequest = createAndSignAuthnRequest(true, wantSigned && idpssoDescriptor.getWantAuthnRequestsSigned());
paosRequest = createPaosRequest((HttpServletRequest) request);
ecpRequest = createEcpRequest();
ecpRelayState = createEcpRelayState((HttpServletRequest) request);
} catch (WSSecurityException | AuthenticationFailureException e) {
LOGGER.debug("Unable to create and sign AuthnRequest.", e);
httpServletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
try {
httpServletResponse.flushBuffer();
} catch (IOException e1) {
LOGGER.debug("Failed to send error response", e1);
}
return handlerResult;
}
LOGGER.trace("Converting SAML Response to DOM");
String soapMessage = soapMessageTemplate.replace("{{" + PAOS_REQUEST + "}}", paosRequest);
soapMessage = soapMessage.replace("{{" + ECP_REQUEST + "}}", ecpRequest);
soapMessage = soapMessage.replace("{{" + SAML_REQUEST + "}}", authnRequest);
soapMessage = soapMessage.replace("{{" + ECP_RELAY_STATE + "}}", ecpRelayState);
soapMessage = soapMessage.replace("{{" + PAOS_RESPONSE + "}}", "");
try {
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
httpServletResponse.setContentType(PAOS_MIME);
httpServletResponse.getOutputStream().print(soapMessage);
httpServletResponse.flushBuffer();
} catch (IOException ioe) {
LOGGER.debug("Failed to send auth response", ioe);
}
return handlerResult;
}
use of org.codice.ddf.security.handler.api.HandlerResult in project ddf by codice.
the class IdpHandler method handleError.
@Override
public HandlerResult handleError(ServletRequest servletRequest, ServletResponse servletResponse, SecurityFilterChain chain) throws AuthenticationFailureException {
HandlerResult result = new HandlerResultImpl(HandlerResult.Status.NO_ACTION, null);
result.setSource(SOURCE);
LOGGER.debug("In error handler for idp - no action taken.");
return result;
}
use of org.codice.ddf.security.handler.api.HandlerResult in project ddf by codice.
the class IdpHandler method getNormalizedToken.
/**
* Handler implementing SAML 2.0 IdP authentication. Supports HTTP-Redirect and HTTP-POST
* bindings.
*
* @param request http request to obtain attributes from and to pass into any local filter chains
* required
* @param response http response to return http responses or redirects
* @param chain original filter chain (should not be called from your handler)
* @param resolve flag with true implying that credentials should be obtained, false implying
* return if no credentials are found.
* @return result of handling this request - status and optional tokens
* @throws AuthenticationFailureException
*/
@Override
public HandlerResult getNormalizedToken(ServletRequest request, ServletResponse response, SecurityFilterChain chain, boolean resolve) throws AuthenticationFailureException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
if (httpRequest.getMethod().equals("HEAD")) {
((HttpServletResponse) response).setStatus(HttpServletResponse.SC_OK);
try {
response.flushBuffer();
} catch (IOException e) {
throw new AuthenticationFailureException("Unable to send response to HEAD message from IdP client.");
}
return new HandlerResultImpl(HandlerResult.Status.NO_ACTION, null);
}
LOGGER.trace("Checking for assertion in HTTP header.");
HandlerResult samlResult = checkForAssertionInHttpHeader(request);
if (samlResult != null && samlResult.getStatus() == HandlerResult.Status.COMPLETED) {
return samlResult;
}
if (isEcpEnabled(request)) {
return doPaosRequest(request, response);
}
if (userAgentCheck && userAgentIsNotBrowser(httpRequest)) {
securityLogger.audit("Attempting to log client in as a legacy system.");
return new HandlerResultImpl(HandlerResult.Status.NO_ACTION, null);
}
HandlerResult handlerResult = new HandlerResultImpl(HandlerResult.Status.REDIRECTED, null);
handlerResult.setSource(SOURCE);
String path = httpRequest.getServletPath();
LOGGER.debug("Doing IdP authentication and authorization for path {}", path);
// Default to HTTP-Redirect if binding is null
if (idpMetadata.getSingleSignOnBinding() == null || idpMetadata.getSingleSignOnBinding().endsWith("Redirect")) {
doHttpRedirectBinding((HttpServletRequest) request, (HttpServletResponse) response);
} else {
doHttpPostBinding((HttpServletRequest) request, (HttpServletResponse) response);
}
return handlerResult;
}
use of org.codice.ddf.security.handler.api.HandlerResult in project ddf by codice.
the class IdpHandler method checkForAssertionInHttpHeader.
private HandlerResult checkForAssertionInHttpHeader(ServletRequest request) {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String authHeader = ((HttpServletRequest) request).getHeader(SecurityConstants.SAML_HEADER_NAME);
HandlerResult handlerResult = new HandlerResultImpl();
// check for full SAML assertions coming in (federated requests, etc.)
if (authHeader != null) {
String[] tokenizedAuthHeader = authHeader.split(" ");
if (tokenizedAuthHeader.length == 2 && tokenizedAuthHeader[0].equals("SAML") && samlSecurity != null) {
String encodedSamlAssertion = tokenizedAuthHeader[1];
LOGGER.trace("Header retrieved");
try {
String tokenString = samlSecurity.inflateBase64(encodedSamlAssertion);
LOGGER.trace("Header value: {}", LogSanitizer.sanitize(tokenString));
SimplePrincipalCollection simplePrincipalCollection = new SimplePrincipalCollection();
simplePrincipalCollection.add(new SecurityAssertionSaml(SAMLUtils.getInstance().getSecurityTokenFromSAMLAssertion(tokenString)), "default");
SAMLAuthenticationToken samlToken = new SAMLAuthenticationToken(simplePrincipalCollection, simplePrincipalCollection, request.getRemoteAddr());
handlerResult.setToken(samlToken);
handlerResult.setStatus(HandlerResult.Status.COMPLETED);
} catch (IOException e) {
LOGGER.info("Unexpected error converting header value to string", e);
}
return handlerResult;
}
}
// Check for legacy SAML cookie
Map<String, Cookie> cookies = HttpUtils.getCookieMap(httpRequest);
Cookie samlCookie = cookies.get(SecurityConstants.SAML_COOKIE_NAME);
if (samlCookie != null && samlSecurity != null) {
String cookieValue = samlCookie.getValue();
LOGGER.trace("Cookie retrieved");
try {
String tokenString = samlSecurity.inflateBase64(cookieValue);
LOGGER.trace("Cookie value: {}", LogSanitizer.sanitize(tokenString));
Element thisToken = StaxUtils.read(new StringReader(tokenString)).getDocumentElement();
SimplePrincipalCollection simplePrincipalCollection = new SimplePrincipalCollection();
simplePrincipalCollection.add(new SecurityAssertionSaml(thisToken), "default");
SAMLAuthenticationToken samlToken = new SAMLAuthenticationToken(null, simplePrincipalCollection, request.getRemoteAddr());
handlerResult.setToken(samlToken);
handlerResult.setStatus(HandlerResult.Status.COMPLETED);
} catch (IOException e) {
LOGGER.info("Unexpected error converting cookie value to string - proceeding without SAML token.", e);
} catch (XMLStreamException e) {
LOGGER.info("Unexpected error converting XML string to element - proceeding without SAML token.", e);
}
return handlerResult;
}
return null;
}
Aggregations