View Javadoc

1   /*
2    * ====================================================================
3    *
4    *  Licensed to the Apache Software Foundation (ASF) under one or more
5    *  contributor license agreements.  See the NOTICE file distributed with
6    *  this work for additional information regarding copyright ownership.
7    *  The ASF licenses this file to You under the Apache License, Version 2.0
8    *  (the "License"); you may not use this file except in compliance with
9    *  the License.  You may obtain a copy of the License at
10   *
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   *
13   *  Unless required by applicable law or agreed to in writing, software
14   *  distributed under the License is distributed on an "AS IS" BASIS,
15   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   *  See the License for the specific language governing permissions and
17   *  limitations under the License.
18   * ====================================================================
19   *
20   * This software consists of voluntary contributions made by many
21   * individuals on behalf of the Apache Software Foundation.  For more
22   * information on the Apache Software Foundation, please see
23   * <http://www.apache.org/>.
24   */
25  
26  package org.apache.http.impl.auth;
27  
28  import java.io.IOException;
29  
30  import org.apache.commons.logging.Log;
31  import org.apache.commons.logging.LogFactory;
32  import org.apache.http.Header;
33  import org.apache.http.HttpRequest;
34  import org.apache.http.auth.AuthenticationException;
35  import org.apache.http.auth.Credentials;
36  import org.apache.http.protocol.HttpContext;
37  import org.ietf.jgss.GSSException;
38  import org.ietf.jgss.Oid;
39  
40  /**
41   * SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) authentication
42   * scheme.
43   *
44   * @since 4.1
45   *
46   * @deprecated (4.2)  use {@link SPNegoScheme} or {@link KerberosScheme}.
47   */
48  @Deprecated
49  public class NegotiateScheme extends GGSSchemeBase {
50  
51      private final Log log = LogFactory.getLog(getClass());
52  
53      private static final String SPNEGO_OID       = "1.3.6.1.5.5.2";
54      private static final String KERBEROS_OID     = "1.2.840.113554.1.2.2";
55  
56      private final SpnegoTokenGenerator spengoGenerator;
57  
58      /**
59       * Default constructor for the Negotiate authentication scheme.
60       *
61       */
62      public NegotiateScheme(final SpnegoTokenGenerator spengoGenerator, boolean stripPort) {
63          super(stripPort);
64          this.spengoGenerator = spengoGenerator;
65      }
66  
67      public NegotiateScheme(final SpnegoTokenGenerator spengoGenerator) {
68          this(spengoGenerator, false);
69      }
70  
71      public NegotiateScheme() {
72          this(null, false);
73      }
74  
75      /**
76       * Returns textual designation of the Negotiate authentication scheme.
77       *
78       * @return <code>Negotiate</code>
79       */
80      public String getSchemeName() {
81          return "Negotiate";
82      }
83  
84      public Header authenticate(
85              final Credentials credentials,
86              final HttpRequest request) throws AuthenticationException {
87          return authenticate(credentials, request, null);
88      }
89  
90      /**
91       * Produces Negotiate authorization Header based on token created by
92       * processChallenge.
93       *
94       * @param credentials Never used be the Negotiate scheme but must be provided to
95       * satisfy common-httpclient API. Credentials from JAAS will be used instead.
96       * @param request The request being authenticated
97       *
98       * @throws AuthenticationException if authorisation string cannot
99       *   be generated due to an authentication failure
100      *
101      * @return an Negotiate authorisation Header
102      */
103     @Override
104     public Header authenticate(
105             final Credentials credentials,
106             final HttpRequest request,
107             final HttpContext context) throws AuthenticationException {
108         return super.authenticate(credentials, request, context);
109     }
110 
111     @Override
112     protected byte[] generateToken(final byte[] input, final String authServer) throws GSSException {
113         /* Using the SPNEGO OID is the correct method.
114          * Kerberos v5 works for IIS but not JBoss. Unwrapping
115          * the initial token when using SPNEGO OID looks like what is
116          * described here...
117          *
118          * http://msdn.microsoft.com/en-us/library/ms995330.aspx
119          *
120          * Another helpful URL...
121          *
122          * http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/tsec_SPNEGO_token.html
123          *
124          * Unfortunately SPNEGO is JRE >=1.6.
125          */
126 
127         /** Try SPNEGO by default, fall back to Kerberos later if error */
128         Oid negotiationOid  = new Oid(SPNEGO_OID);
129 
130         byte[] token = input;
131         boolean tryKerberos = false;
132         try {
133             token = generateGSSToken(token, negotiationOid, authServer);
134         } catch (GSSException ex){
135             // BAD MECH means we are likely to be using 1.5, fall back to Kerberos MECH.
136             // Rethrow any other exception.
137             if (ex.getMajor() == GSSException.BAD_MECH ){
138                 log.debug("GSSException BAD_MECH, retry with Kerberos MECH");
139                 tryKerberos = true;
140             } else {
141                 throw ex;
142             }
143 
144         }
145         if (tryKerberos){
146             /* Kerberos v5 GSS-API mechanism defined in RFC 1964.*/
147             log.debug("Using Kerberos MECH " + KERBEROS_OID);
148             negotiationOid  = new Oid(KERBEROS_OID);
149             token = generateGSSToken(token, negotiationOid, authServer);
150 
151             /*
152              * IIS accepts Kerberos and SPNEGO tokens. Some other servers Jboss, Glassfish?
153              * seem to only accept SPNEGO. Below wraps Kerberos into SPNEGO token.
154              */
155             if (token != null && spengoGenerator != null) {
156                 try {
157                     token = spengoGenerator.generateSpnegoDERObject(token);
158                 } catch (IOException ex) {
159                     log.error(ex.getMessage(), ex);
160                 }
161             }
162         }
163         return token;
164     }
165 
166     /**
167      * Returns the authentication parameter with the given name, if available.
168      *
169      * <p>There are no valid parameters for Negotiate authentication so this
170      * method always returns <tt>null</tt>.</p>
171      *
172      * @param name The name of the parameter to be returned
173      *
174      * @return the parameter with the given name
175      */
176     public String getParameter(String name) {
177         if (name == null) {
178             throw new IllegalArgumentException("Parameter name may not be null");
179         }
180         return null;
181     }
182 
183     /**
184      * The concept of an authentication realm is not supported by the Negotiate
185      * authentication scheme. Always returns <code>null</code>.
186      *
187      * @return <code>null</code>
188      */
189     public String getRealm() {
190         return null;
191     }
192 
193     /**
194      * Returns <tt>true</tt>.
195      * Negotiate authentication scheme is connection based.
196      *
197      * @return <tt>true</tt>.
198      */
199     public boolean isConnectionBased() {
200         return true;
201     }
202 
203 }