View Javadoc

1   /* 
2    * Copyright (c) 2005-2011, Fraunhofer-Gesellschaft
3    * All rights reserved.
4    * 
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions are
7    * met:
8    * 
9    * (1) Redistributions of source code must retain the above copyright
10   *     notice, this list of conditions and the disclaimer at the end.
11   *     Redistributions in binary form must reproduce the above copyright
12   *     notice, this list of conditions and the following disclaimer in
13   *     the documentation and/or other materials provided with the
14   *     distribution.
15   * 
16   * (2) Neither the name of Fraunhofer nor the names of its
17   *     contributors may be used to endorse or promote products derived
18   *     from this software without specific prior written permission.
19   * 
20   * DISCLAIMER
21   * 
22   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26   * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33   *  
34   */
35  package org.ogf.graap.wsag.wsrf.impl;
36  
37  import java.security.cert.X509Certificate;
38  import java.text.MessageFormat;
39  import java.util.Iterator;
40  import java.util.Set;
41  
42  import javax.security.auth.Subject;
43  import javax.xml.namespace.QName;
44  
45  import org.apache.muse.ws.resource.properties.ResourcePropertyCollection;
46  import org.apache.ws.security.WSSecurityException;
47  import org.apache.xmlbeans.XmlString;
48  import org.ogf.graap.wsag.api.Agreement;
49  import org.ogf.graap.wsag.api.WsagConstants;
50  import org.ogf.graap.wsag.security.core.SecurityConstants;
51  import org.ogf.graap.wsag.server.api.WsagSession;
52  import org.ogf.graap.wsag.server.engine.WsagEngine;
53  import org.ogf.graap.wsag.wsrf.AbstractWsResource;
54  import org.w3.x2005.x08.addressing.EndpointReferenceType;
55  
56  /**
57   * Default implementation of an agreement WSRF resource. Each agreement WSRF resource has an associated
58   * agreement instance, that implements for example agreement monitoring capabilities.
59   * 
60   * @author Oliver Waeldrich
61   * 
62   */
63  public class AgreementWsResource extends AbstractWsResource
64  {
65  
66      /**
67       * 
68       */
69      private static final String WSAG4J_SECURITY_DN = "wsag4j.security.dn";
70  
71      private Agreement agreement = null;
72  
73      private WsagSession session = null;
74  
75      private EndpointReferenceType factoryEPR = null;
76  
77      private String subjectDN = null;
78  
79      private boolean subjectInitiatlized = false;
80  
81      /**
82       * Initializes the subject DN with the DN of the entity that created the agreement instance.
83       */
84      private void initializeSubjectDN()
85      {
86          if ( subjectInitiatlized )
87          {
88              return;
89          }
90  
91          try
92          {
93              XmlString xmlObject =
94                  (XmlString) agreement.getAgreementInstance().getExecutionContext().get( WSAG4J_SECURITY_DN );
95              subjectDN = xmlObject.getStringValue();
96              subjectInitiatlized = true;
97          }
98          catch ( Exception e )
99          {
100             throw new RuntimeException( e );
101         }
102     }
103 
104     /**
105      * Sets the subject of the entity that created the agreement instance.
106      * 
107      * @param subject
108      *            the subject to set
109      */
110     public void setSubject( Subject subject )
111     {
112         try
113         {
114             //
115             // empty dn is treated as not authenticated
116             //
117             subjectDN = "";
118 
119             try
120             {
121                 subjectDN = resolveSubjectDN( subject );
122             }
123             catch ( Exception e )
124             {
125                 throw new RuntimeException( "failed to resolve authenticated user DN", e );
126             }
127 
128             //
129             // store the dn in the agreement properties, so it is persisted with the agreement
130             //
131             agreement.getAgreementInstance().getExecutionContext()
132                      .put( WSAG4J_SECURITY_DN, XmlString.Factory.newValue( subjectDN ) );
133         }
134         catch ( Exception e )
135         {
136             throw new RuntimeException( e );
137         }
138     }
139 
140     /**
141      * @param subject
142      */
143     private String resolveSubjectDN( Subject subject )
144     {
145         //
146         // if a subject is provided, we extract the dn from the cert used four authentication
147         //
148         if ( subject != null )
149         {
150             //
151             // get the first public credential
152             //
153             Set<X509Certificate> cretentials = subject.getPublicCredentials( X509Certificate.class );
154             for ( Iterator<X509Certificate> iterator = cretentials.iterator(); iterator.hasNext(); )
155             {
156                 X509Certificate cert = iterator.next();
157                 return cert.getSubjectDN().toString();
158             }
159         }
160 
161         return null;
162     }
163 
164     /**
165      * @return the associated agreement instance
166      * 
167      * @throws WSSecurityException
168      *             indicates that the user that tries to access the agreement instance is not the one that
169      *             created this instance
170      */
171     public Agreement getAgreement() throws WSSecurityException
172     {
173         //
174         // check that the user accessing the agreement instance is the same that
175         // initially created that instance
176         //
177         Subject currentUser =
178             (Subject) WsagEngine.getWsagMessageContext().get( SecurityConstants.AUTHENTICATED_USER );
179 
180         //
181         // access to the the agreement instance is permitted if one of the following conditions is fulfilled:
182         //
183         // 1. the resource is currently initializing
184         // 2. creator or current user is null and anonymous access is allowed (testing)
185         // 3. creator and current user are equal
186         //
187         if ( !isInitialized() )
188         {
189             return agreement;
190         }
191 
192         initializeSubjectDN();
193 
194         if ( ( currentUser == null ) || ( subjectDN == null ) )
195         {
196             if ( WsagEngine.isAllowAnonymousAccess() )
197             {
198                 return agreement;
199             }
200         }
201         else if ( subjectDN.equals( resolveSubjectDN( currentUser ) ) )
202         {
203             return agreement;
204         }
205 
206         //
207         // if the authenticated user does not math the creator of the agreement throw an exception
208         //
209         String message =
210             "The authenticated user does not match the creator of the agreement instance."
211                 + "\nauthenticated: {0}\nexpected: {1}";
212         throw new WSSecurityException( MessageFormat.format( message, currentUser, subjectDN ) );
213     }
214 
215     /**
216      * 
217      * @param agreement
218      *            the associated agreement instance
219      */
220     public void setAgreement( Agreement agreement )
221     {
222         this.agreement = agreement;
223     }
224 
225     /**
226      * 
227      * @param session
228      *            the agreement session
229      */
230     public void setSession( WsagSession session )
231     {
232         this.session = session;
233     }
234 
235     /**
236      * 
237      * @return the agreement session
238      */
239     public WsagSession getSession()
240     {
241         return session;
242     }
243 
244     /**
245      * {@inheritDoc}
246      */
247     @Override
248     public QName getInterfaceName()
249     {
250         return WsagConstants.WSAG_AGREEMENT_QNAME;
251     }
252 
253     /**
254      * @return the factoryEPR
255      */
256     public EndpointReferenceType getFactoryEPR()
257     {
258         return factoryEPR;
259     }
260 
261     /**
262      * @param factoryEPR
263      *            the factoryEPR to set
264      */
265     public void setFactoryEPR( EndpointReferenceType factoryEPR )
266     {
267         this.factoryEPR = factoryEPR;
268     }
269 
270     /**
271      * Returns an {@link AgreementPropertiesCollection} for retrieving the
272      * {@link org.ogf.schemas.graap.wsAgreement.AgreementPropertiesDocument} via the WSRF
273      * GetResourcePropertyDocument method.
274      * 
275      * @return the agreement resource property collection
276      * 
277      * @see AgreementPropertiesCollection
278      * @see org.apache.muse.ws.resource.impl.SimpleWsResource#createPropertyCollection()
279      */
280     @Override
281     protected ResourcePropertyCollection createPropertyCollection()
282     {
283         return new AgreementPropertiesCollection( this );
284     }
285 }