You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2011/10/10 17:17:26 UTC
svn commit: r1181015 -
/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NegotiateScheme.java
Author: olegk
Date: Mon Oct 10 15:17:26 2011
New Revision: 1181015
URL: http://svn.apache.org/viewvc?rev=1181015&view=rev
Log:
Better state handling in NegotiateScheme#authenticate
Modified:
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NegotiateScheme.java
Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NegotiateScheme.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NegotiateScheme.java?rev=1181015&r1=1181014&r2=1181015&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NegotiateScheme.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NegotiateScheme.java Mon Oct 10 15:17:26 2011
@@ -152,124 +152,129 @@ public class NegotiateScheme extends Aut
if (request == null) {
throw new IllegalArgumentException("HTTP request may not be null");
}
- if (state != State.CHALLENGE_RECEIVED) {
- throw new IllegalStateException(
- "Negotiation authentication process has not been initiated");
- }
- try {
- String key = null;
- if (isProxy()) {
- key = ExecutionContext.HTTP_PROXY_HOST;
- } else {
- key = ExecutionContext.HTTP_TARGET_HOST;
- }
- HttpHost host = (HttpHost) context.getAttribute(key);
- if (host == null) {
- throw new AuthenticationException("Authentication host is not set " +
- "in the execution context");
- }
- String authServer;
- if (!this.stripPort && host.getPort() > 0) {
- authServer = host.toHostString();
- } else {
- authServer = host.getHostName();
- }
+ switch (state) {
+ case UNINITIATED:
+ throw new AuthenticationException("SPNEGO authentication has not been initiated");
+ case FAILED:
+ throw new AuthenticationException("SPNEGO authentication has failed");
+ case CHALLENGE_RECEIVED:
+ try {
+ String key = null;
+ if (isProxy()) {
+ key = ExecutionContext.HTTP_PROXY_HOST;
+ } else {
+ key = ExecutionContext.HTTP_TARGET_HOST;
+ }
+ HttpHost host = (HttpHost) context.getAttribute(key);
+ if (host == null) {
+ throw new AuthenticationException("Authentication host is not set " +
+ "in the execution context");
+ }
+ String authServer;
+ if (!this.stripPort && host.getPort() > 0) {
+ authServer = host.toHostString();
+ } else {
+ authServer = host.getHostName();
+ }
- if (log.isDebugEnabled()) {
- log.debug("init " + authServer);
- }
- /* Using the SPNEGO OID is the correct method.
- * Kerberos v5 works for IIS but not JBoss. Unwrapping
- * the initial token when using SPNEGO OID looks like what is
- * described here...
- *
- * http://msdn.microsoft.com/en-us/library/ms995330.aspx
- *
- * Another helpful URL...
- *
- * http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/tsec_SPNEGO_token.html
- *
- * Unfortunately SPNEGO is JRE >=1.6.
- */
+ if (log.isDebugEnabled()) {
+ log.debug("init " + authServer);
+ }
+ /* Using the SPNEGO OID is the correct method.
+ * Kerberos v5 works for IIS but not JBoss. Unwrapping
+ * the initial token when using SPNEGO OID looks like what is
+ * described here...
+ *
+ * http://msdn.microsoft.com/en-us/library/ms995330.aspx
+ *
+ * Another helpful URL...
+ *
+ * http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/tsec_SPNEGO_token.html
+ *
+ * Unfortunately SPNEGO is JRE >=1.6.
+ */
+
+ /** Try SPNEGO by default, fall back to Kerberos later if error */
+ negotiationOid = new Oid(SPNEGO_OID);
+
+ boolean tryKerberos = false;
+ try {
+ GSSManager manager = getManager();
+ GSSName serverName = manager.createName("HTTP@" + authServer, GSSName.NT_HOSTBASED_SERVICE);
+ gssContext = manager.createContext(
+ serverName.canonicalize(negotiationOid), negotiationOid, null,
+ GSSContext.DEFAULT_LIFETIME);
+ gssContext.requestMutualAuth(true);
+ gssContext.requestCredDeleg(true);
+ } catch (GSSException ex){
+ // BAD MECH means we are likely to be using 1.5, fall back to Kerberos MECH.
+ // Rethrow any other exception.
+ if (ex.getMajor() == GSSException.BAD_MECH ){
+ log.debug("GSSException BAD_MECH, retry with Kerberos MECH");
+ tryKerberos = true;
+ } else {
+ throw ex;
+ }
- /** Try SPNEGO by default, fall back to Kerberos later if error */
- negotiationOid = new Oid(SPNEGO_OID);
+ }
+ if (tryKerberos){
+ /* Kerberos v5 GSS-API mechanism defined in RFC 1964.*/
+ log.debug("Using Kerberos MECH " + KERBEROS_OID);
+ negotiationOid = new Oid(KERBEROS_OID);
+ GSSManager manager = getManager();
+ GSSName serverName = manager.createName("HTTP@" + authServer, GSSName.NT_HOSTBASED_SERVICE);
+ gssContext = manager.createContext(
+ serverName.canonicalize(negotiationOid), negotiationOid, null,
+ GSSContext.DEFAULT_LIFETIME);
+ gssContext.requestMutualAuth(true);
+ gssContext.requestCredDeleg(true);
+ }
+ if (token == null) {
+ token = new byte[0];
+ }
+ token = gssContext.initSecContext(token, 0, token.length);
+ if (token == null) {
+ state = State.FAILED;
+ throw new AuthenticationException("GSS security context initialization failed");
+ }
- boolean tryKerberos = false;
- try {
- GSSManager manager = getManager();
- GSSName serverName = manager.createName("HTTP@" + authServer, GSSName.NT_HOSTBASED_SERVICE);
- gssContext = manager.createContext(
- serverName.canonicalize(negotiationOid), negotiationOid, null,
- GSSContext.DEFAULT_LIFETIME);
- gssContext.requestMutualAuth(true);
- gssContext.requestCredDeleg(true);
- } catch (GSSException ex){
- // BAD MECH means we are likely to be using 1.5, fall back to Kerberos MECH.
- // Rethrow any other exception.
- if (ex.getMajor() == GSSException.BAD_MECH ){
- log.debug("GSSException BAD_MECH, retry with Kerberos MECH");
- tryKerberos = true;
- } else {
- throw ex;
+ /*
+ * IIS accepts Kerberos and SPNEGO tokens. Some other servers Jboss, Glassfish?
+ * seem to only accept SPNEGO. Below wraps Kerberos into SPNEGO token.
+ */
+ if (spengoGenerator != null && negotiationOid.toString().equals(KERBEROS_OID)) {
+ token = spengoGenerator.generateSpnegoDERObject(token);
}
- }
- if (tryKerberos){
- /* Kerberos v5 GSS-API mechanism defined in RFC 1964.*/
- log.debug("Using Kerberos MECH " + KERBEROS_OID);
- negotiationOid = new Oid(KERBEROS_OID);
- GSSManager manager = getManager();
- GSSName serverName = manager.createName("HTTP@" + authServer, GSSName.NT_HOSTBASED_SERVICE);
- gssContext = manager.createContext(
- serverName.canonicalize(negotiationOid), negotiationOid, null,
- GSSContext.DEFAULT_LIFETIME);
- gssContext.requestMutualAuth(true);
- gssContext.requestCredDeleg(true);
- }
- if (token == null) {
- token = new byte[0];
- }
- token = gssContext.initSecContext(token, 0, token.length);
- if (token == null) {
+ state = State.TOKEN_GENERATED;
+ } catch (GSSException gsse) {
state = State.FAILED;
- throw new AuthenticationException("GSS security context initialization failed");
- }
-
- /*
- * IIS accepts Kerberos and SPNEGO tokens. Some other servers Jboss, Glassfish?
- * seem to only accept SPNEGO. Below wraps Kerberos into SPNEGO token.
- */
- if (spengoGenerator != null && negotiationOid.toString().equals(KERBEROS_OID)) {
- token = spengoGenerator.generateSpnegoDERObject(token);
+ if (gsse.getMajor() == GSSException.DEFECTIVE_CREDENTIAL
+ || gsse.getMajor() == GSSException.CREDENTIALS_EXPIRED)
+ throw new InvalidCredentialsException(gsse.getMessage(), gsse);
+ if (gsse.getMajor() == GSSException.NO_CRED )
+ throw new InvalidCredentialsException(gsse.getMessage(), gsse);
+ if (gsse.getMajor() == GSSException.DEFECTIVE_TOKEN
+ || gsse.getMajor() == GSSException.DUPLICATE_TOKEN
+ || gsse.getMajor() == GSSException.OLD_TOKEN)
+ throw new AuthenticationException(gsse.getMessage(), gsse);
+ // other error
+ throw new AuthenticationException(gsse.getMessage());
+ } catch (IOException ex){
+ state = State.FAILED;
+ throw new AuthenticationException(ex.getMessage());
}
-
- state = State.TOKEN_GENERATED;
+ case TOKEN_GENERATED:
String tokenstr = new String(Base64.encodeBase64(token, false));
if (log.isDebugEnabled()) {
log.debug("Sending response '" + tokenstr + "' back to the auth server");
}
return new BasicHeader("Authorization", "Negotiate " + tokenstr);
- } catch (GSSException gsse) {
- state = State.FAILED;
- if (gsse.getMajor() == GSSException.DEFECTIVE_CREDENTIAL
- || gsse.getMajor() == GSSException.CREDENTIALS_EXPIRED)
- throw new InvalidCredentialsException(gsse.getMessage(), gsse);
- if (gsse.getMajor() == GSSException.NO_CRED )
- throw new InvalidCredentialsException(gsse.getMessage(), gsse);
- if (gsse.getMajor() == GSSException.DEFECTIVE_TOKEN
- || gsse.getMajor() == GSSException.DUPLICATE_TOKEN
- || gsse.getMajor() == GSSException.OLD_TOKEN)
- throw new AuthenticationException(gsse.getMessage(), gsse);
- // other error
- throw new AuthenticationException(gsse.getMessage());
- } catch (IOException ex){
- state = State.FAILED;
- throw new AuthenticationException(ex.getMessage());
+ default:
+ throw new IllegalStateException("Illegal state: " + state);
}
}
-
/**
* Returns the authentication parameter with the given name, if available.
*