001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036:
037: package com.sun.xml.ws.security.trust.sts;
038:
039: import com.sun.xml.ws.api.security.trust.BaseSTS;
040: import com.sun.xml.ws.api.security.trust.WSTrustContract;
041: import com.sun.xml.ws.api.security.trust.WSTrustException;
042: import com.sun.xml.ws.api.security.trust.config.STSConfiguration;
043: import com.sun.xml.ws.policy.PolicyAssertion;
044: import com.sun.xml.ws.security.IssuedTokenContext;
045: import com.sun.xml.ws.security.impl.IssuedTokenContextImpl;
046: import com.sun.xml.ws.security.impl.policy.Constants;
047: import com.sun.xml.ws.security.trust.WSTrustConstants;
048: import com.sun.xml.ws.security.trust.WSTrustElementFactory;
049: import com.sun.xml.ws.security.trust.WSTrustFactory;
050: import com.sun.xml.ws.security.trust.elements.RequestSecurityToken;
051: import com.sun.xml.ws.security.trust.elements.RequestSecurityTokenResponse;
052: import com.sun.xml.ws.security.trust.impl.DefaultSTSConfiguration;
053: import com.sun.xml.ws.security.trust.impl.DefaultTrustSPMetadata;
054: import com.sun.xml.ws.security.trust.util.WSTrustUtil;
055: import com.sun.xml.wss.SecurityEnvironment;
056: import com.sun.xml.wss.SubjectAccessor;
057: import com.sun.xml.wss.XWSSecurityException;
058:
059: import java.util.Iterator;
060: import javax.xml.namespace.QName;
061:
062: import javax.security.auth.callback.CallbackHandler;
063:
064: import javax.xml.ws.Provider;
065: import javax.xml.ws.WebServiceException;
066: import javax.xml.transform.Source;
067: import javax.xml.ws.handler.MessageContext; //import javax.xml.ws.BindingType;
068: //import javax.xml.ws.RespectBinding;
069:
070: import com.sun.xml.ws.policy.impl.bindings.AppliesTo;
071: import org.w3c.dom.*;
072:
073: /**
074: * The Base class of an STS implementation. This could be used to implement
075: * the actual STS. The sub class could override the methods of this class to
076: * customize the implementation.
077: */
078: //@RespectBinding
079: //@BindingType
080: public abstract class BaseSTSImpl implements BaseSTS {
081: /**
082: * The default value of the timeout for the tokens issued by this STS
083: */
084: public static final int DEFAULT_TIMEOUT = 36000;
085:
086: public static final String DEFAULT_ISSUER = "SampleSunSTS";
087: /**
088: * The xml element tag for STS Configuration
089: */
090: public static final String STS_CONFIGURATION = "STSConfiguration";
091: /**
092: * The default implementation class for the Trust contract. This
093: * class issues SAML tokens.
094: */
095: public static final String DEFAULT_IMPL = "com.sun.xml.ws.security.trust.impl.IssueSamlTokenContractImpl";
096: /**
097: * The default value for AppliesTo if appliesTo is not specified.
098: */
099: public static final String DEFAULT_APPLIESTO = "default";
100: /**
101: * The String AppliesTo
102: */
103: public static final String APPLIES_TO = "AppliesTo";
104: /**
105: * The String LifeTime that is used to specify lifetime of the tokens
106: * issued by this STS.
107: */
108: public static final String LIFETIME = "LifeTime";
109: /**
110: * The String CertAlias that is used in the configuration.
111: * This identifies the alias of the Service that this STS serves.
112: */
113: public static final String ALIAS = "CertAlias";
114: /**
115: * The String encrypt-issued-key
116: */
117: public static final String ENCRYPT_KEY = "encryptIssuedKey";
118: /**
119: * The String encrypt-issued-token
120: */
121: public static final String ENCRYPT_TOKEN = "encryptIssuedToken";
122: /**
123: * The String Contract.
124: */
125: public static final String CONTRACT = "Contract";
126:
127: public static final String ISSUER = "Issuer";
128: /**
129: * The String TokenType.
130: */
131: public static final String TOKEN_TYPE = "TokenType";
132:
133: /**
134: * The String KeyType.
135: */
136: public static final String KEY_TYPE = "KeyType";
137:
138: /**
139: * The String ServiceProviders.
140: */
141: public static final String SERVICE_PROVIDERS = "ServiceProviders";
142: /**
143: * The String endPoint.
144: */
145: public static final String END_POINT = "endPoint";
146:
147: private static final QName Q_EK = new QName("", ENCRYPT_KEY);
148:
149: private static final QName Q_ET = new QName("", ENCRYPT_TOKEN);
150:
151: private static final QName Q_EP = new QName("", END_POINT);
152:
153: /** Implementation of the invoke method of the Provider interface
154: *
155: * @param rstElement The message comprising of RequestSecurityToken.
156: * @return The response message comprising of RequestSecurityTokenResponse
157: * @throws WebServiceException if there is an error processing request.
158: * The cause of the WebServiceException may be set to a subclass
159: * of ProtocolException to control the protocol level
160: * representation of the exception.
161: **/
162: public Source invoke(final Source rstElement) {
163:
164: Source rstrEle = null;
165: try {
166: // Get RequestSecurityToken
167: final WSTrustElementFactory eleFac = WSTrustElementFactory
168: .newInstance();
169: final RequestSecurityToken rst = eleFac
170: .createRSTFrom(rstElement);
171: //String tokenType = null;
172:
173: String appliesTo = null;
174: final AppliesTo applTo = rst.getAppliesTo();
175: if (applTo != null) {
176: appliesTo = WSTrustUtil.getAppliesToURI(applTo);
177: }
178:
179: if (appliesTo == null) {
180: appliesTo = DEFAULT_APPLIESTO;
181: }
182:
183: // if(rst.getTokenType()!=null){
184: // tokenType = rst.getTokenType().toString();
185: // }
186: final STSConfiguration config = getConfiguration();
187: if (rst.getRequestType().toString().equals(
188: WSTrustConstants.ISSUE_REQUEST)) {
189: rstrEle = issue(config, appliesTo, eleFac, rst);
190: } else if (rst.getRequestType().toString().equals(
191: WSTrustConstants.CANCEL_REQUEST)) {
192: rstrEle = cancel(config, appliesTo, eleFac, rst);
193: } else if (rst.getRequestType().toString().equals(
194: WSTrustConstants.RENEW_REQUEST)) {
195: rstrEle = renew(config, appliesTo, eleFac, rst);
196: } else if (rst.getRequestType().toString().equals(
197: WSTrustConstants.VALIDATE_REQUEST)) {
198: rstrEle = validate(config, appliesTo, eleFac, rst);
199: }
200: } catch (Exception ex) {
201: //ex.printStackTrace();
202: throw new WebServiceException(ex);
203: }
204:
205: return rstrEle;
206: }
207:
208: /** The actual STS class should override this method to return the
209: * correct MessageContext
210: *
211: * @return The MessageContext
212: */
213: protected abstract MessageContext getMessageContext();
214:
215: STSConfiguration getConfiguration() {
216: final MessageContext msgCtx = getMessageContext();
217: //final CallbackHandler handler = (CallbackHandler)msgCtx.get(WSTrustConstants.STS_CALL_BACK_HANDLER);
218: final SecurityEnvironment secEnv = (SecurityEnvironment) msgCtx
219: .get(WSTrustConstants.SECURITY_ENVIRONMENT);
220:
221: //Get Runtime STSConfiguration
222: STSConfiguration rtConfig = WSTrustFactory
223: .getRuntimeSTSConfiguration();
224: if (rtConfig != null) {
225: if (rtConfig.getCallbackHandler() == null) {
226: rtConfig.getOtherOptions().put(
227: WSTrustConstants.SECURITY_ENVIRONMENT, secEnv);
228: }
229: return rtConfig;
230: }
231:
232: // Get default STSConfiguration
233: DefaultSTSConfiguration config = new DefaultSTSConfiguration();
234: config.getOtherOptions().put(
235: WSTrustConstants.SECURITY_ENVIRONMENT, secEnv);
236: //config.setCallbackHandler(handler);
237: final Iterator iterator = (Iterator) msgCtx
238: .get(Constants.SUN_TRUST_SERVER_SECURITY_POLICY_NS);
239: if (iterator == null) {
240: throw new WebServiceException(
241: "STS configuration information is not available");
242: }
243:
244: while (iterator.hasNext()) {
245: final PolicyAssertion assertion = (PolicyAssertion) iterator
246: .next();
247: if (!STS_CONFIGURATION.equals(assertion.getName()
248: .getLocalPart())) {
249: continue;
250: }
251: config.setEncryptIssuedToken(Boolean.parseBoolean(assertion
252: .getAttributeValue(Q_ET)));
253: config.setEncryptIssuedKey(Boolean.parseBoolean(assertion
254: .getAttributeValue(Q_EK)));
255: final Iterator<PolicyAssertion> stsConfig = assertion
256: .getNestedAssertionsIterator();
257: while (stsConfig.hasNext()) {
258: final PolicyAssertion serviceSTSPolicy = stsConfig
259: .next();
260: if (LIFETIME.equals(serviceSTSPolicy.getName()
261: .getLocalPart())) {
262: config.setIssuedTokenTimeout(Integer
263: .parseInt(serviceSTSPolicy.getValue()));
264:
265: continue;
266: }
267: if (CONTRACT.equals(serviceSTSPolicy.getName()
268: .getLocalPart())) {
269: config.setType(serviceSTSPolicy.getValue());
270: continue;
271: }
272: if (ISSUER.equals(serviceSTSPolicy.getName()
273: .getLocalPart())) {
274: config.setIssuer(serviceSTSPolicy.getValue());
275: continue;
276: }
277:
278: if (SERVICE_PROVIDERS.equals(serviceSTSPolicy.getName()
279: .getLocalPart())) {
280: final Iterator<PolicyAssertion> serviceProviders = serviceSTSPolicy
281: .getNestedAssertionsIterator();
282: String endpointUri = null;
283: while (serviceProviders.hasNext()) {
284: final PolicyAssertion serviceProvider = serviceProviders
285: .next();
286: endpointUri = serviceProvider
287: .getAttributeValue(Q_EP);
288: if (endpointUri == null) {
289: endpointUri = serviceProvider
290: .getAttributeValue(new QName("",
291: END_POINT.toLowerCase()));
292: }
293: final DefaultTrustSPMetadata data = new DefaultTrustSPMetadata(
294: endpointUri);
295: final Iterator<PolicyAssertion> spConfig = serviceProvider
296: .getNestedAssertionsIterator();
297: while (spConfig.hasNext()) {
298: final PolicyAssertion policy = spConfig
299: .next();
300: if (ALIAS.equals(policy.getName()
301: .getLocalPart())) {
302: data.setCertAlias(policy.getValue());
303: } else if (TOKEN_TYPE.equals(policy
304: .getName().getLocalPart())) {
305: data.setTokenType(policy.getValue());
306: } else if (KEY_TYPE.equals(policy.getName()
307: .getLocalPart())) {
308: data.setKeyType(policy.getValue());
309: }
310: }
311:
312: config.addTrustSPMetadata(data, endpointUri);
313: }
314: }
315: }
316: }
317:
318: return config;
319: }
320:
321: private Source issue(final STSConfiguration config,
322: final String appliesTo, final WSTrustElementFactory eleFac,
323: final RequestSecurityToken rst) throws WSTrustException {
324:
325: // Create the RequestSecurityTokenResponse message
326: final WSTrustContract<RequestSecurityToken, RequestSecurityTokenResponse> contract = WSTrustFactory
327: .newWSTrustContract(config, appliesTo);
328: final IssuedTokenContext context = new IssuedTokenContextImpl();
329: try {
330: context.setRequestorSubject(SubjectAccessor
331: .getRequesterSubject(getMessageContext()));
332: } catch (XWSSecurityException ex) {
333: throw new WSTrustException("error getting subject", ex);
334: }
335:
336: final RequestSecurityTokenResponse rstr = contract.issue(rst,
337: context);
338:
339: /* Token samlToken = rstr.getRequestedSecurityToken().getToken();
340: rstr.getRequestedSecurityToken().setAny(null);
341: Element samlEle = (Element)samlToken.getTokenValue();
342: Element rstrEle = eleFac.toElement(rstr);
343: Document doc = rstrEle.getOwnerDocument();
344: samlEle = (Element)doc.importNode(samlEle, true);
345: NodeList list = rstrEle.getElementsByTagNameNS("*", "RequestedSecurityToken");
346: Element rdstEle = (Element)list.item(0);
347: rdstEle.appendChild(samlEle);
348:
349: return new DOMSource(rstrEle);*/
350: return eleFac.toSource(rstr);
351: }
352:
353: private Source cancel(final STSConfiguration config,
354: final String appliesTo, final WSTrustElementFactory eleFac,
355: final RequestSecurityToken rst) {
356: return null;
357: }
358:
359: private Source renew(final STSConfiguration config,
360: final String appliesTo, final WSTrustElementFactory eleFac,
361: final RequestSecurityToken rst) throws WSTrustException {
362: Source rstrEle;
363:
364: // Create the RequestSecurityTokenResponse message
365: final WSTrustContract<RequestSecurityToken, RequestSecurityTokenResponse> contract = WSTrustFactory
366: .newWSTrustContract(config, appliesTo);
367: final IssuedTokenContext context = new IssuedTokenContextImpl();
368:
369: final RequestSecurityTokenResponse rstr = contract.renew(rst,
370: context);
371:
372: rstrEle = eleFac.toSource(rstr);
373: return rstrEle;
374: }
375:
376: private Source validate(final STSConfiguration config,
377: final String appliesTo, final WSTrustElementFactory eleFac,
378: final RequestSecurityToken rst) throws WSTrustException {
379: Source rstrEle;
380:
381: // Create the RequestSecurityTokenResponse message
382: final WSTrustContract<RequestSecurityToken, RequestSecurityTokenResponse> contract = WSTrustFactory
383: .newWSTrustContract(config, appliesTo);
384: final IssuedTokenContext context = new IssuedTokenContextImpl();
385:
386: final RequestSecurityTokenResponse rstr = contract.validate(
387: rst, context);
388:
389: rstrEle = eleFac.toSource(rstr);
390: return rstrEle;
391: }
392: }
|