/** * Copyright (c) Codice Foundation * <p/> * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation, either version 3 of the * License, or any later version. * <p/> * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. A copy of the GNU Lesser General Public License * is distributed along with this program and can be found at * <http://www.gnu.org/licenses/lgpl.html>. */ package ddf.security.service.impl; import java.security.Principal; import java.util.Date; import java.util.List; import java.util.concurrent.TimeUnit; import org.apache.cxf.message.Message; import org.apache.cxf.ws.security.tokenstore.SecurityToken; import org.apache.cxf.ws.security.tokenstore.TokenStore; import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor; import org.apache.cxf.ws.security.wss4j.WSS4JUtils; import org.apache.wss4j.common.principal.SAMLTokenPrincipal; import org.apache.wss4j.common.saml.SamlAssertionWrapper; import org.apache.wss4j.dom.WSSecurityEngineResult; import org.apache.wss4j.dom.handler.WSHandlerConstants; import org.apache.wss4j.dom.handler.WSHandlerResult; import ddf.security.assertion.SecurityAssertion; import ddf.security.assertion.impl.SecurityAssertionImpl; /** * Creates a SecurityAssertion object by extracting the token id from the message and using that id * to retrieve the SecurityToken object from the TokenStore instance. * * @author tustisos */ public final class SecurityAssertionStore { /** * Return the SecurityAssertion wrapper associated with the provided message * * @param message Message * @return SecurityAssertion */ public static SecurityAssertion getSecurityAssertion(Message message) { if (message != null) { TokenStore tokenStore = getTokenStore(message); Principal principal = (Principal) message.get(WSS4JInInterceptor.PRINCIPAL_RESULT); if (!(principal instanceof SAMLTokenPrincipal)) { // Try to find the SAMLTokenPrincipal if it exists List<?> wsResults = List.class.cast(message.get(WSHandlerConstants.RECV_RESULTS)); if (wsResults != null) { for (Object wsResult : wsResults) { if (wsResult instanceof WSHandlerResult) { List<WSSecurityEngineResult> wsseResults = ((WSHandlerResult) wsResult) .getResults(); for (WSSecurityEngineResult wsseResult : wsseResults) { Object principalResult = wsseResult .get(WSSecurityEngineResult.TAG_PRINCIPAL); if (principalResult instanceof SAMLTokenPrincipal) { principal = (SAMLTokenPrincipal) principalResult; break; } } } } } } if (tokenStore != null && principal != null && principal instanceof SAMLTokenPrincipal) { String id = ((SAMLTokenPrincipal) principal).getId(); SamlAssertionWrapper samlAssertionWrapper = ((SAMLTokenPrincipal) principal) .getToken(); SecurityToken token = tokenStore.getToken(id); if (token == null) { if (samlAssertionWrapper.getSaml2().getIssueInstant() != null && samlAssertionWrapper.getSaml2().getConditions() != null && samlAssertionWrapper.getSaml2().getConditions().getNotOnOrAfter() != null) { token = new SecurityToken(id, samlAssertionWrapper.getElement(), samlAssertionWrapper.getSaml2().getIssueInstant().toDate(), samlAssertionWrapper.getSaml2().getConditions().getNotOnOrAfter() .toDate()); } else { // we don't know how long this should last or when it was created, so just // set it to 1 minute // This shouldn't happen unless someone sets up a third party STS with weird // settings. Date date = new Date(); token = new SecurityToken(id, samlAssertionWrapper.getElement(), date, new Date(date.getTime() + TimeUnit.MINUTES.toMillis(1))); } tokenStore.add(token); } return new SecurityAssertionImpl(token); } } return new SecurityAssertionImpl(); } /** * Return the TokenStore associated with this message. * * @param message * @return TokenStore */ public static TokenStore getTokenStore(Message message) { return WSS4JUtils.getTokenStore(message); } }