Class ScramScheme
- java.lang.Object
-
- org.apache.hc.client5.http.impl.auth.ScramScheme
-
- All Implemented Interfaces:
AuthScheme
@Contract(threading=UNSAFE) @Experimental public final class ScramScheme extends java.lang.Object implements AuthScheme
Strict HTTP SCRAM client implementingSCRAM-SHA-256per RFC 7804 with SCRAM core per RFC 5802/7677.HTTP SCRAM uses no channel binding (GS2 header
"n,,";c=biws).Experimental: This API is work in progress and may change without notice in a future release.
- Since:
- 5.6
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static classScramScheme.SimplePrincipalprivate static classScramScheme.State
-
Field Summary
Fields Modifier and Type Field Description private static java.util.Base64.EncoderB64private static java.util.Base64.DecoderB64Dprivate static java.lang.StringC_BIND_B64private java.lang.StringclientFirstBareprivate java.lang.StringclientNonceprivate booleancompleteprivate static intDEFAULT_MAX_ITERATIONS_ALLOWEDprivate static intDEFAULT_WARN_MIN_ITERATIONSprivate byte[]expectedVprivate static java.lang.StringGS2_HEADERprivate intiterationsprivate static org.slf4j.LoggerLOGprivate intmaxIterationsAllowedprivate intminIterationsRequiredprivate char[]passwordprivate java.security.Principalprincipalprivate java.lang.Stringrealmprivate byte[]saltprivate java.security.SecureRandomsecureRandomprivate java.lang.StringserverFirstRawprivate java.lang.StringserverNonceprivate java.lang.Stringsidprivate ScramScheme.Statestateprivate java.lang.Stringusernameprivate intwarnMinIterations
-
Constructor Summary
Constructors Constructor Description ScramScheme()Default policy: warn ifi < 4096, no hard enforcement; SHA-256 only.ScramScheme(int warnMinIterations, int minIterationsRequired, int maxIterationsAllowed, java.security.SecureRandom rnd)Constructor with custom iteration policy.ScramScheme(int warnMinIterations, int minIterationsRequired, java.security.SecureRandom rnd)Constructor with custom iteration policy.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description private static java.lang.Stringb64ToString(java.lang.String b64)private java.lang.StringbuildClientFinalAndExpectV()private java.lang.StringbuildClientFirst()private static java.lang.StringescapeUser(java.lang.String user)java.lang.StringgenerateAuthResponse(org.apache.hc.core5.http.HttpHost host, org.apache.hc.core5.http.HttpRequest request, org.apache.hc.core5.http.protocol.HttpContext context)Generates an authorization response based on the current state.private java.lang.StringgenNonce()java.lang.StringgetName()Returns textual designation of the scheme.java.security.PrincipalgetPrincipal()ReturnsPrincipalwhose credentials are used.java.lang.StringgetRealm()Returns authentication realm.private static byte[]hiPBKDF2(char[] password, byte[] salt, int iterations, int dkLen)private static byte[]hmac(byte[] key, java.lang.String msg)booleanisChallengeComplete()Authentication process may involve a series of challenge-response exchanges.booleanisChallengeExpected()SCRAM must inspect final responses to verifyv=inAuthentication-Info.booleanisConnectionBased()SCRAM is per-request (no connection binding).booleanisResponseReady(org.apache.hc.core5.http.HttpHost host, CredentialsProvider credentialsProvider, org.apache.hc.core5.http.protocol.HttpContext context)Allow response when: - INIT (preemptive client-first) — only if creds have been prepared - ANNOUNCED (401 without data) - SERVER_FIRST_RCVD (ready to send client-final)private static java.util.Map<java.lang.String,java.lang.String>parseAttrs(java.lang.String s)voidprocessChallenge(AuthChallenge authChallenge, org.apache.hc.core5.http.protocol.HttpContext context)Legacy entry point: wrapsAuthenticationExceptionasMalformedChallengeException.voidprocessChallenge(org.apache.hc.core5.http.HttpHost host, boolean challenged, AuthChallenge authChallenge, org.apache.hc.core5.http.protocol.HttpContext context)Handles 401 challenges (with/withoutdata) and final responses carryingAuthentication-Info(any status code).private static java.lang.StringquoteParam(java.lang.String v)private static byte[]sha256(byte[] in)private static java.lang.StringstringToB64(java.lang.String s)private static java.util.Map<java.lang.String,java.lang.String>toParamMap(java.util.List<org.apache.hc.core5.http.NameValuePair> pairs)private static byte[]xor(byte[] a, byte[] b)private static voidzero(byte[] a)private voidzeroAndClearExpectedV()
-
-
-
Field Detail
-
LOG
private static final org.slf4j.Logger LOG
-
DEFAULT_WARN_MIN_ITERATIONS
private static final int DEFAULT_WARN_MIN_ITERATIONS
- See Also:
- Constant Field Values
-
DEFAULT_MAX_ITERATIONS_ALLOWED
private static final int DEFAULT_MAX_ITERATIONS_ALLOWED
- See Also:
- Constant Field Values
-
GS2_HEADER
private static final java.lang.String GS2_HEADER
- See Also:
- Constant Field Values
-
C_BIND_B64
private static final java.lang.String C_BIND_B64
- See Also:
- Constant Field Values
-
B64
private static final java.util.Base64.Encoder B64
-
B64D
private static final java.util.Base64.Decoder B64D
-
secureRandom
private final java.security.SecureRandom secureRandom
-
warnMinIterations
private final int warnMinIterations
-
minIterationsRequired
private final int minIterationsRequired
-
maxIterationsAllowed
private final int maxIterationsAllowed
-
state
private ScramScheme.State state
-
complete
private boolean complete
-
realm
private java.lang.String realm
-
sid
private java.lang.String sid
-
username
private java.lang.String username
-
password
private char[] password
-
principal
private java.security.Principal principal
-
clientNonce
private java.lang.String clientNonce
-
clientFirstBare
private java.lang.String clientFirstBare
-
serverFirstRaw
private java.lang.String serverFirstRaw
-
serverNonce
private java.lang.String serverNonce
-
salt
private byte[] salt
-
iterations
private int iterations
-
expectedV
private byte[] expectedV
-
-
Constructor Detail
-
ScramScheme
public ScramScheme()
Default policy: warn ifi < 4096, no hard enforcement; SHA-256 only.- Since:
- 5.6
-
ScramScheme
public ScramScheme(int warnMinIterations, int minIterationsRequired, java.security.SecureRandom rnd)Constructor with custom iteration policy.- Parameters:
warnMinIterations- warn if iteration count is lower than this (0 disables warnings)minIterationsRequired- fail if iteration count is lower than this (0 disables enforcement)rnd- optional secure random source (null uses system default)- Since:
- 5.6
-
ScramScheme
public ScramScheme(int warnMinIterations, int minIterationsRequired, int maxIterationsAllowed, java.security.SecureRandom rnd)Constructor with custom iteration policy.- Parameters:
warnMinIterations- warn if iteration count is lower than this (0 disables warnings)minIterationsRequired- fail if iteration count is lower than this (0 disables enforcement)maxIterationsAllowed- fail if iteration count is greater than this (must be positive)rnd- optional secure random source (null uses system default)- Since:
- 5.6
-
-
Method Detail
-
getName
public java.lang.String getName()
Returns textual designation of the scheme.- Specified by:
getNamein interfaceAuthScheme- Returns:
- the name of the given authentication scheme
- Since:
- 5.6
-
isConnectionBased
public boolean isConnectionBased()
SCRAM is per-request (no connection binding).- Specified by:
isConnectionBasedin interfaceAuthScheme- Returns:
trueif the scheme is connection based,falseif the scheme is request based.- Since:
- 5.6
-
isChallengeExpected
public boolean isChallengeExpected()
SCRAM must inspect final responses to verifyv=inAuthentication-Info.- Specified by:
isChallengeExpectedin interfaceAuthScheme- Returns:
- true if responses with non 401/407 response codes must be processed by the scheme.
- Since:
- 5.6
-
processChallenge
public void processChallenge(AuthChallenge authChallenge, org.apache.hc.core5.http.protocol.HttpContext context) throws MalformedChallengeException
Legacy entry point: wrapsAuthenticationExceptionasMalformedChallengeException.- Specified by:
processChallengein interfaceAuthScheme- Parameters:
authChallenge- the auth challengecontext- HTTP context- Throws:
MalformedChallengeException- in case the auth challenge is incomplete, malformed or otherwise invalid.- Since:
- 5.6
- See Also:
AuthScheme.processChallenge(HttpHost, boolean, AuthChallenge, HttpContext)
-
processChallenge
public void processChallenge(org.apache.hc.core5.http.HttpHost host, boolean challenged, AuthChallenge authChallenge, org.apache.hc.core5.http.protocol.HttpContext context) throws MalformedChallengeException, AuthenticationExceptionHandles 401 challenges (with/withoutdata) and final responses carryingAuthentication-Info(any status code).- Specified by:
processChallengein interfaceAuthScheme- Parameters:
host- HTTP hostchallenged- true if the response was unauthorised (401/407)authChallenge- the auth challenge or null if no challenge was receivedcontext- HTTP context- Throws:
MalformedChallengeException- in case the auth challenge is incomplete,AuthenticationException- in case the authentication process is unsuccessful.- Since:
- 5.6
-
isChallengeComplete
public boolean isChallengeComplete()
Description copied from interface:AuthSchemeAuthentication process may involve a series of challenge-response exchanges. This method tests if the authorization process has been fully completed (either successfully or unsuccessfully), that is, all the required authorization challenges have been processed in their entirety.Please note if the scheme returns
truefrom this method in response to a challenge, it effectively implies a failure to respond to this challenge and termination of the authentication process.- Specified by:
isChallengeCompletein interfaceAuthScheme- Returns:
trueif the authentication process has been completed,falseotherwise.- Since:
- 5.6
-
getRealm
public java.lang.String getRealm()
Description copied from interface:AuthSchemeReturns authentication realm. If the concept of an authentication realm is not applicable to the given authentication scheme, returnsnull.- Specified by:
getRealmin interfaceAuthScheme- Returns:
- the authentication realm
- Since:
- 5.6
-
isResponseReady
public boolean isResponseReady(org.apache.hc.core5.http.HttpHost host, CredentialsProvider credentialsProvider, org.apache.hc.core5.http.protocol.HttpContext context) throws AuthenticationExceptionAllow response when: - INIT (preemptive client-first) — only if creds have been prepared - ANNOUNCED (401 without data) - SERVER_FIRST_RCVD (ready to send client-final)- Specified by:
isResponseReadyin interfaceAuthSchemecredentialsProvider- The credentials to be used for authenticationcontext- HTTP context- Returns:
trueif an authorization response can be generated and the authentication handshake can proceed,falseotherwise.- Throws:
AuthenticationException- if authorization string cannot be generated due to an authentication failure- Since:
- 5.6
-
generateAuthResponse
public java.lang.String generateAuthResponse(org.apache.hc.core5.http.HttpHost host, org.apache.hc.core5.http.HttpRequest request, org.apache.hc.core5.http.protocol.HttpContext context) throws AuthenticationExceptionDescription copied from interface:AuthSchemeGenerates an authorization response based on the current state. Some authentication schemes may need to load user credentials required to generate an authorization response from aCredentialsProviderprior to this method call.- Specified by:
generateAuthResponsein interfaceAuthSchemerequest- The request being authenticatedcontext- HTTP context- Returns:
- authorization header
- Throws:
AuthenticationException- if authorization string cannot be generated due to an authentication failure- Since:
- 5.6
- See Also:
AuthScheme.isResponseReady(HttpHost, CredentialsProvider, HttpContext)
-
getPrincipal
public java.security.Principal getPrincipal()
ReturnsPrincipalwhose credentials are used.- Specified by:
getPrincipalin interfaceAuthScheme- Returns:
- user principal
- Since:
- 5.6
- See Also:
AuthScheme.isConnectionBased()
-
buildClientFirst
private java.lang.String buildClientFirst()
-
buildClientFinalAndExpectV
private java.lang.String buildClientFinalAndExpectV() throws AuthenticationException- Throws:
AuthenticationException
-
zero
private static void zero(byte[] a)
-
zeroAndClearExpectedV
private void zeroAndClearExpectedV()
-
toParamMap
private static java.util.Map<java.lang.String,java.lang.String> toParamMap(java.util.List<org.apache.hc.core5.http.NameValuePair> pairs)
-
parseAttrs
private static java.util.Map<java.lang.String,java.lang.String> parseAttrs(java.lang.String s) throws MalformedChallengeException- Throws:
MalformedChallengeException
-
genNonce
private java.lang.String genNonce()
-
escapeUser
private static java.lang.String escapeUser(java.lang.String user)
-
quoteParam
private static java.lang.String quoteParam(java.lang.String v)
-
hiPBKDF2
private static byte[] hiPBKDF2(char[] password, byte[] salt, int iterations, int dkLen) throws java.security.GeneralSecurityException- Throws:
java.security.GeneralSecurityException
-
hmac
private static byte[] hmac(byte[] key, java.lang.String msg) throws java.security.GeneralSecurityException- Throws:
java.security.GeneralSecurityException
-
sha256
private static byte[] sha256(byte[] in) throws java.security.GeneralSecurityException- Throws:
java.security.GeneralSecurityException
-
xor
private static byte[] xor(byte[] a, byte[] b)
-
stringToB64
private static java.lang.String stringToB64(java.lang.String s)
-
b64ToString
private static java.lang.String b64ToString(java.lang.String b64) throws MalformedChallengeException- Throws:
MalformedChallengeException
-
-