/**
   * Produces basic authorization header for the given set of {@link Credentials}.
   *
   * @param credentials The set of credentials to be used for authentication
   * @param request The request being authenticated
   * @throws org.apache.http.auth.InvalidCredentialsException if authentication credentials are not
   *     valid or not applicable for this authentication scheme
   * @throws AuthenticationException if authorization string cannot be generated due to an
   *     authentication failure
   * @return a basic authorization string
   */
  @Override
  public Header authenticate(
      final Credentials credentials, final HttpRequest request, final HttpContext context)
      throws AuthenticationException {

    Args.notNull(credentials, "Credentials");
    Args.notNull(request, "HTTP request");
    final StringBuilder tmp = new StringBuilder();
    tmp.append(credentials.getUserPrincipal().getName());
    tmp.append(":");
    tmp.append((credentials.getPassword() == null) ? "null" : credentials.getPassword());

    final Base64 base64codec = new Base64(0);
    final byte[] base64password =
        base64codec.encode(EncodingUtils.getBytes(tmp.toString(), getCredentialsCharset(request)));

    final CharArrayBuffer buffer = new CharArrayBuffer(32);
    if (isProxy()) {
      buffer.append(AUTH.PROXY_AUTH_RESP);
    } else {
      buffer.append(AUTH.WWW_AUTH_RESP);
    }
    buffer.append(": Basic ");
    buffer.append(base64password, 0, base64password.length);

    return new BufferedHeader(buffer);
  }
  /**
   * Returns a basic {@code Authorization} header value for the given {@link Credentials} and
   * charset.
   *
   * @param credentials The credentials to encode.
   * @param charset The charset to use for encoding the credentials
   * @return a basic authorization header
   * @deprecated (4.3) use {@link #authenticate(Credentials, HttpRequest, HttpContext)}.
   */
  @Deprecated
  public static Header authenticate(
      final Credentials credentials, final String charset, final boolean proxy) {
    Args.notNull(credentials, "Credentials");
    Args.notNull(charset, "charset");

    final StringBuilder tmp = new StringBuilder();
    tmp.append(credentials.getUserPrincipal().getName());
    tmp.append(":");
    tmp.append((credentials.getPassword() == null) ? "null" : credentials.getPassword());

    final byte[] base64password =
        Base64.encodeBase64(EncodingUtils.getBytes(tmp.toString(), charset), false);

    final CharArrayBuffer buffer = new CharArrayBuffer(32);
    if (proxy) {
      buffer.append(AUTH.PROXY_AUTH_RESP);
    } else {
      buffer.append(AUTH.WWW_AUTH_RESP);
    }
    buffer.append(": Basic ");
    buffer.append(base64password, 0, base64password.length);

    return new BufferedHeader(buffer);
  }
  /**
   * Returns a basic <tt>Authorization</tt> header value for the given {@link Credentials} and
   * charset.
   *
   * @param credentials The credentials to encode.
   * @param charset The charset to use for encoding the credentials
   * @return a basic authorization header
   */
  public static Header authenticate(
      final Credentials credentials, final String charset, boolean proxy) {
    if (credentials == null) {
      throw new IllegalArgumentException("Credentials may not be null");
    }
    if (charset == null) {
      throw new IllegalArgumentException("charset may not be null");
    }

    StringBuilder tmp = new StringBuilder();
    tmp.append(credentials.getUserPrincipal().getName());
    tmp.append(":");
    tmp.append((credentials.getPassword() == null) ? "null" : credentials.getPassword());

    byte[] base64password = Base64.encodeBase64(EncodingUtils.getBytes(tmp.toString(), charset));

    CharArrayBuffer buffer = new CharArrayBuffer(32);
    if (proxy) {
      buffer.append(AUTH.PROXY_AUTH_RESP);
    } else {
      buffer.append(AUTH.WWW_AUTH_RESP);
    }
    buffer.append(": Basic ");
    buffer.append(base64password, 0, base64password.length);

    return new BufferedHeader(buffer);
  }
