Author: markt
Date: Thu Mar 31 19:33:04 2011
New Revision: 1087416
URL: http://svn.apache.org/viewvc?rev=1087416&view=rev
Log:
SPNEGO support part 2
Expose the users delegated credentials through a request attribute so
applications can make use of it
Modified:
tomcat/trunk/java/org/apache/catalina/Globals.java
tomcat/trunk/java/org/apache/catalina/Realm.java
tomcat/trunk/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java
tomcat/trunk/java/org/apache/catalina/connector/Request.java
tomcat/trunk/java/org/apache/catalina/realm/CombinedRealm.java
tomcat/trunk/java/org/apache/catalina/realm/GenericPrincipal.java
tomcat/trunk/java/org/apache/catalina/realm/LocalStrings.properties
tomcat/trunk/java/org/apache/catalina/realm/LockOutRealm.java
tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java
tomcat/trunk/java/org/apache/catalina/session/StandardSession.java
tomcat/trunk/webapps/docs/config/valve.xml
Modified: tomcat/trunk/java/org/apache/catalina/Globals.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Globals.java?rev=1087416&r1=1087415&r2=1087416&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/Globals.java (original)
+++ tomcat/trunk/java/org/apache/catalina/Globals.java Thu Mar 31 19:33:04 2011
@@ -151,6 +151,10 @@ public final class Globals {
"javax.security.auth.subject";
+ public static final String GSS_CREDENTIAL_ATTR =
+ "org.apache.catalina.realm.GSS_CREDENTIAL";
+
+
/**
* The master flag which controls strict servlet specification
* compliance.
Modified: tomcat/trunk/java/org/apache/catalina/Realm.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Realm.java?rev=1087416&r1=1087415&r2=1087416&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/Realm.java (original)
+++ tomcat/trunk/java/org/apache/catalina/Realm.java Thu Mar 31 19:33:04 2011
@@ -111,9 +111,11 @@ public interface Realm {
* Return the Principal associated with the specified chain of X509
* client certificates. If there is none, return <code>null</code>.
*
- * @param certs The gssContext processed by the {@link Authenticator}.
+ * @param gssContext The gssContext processed by the {@link Authenticator}.
+ * @param storeCreds Should the realm attempt to store the delegated
+ * credentials in the returned Principal?
*/
- public Principal authenticate(GSSContext gssContext);
+ public Principal authenticate(GSSContext gssContext, boolean storeCreds);
/**
Modified:
tomcat/trunk/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java?rev=1087416&r1=1087415&r2=1087416&view=diff
==============================================================================
---
tomcat/trunk/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java
(original)
+++
tomcat/trunk/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java
Thu Mar 31 19:33:04 2011
@@ -77,6 +77,15 @@ public class SpnegoAuthenticator extends
this.loginConfigName = loginConfigName;
}
+ private boolean storeDelegatedCredentials = true;
+ public boolean isStoreDelegatedCredentials() {
+ return storeDelegatedCredentials;
+ }
+ public void setStoreDelegatedCredentials(
+ boolean storeDelegatedCredentials) {
+ this.storeDelegatedCredentials = storeDelegatedCredentials;
+ }
+
@Override
protected String getAuthMethod() {
@@ -229,7 +238,8 @@ public class SpnegoAuthenticator extends
return false;
}
- principal = context.getRealm().authenticate(gssContext);
+ principal = context.getRealm().authenticate(gssContext,
+ storeDelegatedCredentials);
} catch (GSSException e) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("spnegoAuthenticator.ticketValidateFail",
Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=1087416&r1=1087415&r2=1087416&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Thu Mar 31
19:33:04 2011
@@ -923,6 +923,13 @@ public class Request
return asyncSupported;
}
+ if (name.equals(Globals.GSS_CREDENTIAL_ATTR)) {
+ if (userPrincipal instanceof GenericPrincipal) {
+ return ((GenericPrincipal) userPrincipal).getGssCredential();
+ }
+ return null;
+ }
+
Object attr=attributes.get(name);
if(attr!=null)
Modified: tomcat/trunk/java/org/apache/catalina/realm/CombinedRealm.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/CombinedRealm.java?rev=1087416&r1=1087415&r2=1087416&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/realm/CombinedRealm.java (original)
+++ tomcat/trunk/java/org/apache/catalina/realm/CombinedRealm.java Thu Mar 31
19:33:04 2011
@@ -271,7 +271,7 @@ public class CombinedRealm extends Realm
* {@inheritDoc}
*/
@Override
- public Principal authenticate(GSSContext gssContext) {
+ public Principal authenticate(GSSContext gssContext, boolean storeCreds) {
if (gssContext.isEstablished()) {
Principal authenticatedUser = null;
String username = null;
@@ -292,7 +292,7 @@ public class CombinedRealm extends Realm
username, realm.getInfo()));
}
- authenticatedUser = realm.authenticate(gssContext);
+ authenticatedUser = realm.authenticate(gssContext, storeCreds);
if (authenticatedUser == null) {
if (log.isDebugEnabled()) {
Modified: tomcat/trunk/java/org/apache/catalina/realm/GenericPrincipal.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/GenericPrincipal.java?rev=1087416&r1=1087415&r2=1087416&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/realm/GenericPrincipal.java (original)
+++ tomcat/trunk/java/org/apache/catalina/realm/GenericPrincipal.java Thu Mar
31 19:33:04 2011
@@ -25,6 +25,8 @@ import java.util.List;
import javax.security.auth.login.LoginContext;
+import org.ietf.jgss.GSSCredential;
+
/**
* Generic implementation of <strong>java.security.Principal</strong> that
@@ -98,6 +100,26 @@ public class GenericPrincipal implements
*/
public GenericPrincipal(String name, String password, List<String> roles,
Principal userPrincipal, LoginContext loginContext) {
+ this(name, password, roles, userPrincipal, loginContext, null);
+ }
+
+ /**
+ * Construct a new Principal, associated with the specified Realm, for the
+ * specified username and password, with the specified role names
+ * (as Strings).
+ *
+ * @param name The username of the user represented by this Principal
+ * @param password Credentials used to authenticate this user
+ * @param roles List of roles (must be Strings) possessed by this user
+ * @param userPrincipal - the principal to be returned from the request
+ * getUserPrincipal call if not null; if null, this will be returned
+ * @param loginContext - If provided, this will be used to log out the
user
+ * at the appropriate time
+ * @param gssCredential - If provided, the user's delegated
credentials
+ */
+ public GenericPrincipal(String name, String password, List<String> roles,
+ Principal userPrincipal, LoginContext loginContext,
+ GSSCredential gssCredential) {
super();
this.name = name;
this.password = password;
@@ -109,6 +131,7 @@ public class GenericPrincipal implements
Arrays.sort(this.roles);
}
this.loginContext = loginContext;
+ this.gssCredential = gssCredential;
}
@@ -167,6 +190,19 @@ public class GenericPrincipal implements
*/
protected LoginContext loginContext = null;
+
+ /**
+ * The user's delegated credentials.
+ */
+ protected GSSCredential gssCredential = null;
+
+ public GSSCredential getGssCredential() {
+ return this.gssCredential;
+ }
+ protected void setGssCredential(GSSCredential gssCredential) {
+ this.gssCredential = gssCredential;
+ }
+
// --------------------------------------------------------- Public Methods
Modified: tomcat/trunk/java/org/apache/catalina/realm/LocalStrings.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/LocalStrings.properties?rev=1087416&r1=1087415&r2=1087416&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/realm/LocalStrings.properties
(original)
+++ tomcat/trunk/java/org/apache/catalina/realm/LocalStrings.properties Thu Mar
31 19:33:04 2011
@@ -65,6 +65,7 @@ memoryRealm.readXml=Exception while read
memoryRealm.xmlFeatureEncoding=Exception configuring digester to permit java
encoding names in XML files. Only IANA encoding names will be supported.
realmBase.algorithm=Invalid message digest algorithm {0} specified
realmBase.alreadyStarted=This Realm has already been started
+realmBase.delegatedCredentialFail=Unable to obtain delegated credentials for
user [{0}
realmBase.digest=Error digesting user credentials
realmBase.forbidden=Access to the requested resource has been denied
realmBase.hasRoleFailure=Username {0} does NOT have role {1}
Modified: tomcat/trunk/java/org/apache/catalina/realm/LockOutRealm.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/LockOutRealm.java?rev=1087416&r1=1087415&r2=1087416&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/realm/LockOutRealm.java (original)
+++ tomcat/trunk/java/org/apache/catalina/realm/LockOutRealm.java Thu Mar 31
19:33:04 2011
@@ -225,7 +225,7 @@ public class LockOutRealm extends Combin
* {@inheritDoc}
*/
@Override
- public Principal authenticate(GSSContext gssContext) {
+ public Principal authenticate(GSSContext gssContext, boolean storeCreds) {
if (gssContext.isEstablished()) {
String username = null;
GSSName name = null;
@@ -246,7 +246,8 @@ public class LockOutRealm extends Combin
return null;
}
- Principal authenticatedUser = super.authenticate(gssContext);
+ Principal authenticatedUser =
+ super.authenticate(gssContext, storeCreds);
if (authenticatedUser == null) {
registerAuthFailure(username);
Modified: tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java?rev=1087416&r1=1087415&r2=1087416&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java (original)
+++ tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java Thu Mar 31
19:33:04 2011
@@ -55,6 +55,7 @@ import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.res.StringManager;
import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSName;
@@ -424,7 +425,7 @@ public abstract class RealmBase extends
* {@inheritDoc}
*/
@Override
- public Principal authenticate(GSSContext gssContext) {
+ public Principal authenticate(GSSContext gssContext, boolean storeCred) {
if (gssContext.isEstablished()) {
GSSName name = null;
try {
@@ -434,7 +435,20 @@ public abstract class RealmBase extends
}
if (name!= null) {
- return getPrincipal(name.toString());
+ GSSCredential gssCredential = null;
+ if (storeCred && gssContext.getCredDelegState()) {
+ try {
+ gssCredential = gssContext.getDelegCred();
+ } catch (GSSException e) {
+ e.printStackTrace();
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString(
+ "realmBase.delegatedCredentialFail", name),
+ e);
+ }
+ }
+ }
+ return getPrincipal(name.toString(), gssCredential);
}
}
@@ -785,7 +799,7 @@ public abstract class RealmBase extends
if (roles.length == 0 && !constraint.getAllRoles()) {
if(constraint.getAuthConstraint()) {
if( log.isDebugEnabled() )
- log.debug("No roles ");
+ log.debug("No role)s ");
status = false; // No listed roles means no access at all
denyfromall = true;
break;
@@ -1181,6 +1195,17 @@ public abstract class RealmBase extends
protected abstract Principal getPrincipal(String username);
+ protected Principal getPrincipal(String username,
+ GSSCredential gssCredential) {
+ Principal p = getPrincipal(username);
+
+ if (p instanceof GenericPrincipal) {
+ ((GenericPrincipal) p).setGssCredential(gssCredential);
+ }
+
+ return p;
+ }
+
/**
* Return the Server object that is the ultimate parent for the container
* with which this Realm is associated. If the server cannot be found (eg
Modified: tomcat/trunk/java/org/apache/catalina/session/StandardSession.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/session/StandardSession.java?rev=1087416&r1=1087415&r2=1087416&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/session/StandardSession.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/session/StandardSession.java Thu Mar
31 19:33:04 2011
@@ -176,7 +176,8 @@ public class StandardSession implements
* Set of attribute names which are not allowed to be persisted.
*/
protected static final String[] excludedAttributes = {
- Globals.SUBJECT_ATTR
+ Globals.SUBJECT_ATTR,
+ Globals.GSS_CREDENTIAL_ATTR
};
Modified: tomcat/trunk/webapps/docs/config/valve.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/valve.xml?rev=1087416&r1=1087415&r2=1087416&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/valve.xml (original)
+++ tomcat/trunk/webapps/docs/config/valve.xml Thu Mar 31 19:33:04 2011
@@ -891,6 +891,15 @@
specified, the platform default provider will be used.</p>
</attribute>
+ <attribute name="storeDelegatedCredentials" required="false">
+ <p>Controls if the user' delegated credentials will be stored in
+ the user Principal. If available, the delegated credentials will be
+ available to applications (e.g. for onward authentication to external
+ services) via the <code>org.apache.catalina.realm.GSS_CREDENTIAL</code>
+ request attribute.If not set, the default value of <code>true</code>
+ will be used.</p>
+ </attribute>
+
</attributes>
</subsection>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]