Index: juddi-core-openjpa/src/test/resources/juddiv3.properties =================================================================== --- juddi-core-openjpa/src/test/resources/juddiv3.properties (revision 1451436) +++ juddi-core-openjpa/src/test/resources/juddiv3.properties (working copy) @@ -77,3 +77,6 @@ juddi.notification.start.buffer=0 + +# Duration of time for tokens to expire +juddi.authenticate.Expiration=15 \ No newline at end of file Index: juddi-core/src/main/java/org/apache/juddi/api/impl/AuthenticatedService.java =================================================================== --- juddi-core/src/main/java/org/apache/juddi/api/impl/AuthenticatedService.java (revision 1451436) +++ juddi-core/src/main/java/org/apache/juddi/api/impl/AuthenticatedService.java (working copy) @@ -18,9 +18,16 @@ package org.apache.juddi.api.impl; import java.util.Date; +import java.util.GregorianCalendar; import javax.persistence.EntityManager; +import javax.persistence.EntityTransaction; +import org.apache.juddi.api.util.QueryStatus; +import org.apache.juddi.api.util.SecurityQuery; +import org.apache.juddi.config.AppConfig; +import org.apache.juddi.config.PersistenceManager; +import org.apache.juddi.config.ResourceConfig; import org.apache.juddi.model.UddiEntityPublisher; import org.apache.juddi.v3.auth.Authenticator; import org.apache.juddi.v3.auth.AuthenticatorFactory; @@ -28,8 +35,10 @@ import org.apache.juddi.v3.error.ErrorMessage; import org.uddi.v3_service.DispositionReportFaultMessage; -/** +/**Although this class is abstract, it provides token validation * @author Jeff Faath + * + * @author Alex O'Ree - modified to include token expiration validation */ public abstract class AuthenticatedService { public static final int AUTHTOKEN_ACTIVE = 1; @@ -43,7 +52,21 @@ org.apache.juddi.model.AuthToken modelAuthToken = em.find(org.apache.juddi.model.AuthToken.class, authInfo); if (modelAuthToken == null) throw new AuthTokenRequiredException(new ErrorMessage("errors.auth.AuthInvalid")); - + + GregorianCalendar gcal = modelAuthToken.getExpiration(); + if (gcal == null) + { + throw new AuthTokenRequiredException(new ErrorMessage("errors.auth.AuthTokenExpired")); + } + GregorianCalendar now = new GregorianCalendar(); + if (!now.equals(gcal)) + { + if (now.after(gcal)) + { + modelAuthToken.setTokenState(AUTHTOKEN_RETIRED); + throw new AuthTokenRequiredException(new ErrorMessage("errors.auth.AuthTokenExpired")); + } + } if (modelAuthToken.getTokenState() == AUTHTOKEN_RETIRED) throw new AuthTokenRequiredException(new ErrorMessage("errors.auth.AuthInvalid")); @@ -58,7 +81,7 @@ throw new AuthTokenRequiredException(new ErrorMessage("errors.auth.AuthInvalid")); // Auth token is being used. Adjust appropriate values so that it's internal 'expiration clock' is reset. - modelAuthToken.setLastUsed(new Date()); + modelAuthToken.setLastUsed(new GregorianCalendar()); modelAuthToken.setNumberOfUses(modelAuthToken.getNumberOfUses() + 1); return entityPublisher; Index: juddi-core/src/main/java/org/apache/juddi/api/impl/UDDISecurityImpl.java =================================================================== --- juddi-core/src/main/java/org/apache/juddi/api/impl/UDDISecurityImpl.java (revision 1451436) +++ juddi-core/src/main/java/org/apache/juddi/api/impl/UDDISecurityImpl.java (working copy) @@ -17,8 +17,10 @@ package org.apache.juddi.api.impl; -import java.util.Date; import java.util.UUID; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.logging.Level; import javax.jws.WebService; import javax.persistence.EntityManager; @@ -30,11 +32,17 @@ import org.uddi.v3_service.DispositionReportFaultMessage; import org.uddi.v3_service.UDDISecurityPortType; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.juddi.api.util.PublicationQuery; import org.apache.juddi.api.util.QueryStatus; import org.apache.juddi.api.util.ReplicationQuery; import org.apache.juddi.api.util.SecurityQuery; +import org.apache.juddi.config.AppConfig; import org.apache.juddi.config.PersistenceManager; +import org.apache.juddi.config.Property; +import org.apache.juddi.config.ResourceConfig; import org.apache.juddi.mapping.MappingModelToApi; import org.apache.juddi.model.Publisher; import org.apache.juddi.v3.auth.Authenticator; @@ -49,7 +57,7 @@ endpointInterface="org.uddi.v3_service.UDDISecurityPortType", targetNamespace = "urn:uddi-org:v3_service") public class UDDISecurityImpl extends AuthenticatedService implements UDDISecurityPortType { - + private Log log = LogFactory.getLog(AppConfig.class); public static final String AUTH_TOKEN_PREFIX = "authtoken:"; private UDDIServiceCounter serviceCounter; @@ -71,7 +79,7 @@ org.apache.juddi.model.AuthToken modelAuthToken = em.find(org.apache.juddi.model.AuthToken.class, body.getAuthInfo()); if (modelAuthToken != null) { - modelAuthToken.setLastUsed(new Date()); + modelAuthToken.setLastUsed(new GregorianCalendar()); modelAuthToken.setNumberOfUses(modelAuthToken.getNumberOfUses() + 1); modelAuthToken.setTokenState(AUTHTOKEN_RETIRED); } @@ -124,8 +132,22 @@ org.apache.juddi.model.AuthToken modelAuthToken = new org.apache.juddi.model.AuthToken(); if (authInfo != null) { modelAuthToken.setAuthToken(authInfo); - modelAuthToken.setCreated(new Date()); - modelAuthToken.setLastUsed(new Date()); + modelAuthToken.setCreated(new GregorianCalendar()); + modelAuthToken.setLastUsed(new GregorianCalendar()); + GregorianCalendar gcal = new GregorianCalendar(); + try{ + int minutes=AppConfig.getConfiguration().getInt(Property.JUDDI_AUTH_TOKEN_EXPIRATION); + if (minutes <=0) + throw new ConfigurationException("invalid token expiration range"); + gcal.add(Calendar.MINUTE, minutes); + } + catch (Exception ex){ + log.warn(ResourceConfig.getGlobalMessage("errors.config.InvalidTokenExpirationSetting"),ex); + gcal.add(Calendar.MINUTE, 15); + } + + + modelAuthToken.setExpiration(gcal); modelAuthToken.setAuthorizedName(publisherId); modelAuthToken.setNumberOfUses(0); modelAuthToken.setTokenState(AUTHTOKEN_ACTIVE); Index: juddi-core/src/main/java/org/apache/juddi/config/Property.java =================================================================== --- juddi-core/src/main/java/org/apache/juddi/config/Property.java (revision 1451436) +++ juddi-core/src/main/java/org/apache/juddi/config/Property.java (working copy) @@ -26,6 +26,7 @@ public final static String JUDDI_NODE_ID ="juddi.nodeId"; public final static String JUDDI_TRANSFER_EXPIRATION_DAYS ="juddi.transfer.expiration.days"; public final static String JUDDI_AUTHENTICATE_INQUIRY ="juddi.authenticate.Inquiry"; + public final static String JUDDI_AUTH_TOKEN_EXPIRATION ="juddi.authenticate.Expiration"; public final static String JUDDI_SUBSCRIPTION_EXPIRATION_DAYS="juddi.subscription.expiration.days"; public final static String JUDDI_NOTIFICATION_START_BUFFER ="juddi.notification.start.buffer"; public final static String JUDDI_NOTIFICATION_INTERVAL ="juddi.notification.interval"; Index: juddi-core/src/main/java/org/apache/juddi/model/AuthToken.java =================================================================== --- juddi-core/src/main/java/org/apache/juddi/model/AuthToken.java (revision 1451436) +++ juddi-core/src/main/java/org/apache/juddi/model/AuthToken.java (working copy) @@ -23,7 +23,7 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; - +import java.util.GregorianCalendar; /** * @author Kurt T Stam */ @@ -34,23 +34,25 @@ private static final long serialVersionUID = 1147567747533293480L; private String authToken; private String authorizedName; - private Date created; - private Date lastUsed; + private GregorianCalendar created; + private GregorianCalendar lastUsed; private int numberOfUses; private int tokenState; + private GregorianCalendar expiration; public AuthToken() { } public AuthToken(String authToken, String authorizedName, - String publisherName, Date created, Date lastUsed, - int numberOfUses, int tokenState) { + String publisherName, GregorianCalendar created, GregorianCalendar lastUsed, + int numberOfUses, int tokenState, GregorianCalendar expiration) { this.authToken = authToken; this.authorizedName = authorizedName; this.created = created; this.lastUsed = lastUsed; this.numberOfUses = numberOfUses; this.tokenState = tokenState; + this.expiration = expiration; } @Id @@ -72,19 +74,28 @@ @Temporal(TemporalType.TIMESTAMP) @Column(name = "created", nullable = false, length = 29) - public Date getCreated() { + public GregorianCalendar getCreated() { return this.created; } - public void setCreated(Date created) { + public void setCreated(GregorianCalendar created) { this.created = created; } + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "expiration", nullable = false, length = 29) + public GregorianCalendar getExpiration() { + return this.expiration; + } + public void setExpiration(GregorianCalendar expiration) { + this.expiration = expiration; + } @Temporal(TemporalType.TIMESTAMP) @Column(name = "last_used", nullable = false, length = 29) - public Date getLastUsed() { + public GregorianCalendar getLastUsed() { return this.lastUsed; } - public void setLastUsed(Date lastUsed) { + public void setLastUsed(GregorianCalendar lastUsed) { this.lastUsed = lastUsed; } Index: juddi-core/src/main/resources/messages.properties =================================================================== --- juddi-core/src/main/resources/messages.properties (revision 1451436) +++ juddi-core/src/main/resources/messages.properties (working copy) @@ -66,7 +66,7 @@ errors.configuration.Retrieval=An error occurred attempting to retrieve configuration information errors.install.AlreadyInstalled=It appears that the application is already installed. Please un-install before proceeding. errors.NullInput=No input was provided for this API call -errors.keyunavailable.BadPartition=The proposed key is not within the partition defined by owning publisher +errors.keyunavailable.BadPartition=The proposed key is not within the partition defined by owning publisher. If you're tring to create a new tModel in a new partition, try creating a tModel that ends in :keyGenerator errors.keyunavailable.KeyExists=The key used for the save operation already exists. Another key must be chosen errors.invalidkey.NullKey=The key cannot be null errors.invalidkey.MalformedKey=The passed key does not conform to UDDI v3 rules @@ -93,6 +93,7 @@ errors.invalidprojection.ParentMismatch=The supplied business key doesn't match the actual business key of the service being projected errors.usermismatch.InvalidOwner=The user is not authorized to access the given entity errors.usermismatch.InvalidOwnerParent=The user is not authorized to access the given parent entity +errors.config.InvalidTokenExpirationSetting=The authentication token expiration setting is missing or invalid, will default to 15 minutes. See juddiv3.properties file #-- Error messages related to entities and other data structures errors.savebusiness.NoInput=At least one BusinessEntity must be provided @@ -109,8 +110,8 @@ errors.bindingtemplate.NoAccessPoint=A binding template must contain an access point errors.tmodel.NullInput=The tModel structure cannot be blank errors.tmodel.NoName=A tModel must contain a name -errors.tmodel.keygenerator.BadCategory=A Key Generator tModel must have exactly one 'types' category whose value is 'keyGenerator' -errors.tmodel.keygenerator.RootKeyGen=A Key Generator cannot be added for the root publisher +errors.tmodel.keygenerator.BadCategory=A Key Generator tModel must have exactly one 'types' category (categoryBag/keyedReference/value) whose value is 'keyGenerator' +errors.tmodel.keygenerator.RootKeyGen=A Key Generator cannot be added for the root publisher. Try signing in as a different user errors.pubassertion.NullInput=The publisherAssertion structure cannot be blank errors.pubassertion.BlankKeyedRef=The keyedReference of the publisherAssertion cannot be blank. All fields must contain content. errors.pubassertion.BlankFromKey=The fromKey of the publisherAssertion cannot be blank. @@ -140,10 +141,10 @@ errors.instdetails.NoOverviewOrParms=The instanceDetails structure must contain either an overviewDoc or instanceParms errors.overviewdoc.NullInput=The overviewDoc structure cannot be blank errors.overviewdoc.NoDescOrUrl=The overviewDoc structure must contain either a description or overviewURL -errors.findqualifiers.NoInput=The findQualifier collection must contain at least one findQualifier +errors.findqualifiers.NoInput=The findQualifier collection must contain at least one findQualifier. Try 'approximateMatch' errors.findqualifiers.DuplicateValue=A duplicate findQualifier was passed. No duplicates are allowed errors.findqualifiers.InvalidCombo=An invalid findQualifier combination occurred -errors.findbusiness.NoInput=At least one search criterion must be supplied +errors.findbusiness.NoInput=At least one search criterion must be supplied. Try using '%' as a wild card with the a 'approximateMatch' find qualifer for everything errors.findservice.NoInput=At least one name, categoryBag, find_tModel or tModelBag or name must be supplied errors.findbinding.NoInput=At least one categoryBag, find_tModel or tModelBag must be supplied errors.findtmodel.NoInput=At least one categoryBag, identifierBag or name must be supplied @@ -197,6 +198,7 @@ #-- Authentication error messages errors.auth.AuthRequired=Authentication is required for this API call errors.auth.AuthInvalid=Invalid authentication information +errors.auth.AuthTokenExpired=The authentication token is expired errors.auth.InvalidUserId=An invalid user identification was passed errors.auth.InvalidCredentials=Invalid credentials were passed errors.auth.NoPublisher=The user provided does not have a publishing account @@ -216,6 +218,5 @@ errors.local.registryunavailable=The registry is currently unavailable errors.local.operation.notidentified=The UDDI service operation could not be identified errors.local.inquiry.notsupported=The operation is not supported by the UDDI version 3 Inquiry API -errors.local.publish.notsupported=The operation is not supported by the UDDI ver -sion 3 Publish API +errors.local.publish.notsupported=The operation is not supported by the UDDI version 3 Publish API errors.local.security.notsupported=The operation is not supported by the UDDI version 3 Security API Index: juddiv3-samples/src/main/webapp/WEB-INF/classes/juddiv3.properties =================================================================== --- juddiv3-samples/src/main/webapp/WEB-INF/classes/juddiv3.properties (revision 1451436) +++ juddiv3-samples/src/main/webapp/WEB-INF/classes/juddiv3.properties (working copy) @@ -86,3 +86,6 @@ #juddi.proxy.factory.url.pkg =org.jboss.naming + +# Duration of time for tokens to expire +juddi.authenticate.Expiration=15 \ No newline at end of file Index: juddiv3-war/src/main/webapp/WEB-INF/classes/juddiv3.properties =================================================================== --- juddiv3-war/src/main/webapp/WEB-INF/classes/juddiv3.properties (revision 1451436) +++ juddiv3-war/src/main/webapp/WEB-INF/classes/juddiv3.properties (working copy) @@ -85,3 +85,6 @@ juddi.rmi.port=0 + +# Duration of time for tokens to expire +juddi.authenticate.Expiration=15 \ No newline at end of file