Exemple #4
0
  /**
   * Creates digest-response header as defined in RFC2617.
   *
   * @param credentials User credentials
   * @param digest The response tag's value as String.
   * @return The digest-response as String.
   */
  private Header createDigestHeader(final Credentials credentials, final String digest)
      throws AuthenticationException {

    CharArrayBuffer buffer = new CharArrayBuffer(128);
    if (isProxy()) {
      buffer.append(AUTH.PROXY_AUTH_RESP);
    } else {
      buffer.append(AUTH.WWW_AUTH_RESP);
    }
    buffer.append(": Digest ");

    String uri = getParameter("uri");
    String realm = getParameter("realm");
    String nonce = getParameter("nonce");
    String opaque = getParameter("opaque");
    String response = digest;
    String algorithm = getParameter("algorithm");

    String uname = credentials.getUserPrincipal().getName();

    List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>(20);
    params.add(new BasicNameValuePair("username", uname));
    params.add(new BasicNameValuePair("realm", realm));
    params.add(new BasicNameValuePair("nonce", nonce));
    params.add(new BasicNameValuePair("uri", uri));
    params.add(new BasicNameValuePair("response", response));

    if (qopVariant != QOP_MISSING) {
      params.add(new BasicNameValuePair("qop", getQopVariantString()));
      params.add(new BasicNameValuePair("nc", NC));
      params.add(new BasicNameValuePair("cnonce", getCnonce()));
    }
    if (algorithm != null) {
      params.add(new BasicNameValuePair("algorithm", algorithm));
    }
    if (opaque != null) {
      params.add(new BasicNameValuePair("opaque", opaque));
    }

    for (int i = 0; i < params.size(); i++) {
      BasicNameValuePair param = params.get(i);
      if (i > 0) {
        buffer.append(", ");
      }
      boolean noQuotes = "nc".equals(param.getName()) || "qop".equals(param.getName());
      BasicHeaderValueFormatter.DEFAULT.formatNameValuePair(buffer, param, !noQuotes);
    }
    return new BufferedHeader(buffer);
  }
