/** * Copyright 2014 symentis GmbH * * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * 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.symentis.cas.ws.sample.client; import com.symentis.cas.adaptors.ws.WebserviceClientBase; import com.symentis.cas.ws.samples.auth.schema.AuthRequest; import com.symentis.cas.ws.samples.auth.schema.AuthResponse; import com.symentis.cas.ws.samples.auth.schema.ObjectFactory; import org.apache.commons.lang.StringUtils; import org.jasig.cas.authentication.UsernamePasswordCredential; import org.jasig.cas.authentication.principal.DefaultPrincipalFactory; import org.jasig.cas.authentication.principal.Principal; import com.symentis.cas.adaptors.ws.WebserviceClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.sun.xml.wss.XWSSProcessor; import com.sun.xml.wss.XWSSProcessorFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.springframework.core.io.Resource; import org.springframework.web.context.ServletContextAware; import org.springframework.web.context.support.ServletContextResource; import javax.servlet.ServletContext; import javax.validation.constraints.NotNull; import java.security.GeneralSecurityException; import java.util.HashMap; import java.util.Map; /** * Example CAS SOAP Spring-WS Webservice Client using JaxB and optional WSSE header support. * For static username password setup, set wsUsername and wsPass in the bean def, * otherwise the given users' credentials username/password are used. * <p/> * Creation date: 15.04.2014 01:42:35 * <p/> * * @author Robert Oschwald */ public class ExampleWsClient extends WebserviceClientBase implements WebserviceClient, ServletContextAware { private static final Logger log = LoggerFactory.getLogger(ExampleWsClient.class); private ServletContext servletContext; private Resource _sConfigResource; // optional static username/pw from bean context definition. See setters. private String _wsUsername; private String _wsPass; private String _username; private String _password; private boolean _useWSSE; private String configFilePath; /** * Perform authentication. * <p/> * Creation date: 15.04.2014 05:01:05 * <p/> * * @param credential The given user credential * @return SimplePrincipal * @throws GeneralSecurityException * */ public Principal doAuthentication(UsernamePasswordCredential credential) throws GeneralSecurityException { return authenticateUser(credential); } private Principal authenticateUser(UsernamePasswordCredential credential) throws GeneralSecurityException { log.warn("SOAP authenticate User: " + credential.getUsername()); ObjectFactory factory = new ObjectFactory(); AuthRequest request = factory.createAuthRequest(); AuthResponse response; // configure parameters this.configureParameters(credential); request.setNetid(this._username); request.setPassword(this._password); try { if (_useWSSE) { // With dynamic WSSE header. Adding the given username / pw as a WSSE header SecurityConfigModifier securityConfigCallbackHandler = new SecurityConfigModifier(this._username, this._password); // processor with callback to dynamically add username/password. XWSSProcessorFactory pf = XWSSProcessorFactory.newInstance(); final XWSSProcessor processor = pf.createProcessorForSecurityConfiguration( this._sConfigResource.getInputStream(), securityConfigCallbackHandler); // add WSSE security header to message via CallBack Handler. // Would be much easier with SpringWS 2.5.x ... response = (AuthResponse) getWebServiceTemplate().marshalSendAndReceive( getDefaultUri(), request, new LocalWebServiceMessageCallback(processor)); } else { log.warn("send soap request: " + request); response = (AuthResponse) getWebServiceTemplate().marshalSendAndReceive(getDefaultUri(), request); } } catch (Exception e) { log.error("Error:", e); return null; } log.debug("SOAP Response: " + response.getFirstname() + "," + response.getLastname() + "," + response.getNetid()); if (response == null) return null; if (StringUtils.isNotBlank(response.getNetid())) { Map<String, Object> attributes = new HashMap<String, Object>(); attributes.put("firstname", response.getFirstname()); attributes.put("lastname", response.getLastname()); attributes.put("netid", response.getNetid()); log.debug("Attributes: " + attributes); return new DefaultPrincipalFactory().createPrincipal(this._username, attributes); } return null; } /** * Prepare client call * Uses username/password if set in the bean definition. Otherwise, use the given credentials * Also prepares the securityConfigResource. */ private void configureParameters(UsernamePasswordCredential credential) { if (this._sConfigResource == null){ this._sConfigResource = new ServletContextResource(servletContext, this.configFilePath); } if (StringUtils.isNotBlank(this._wsUsername)) { // got username/pw from bean definition this._username = this._wsUsername; this._password = this._wsPass; } else { // get username/pw from credentials. this._username = credential.getUsername(); this._password = credential.getPassword(); } // ensure that username is lowercase if (this._username != null) { this._username = this._username.trim().toLowerCase(); } } /** * Optional: Static username for SOAP Request (WSSE Header) * @param wsUsername The SOAP Username */ public void setWsUsername(String wsUsername) { this._wsUsername = wsUsername; } /** * Optional: Static password for SOAP Request (WSSE Header) * @param wsPass The SOAP Username */ public void setWsPass(String wsPass) { this._wsPass = wsPass; } /* Set to true to modify outgoing payload to add a WSSE header */ public void setUseWSSE(boolean useWSSE) { this._useWSSE = useWSSE; } /** * setter for WsSecurity config file path * <p/> * Creation date: 26.11.2015 09:48:30 * <p/> */ public void setConfigFilePath(String configFilePath) { this.configFilePath = configFilePath; } public void setServletContext(ServletContext servletContext) { this.servletContext = servletContext; } }