Exemple #5
0
  /**
   * Creates digest-response header as defined in RFC2617.
   *
   * @param credentials User credentials
   * @return The digest-response as String.
   */
  private Header createDigestHeader(final Credentials credentials) throws AuthenticationException {
    String uri = getParameter("uri");
    String realm = getParameter("realm");
    String nonce = getParameter("nonce");
    String opaque = getParameter("opaque");
    String method = getParameter("methodname");
    String algorithm = getParameter("algorithm");
    if (uri == null) {
      throw new IllegalStateException("URI may not be null");
    }
    if (realm == null) {
      throw new IllegalStateException("Realm may not be null");
    }
    if (nonce == null) {
      throw new IllegalStateException("Nonce may not be null");
    }

    // TODO: add support for QOP_INT
    int qop = QOP_UNKNOWN;
    String qoplist = getParameter("qop");
    if (qoplist != null) {
      StringTokenizer tok = new StringTokenizer(qoplist, ",");
      while (tok.hasMoreTokens()) {
        String variant = tok.nextToken().trim();
        if (variant.equals("auth")) {
          qop = QOP_AUTH;
          break;
        }
      }
    } else {
      qop = QOP_MISSING;
    }

    if (qop == QOP_UNKNOWN) {
      throw new AuthenticationException("None of the qop methods is supported: " + qoplist);
    }

    // If an algorithm is not specified, default to MD5.
    if (algorithm == null) {
      algorithm = "MD5";
    }
    // If an charset is not specified, default to ISO-8859-1.
    String charset = getParameter("charset");
    if (charset == null) {
      charset = "ISO-8859-1";
    }

    String digAlg = algorithm;
    if (digAlg.equalsIgnoreCase("MD5-sess")) {
      digAlg = "MD5";
    }

    MessageDigest digester;
    try {
      digester = createMessageDigest(digAlg);
    } catch (UnsupportedDigestAlgorithmException ex) {
      throw new AuthenticationException("Unsuppported digest algorithm: " + digAlg);
    }

    String uname = credentials.getUserPrincipal().getName();
    String pwd = credentials.getPassword();

    if (nonce.equals(this.lastNonce)) {
      nounceCount++;
    } else {
      nounceCount = 1;
      cnonce = null;
      lastNonce = nonce;
    }
    StringBuilder sb = new StringBuilder(256);
    Formatter formatter = new Formatter(sb, Locale.US);
    formatter.format("%08x", nounceCount);
    String nc = sb.toString();

    if (cnonce == null) {
      cnonce = createCnonce();
    }

    a1 = null;
    a2 = null;
    // 3.2.2.2: Calculating digest
    if (algorithm.equalsIgnoreCase("MD5-sess")) {
      // H( unq(username-value) ":" unq(realm-value) ":" passwd )
      //      ":" unq(nonce-value)
      //      ":" unq(cnonce-value)

      // calculated one per session
      sb.setLength(0);
      sb.append(uname).append(':').append(realm).append(':').append(pwd);
      String checksum = encode(digester.digest(EncodingUtils.getBytes(sb.toString(), charset)));
      sb.setLength(0);
      sb.append(checksum).append(':').append(nonce).append(':').append(cnonce);
      a1 = sb.toString();
    } else {
      // unq(username-value) ":" unq(realm-value) ":" passwd
      sb.setLength(0);
      sb.append(uname).append(':').append(realm).append(':').append(pwd);
      a1 = sb.toString();
    }

    String hasha1 = encode(digester.digest(EncodingUtils.getBytes(a1, charset)));

    if (qop == QOP_AUTH) {
      // Method ":" digest-uri-value
      a2 = method + ':' + uri;
    } else if (qop == QOP_AUTH_INT) {
      // Method ":" digest-uri-value ":" H(entity-body)
      // TODO: calculate entity hash if entity is repeatable
      throw new AuthenticationException("qop-int method is not suppported");
    } else {
      a2 = method + ':' + uri;
    }

    String hasha2 = encode(digester.digest(EncodingUtils.getBytes(a2, charset)));

    // 3.2.2.1

    String digestValue;
    if (qop == QOP_MISSING) {
      sb.setLength(0);
      sb.append(hasha1).append(':').append(nonce).append(':').append(hasha2);
      digestValue = sb.toString();
    } else {
      sb.setLength(0);
      sb.append(hasha1)
          .append(':')
          .append(nonce)
          .append(':')
          .append(nc)
          .append(':')
          .append(cnonce)
          .append(':')
          .append(qop == QOP_AUTH_INT ? "auth-int" : "auth")
          .append(':')
          .append(hasha2);
      digestValue = sb.toString();
    }

    String digest = encode(digester.digest(EncodingUtils.getAsciiBytes(digestValue)));

    CharArrayBuffer buffer = new CharArrayBuffer(128);
    if (isProxy()) {
      buffer.append(AUTH.PROXY_AUTH_RESP);
    } else {
      buffer.append(AUTH.WWW_AUTH_RESP);
    }
    buffer.append(": Digest ");

    List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>(20);
    params.add(new BasicNameValuePair("username", uname));
    params.add(new BasicNameValuePair("realm", realm));
    params.add(new BasicNameValuePair("nonce", nonce));
    params.add(new BasicNameValuePair("uri", uri));
    params.add(new BasicNameValuePair("response", digest));

    if (qop != QOP_MISSING) {
      params.add(new BasicNameValuePair("qop", qop == QOP_AUTH_INT ? "auth-int" : "auth"));
      params.add(new BasicNameValuePair("nc", nc));
      params.add(new BasicNameValuePair("cnonce", cnonce));
    }
    if (algorithm != null) {
      params.add(new BasicNameValuePair("algorithm", algorithm));
    }
    if (opaque != null) {
      params.add(new BasicNameValuePair("opaque", opaque));
    }

    for (int i = 0; i < params.size(); i++) {
      BasicNameValuePair param = params.get(i);
      if (i > 0) {
        buffer.append(", ");
      }
      boolean noQuotes = "nc".equals(param.getName()) || "qop".equals(param.getName());
      BasicHeaderValueFormatter.DEFAULT.formatNameValuePair(buffer, param, !noQuotes);
    }
    return new BufferedHeader(buffer);
  }
 public Header authenticate(Credentials paramCredentials, HttpRequest paramHttpRequest)
 {
   while (true)
   {
     NTCredentials localNTCredentials;
     String str;
     CharArrayBuffer localCharArrayBuffer;
     try
     {
       localNTCredentials = (NTCredentials)paramCredentials;
       if ((this.state == State.CHALLENGE_RECEIVED) || (this.state == State.FAILED))
       {
         str = this.engine.generateType1Msg(localNTCredentials.getDomain(), localNTCredentials.getWorkstation());
         this.state = State.MSG_TYPE1_GENERATED;
         localCharArrayBuffer = new CharArrayBuffer(32);
         if (!isProxy())
           break label222;
         localCharArrayBuffer.append("Proxy-Authorization");
         localCharArrayBuffer.append(": NTLM ");
         localCharArrayBuffer.append(str);
         return new BufferedHeader(localCharArrayBuffer);
       }
     }
     catch (ClassCastException localClassCastException)
     {
       throw new InvalidCredentialsException("Credentials cannot be used for NTLM authentication: " + paramCredentials.getClass().getName());
     }
     if (this.state == State.MSG_TYPE2_RECEVIED)
     {
       str = this.engine.generateType3Msg(localNTCredentials.getUserName(), localNTCredentials.getPassword(), localNTCredentials.getDomain(), localNTCredentials.getWorkstation(), this.challenge);
       this.state = State.MSG_TYPE3_GENERATED;
     }
     else
     {
       throw new AuthenticationException("Unexpected state: " + this.state);
       label222: localCharArrayBuffer.append("Authorization");
     }
   }
 }
Exemple #7
0
  /**
   * Creates an MD5 response digest.
   *
   * @return The created digest as string. This will be the response tag's value in the
   *     Authentication HTTP header.
   * @throws AuthenticationException when MD5 is an unsupported algorithm
   */
  private String createDigest(final Credentials credentials) throws AuthenticationException {
    // Collecting required tokens
    String uri = getParameter("uri");
    String realm = getParameter("realm");
    String nonce = getParameter("nonce");
    String method = getParameter("methodname");
    String algorithm = getParameter("algorithm");
    if (uri == null) {
      throw new IllegalStateException("URI may not be null");
    }
    if (realm == null) {
      throw new IllegalStateException("Realm may not be null");
    }
    if (nonce == null) {
      throw new IllegalStateException("Nonce may not be null");
    }
    // If an algorithm is not specified, default to MD5.
    if (algorithm == null) {
      algorithm = "MD5";
    }
    // If an charset is not specified, default to ISO-8859-1.
    String charset = getParameter("charset");
    if (charset == null) {
      charset = "ISO-8859-1";
    }

    if (qopVariant == QOP_AUTH_INT) {
      throw new AuthenticationException("Unsupported qop in HTTP Digest authentication");
    }

    MessageDigest md5Helper = createMessageDigest("MD5");

    String uname = credentials.getUserPrincipal().getName();
    String pwd = credentials.getPassword();

    // 3.2.2.2: Calculating digest
    StringBuilder tmp = new StringBuilder(uname.length() + realm.length() + pwd.length() + 2);
    tmp.append(uname);
    tmp.append(':');
    tmp.append(realm);
    tmp.append(':');
    tmp.append(pwd);
    // unq(username-value) ":" unq(realm-value) ":" passwd
    String a1 = tmp.toString();

    // a1 is suitable for MD5 algorithm
    if (algorithm.equals("MD5-sess")) {
      // H( unq(username-value) ":" unq(realm-value) ":" passwd )
      //      ":" unq(nonce-value)
      //      ":" unq(cnonce-value)

      String cnonce = getCnonce();

      String tmp2 = encode(md5Helper.digest(EncodingUtils.getBytes(a1, charset)));
      StringBuilder tmp3 = new StringBuilder(tmp2.length() + nonce.length() + cnonce.length() + 2);
      tmp3.append(tmp2);
      tmp3.append(':');
      tmp3.append(nonce);
      tmp3.append(':');
      tmp3.append(cnonce);
      a1 = tmp3.toString();
    } else if (!algorithm.equals("MD5")) {
      throw new AuthenticationException("Unhandled algorithm " + algorithm + " requested");
    }
    String md5a1 = encode(md5Helper.digest(EncodingUtils.getBytes(a1, charset)));

    String a2 = null;
    if (qopVariant == QOP_AUTH_INT) {
      // Unhandled qop auth-int
      // we do not have access to the entity-body or its hash
      // TODO: add Method ":" digest-uri-value ":" H(entity-body)
    } else {
      a2 = method + ':' + uri;
    }
    String md5a2 = encode(md5Helper.digest(EncodingUtils.getAsciiBytes(a2)));

    // 3.2.2.1
    String serverDigestValue;
    if (qopVariant == QOP_MISSING) {
      StringBuilder tmp2 = new StringBuilder(md5a1.length() + nonce.length() + md5a2.length());
      tmp2.append(md5a1);
      tmp2.append(':');
      tmp2.append(nonce);
      tmp2.append(':');
      tmp2.append(md5a2);
      serverDigestValue = tmp2.toString();
    } else {
      String qopOption = getQopVariantString();
      String cnonce = getCnonce();

      StringBuilder tmp2 =
          new StringBuilder(
              md5a1.length()
                  + nonce.length()
                  + NC.length()
                  + cnonce.length()
                  + qopOption.length()
                  + md5a2.length()
                  + 5);
      tmp2.append(md5a1);
      tmp2.append(':');
      tmp2.append(nonce);
      tmp2.append(':');
      tmp2.append(NC);
      tmp2.append(':');
      tmp2.append(cnonce);
      tmp2.append(':');
      tmp2.append(qopOption);
      tmp2.append(':');
      tmp2.append(md5a2);
      serverDigestValue = tmp2.toString();
    }

    String serverDigest = encode(md5Helper.digest(EncodingUtils.getAsciiBytes(serverDigestValue)));

    return serverDigest;
  }