As a protocol, secure basic authentication is identical to basic authentication as described in RFC 7617. The differences are in how passwords are created and compared, and in how realms are named. Generally, a secure-basic-authentication password is a URL-safe, base 64 encoding of a sequence of bytes. The first four bytes is a time stamp of a 32 bit two's complement integer, stored in little-endian byte order, providing the time at which the password was created as the number of seconds since 1970-01-01T00:00:00Z. The next four bytes is a 32-bit CRC of the first 4 bytes of the sequence followed by the password as an array of bytes using the UTF-8 character encoding. The remainder of the sequence is either
- a SHA-256 message digest of (1) the first eight bytes of the sequence and (2) a password using the UTF-8 character encoding.
- a digital signature of (1) the first eight bytes of the sequence and (2) a password using the UTF-8 character encoding.
- a digital signature of (1) the first eight bytes of the sequence, (2) the DER encoding of the public key provided in an SSL certificate, and (3) a password using the UTF-8 character encoding.
- [D]. This corresponds to Case 1 above.
- [S]. This corresponds to Case 2 above.
- [SC]. This corresponds to Case 3 above.
NOTE: For compatibility with openssl, one should use the keytool
program, or
SecureBasicUtilities.createPEMPair(File,String,String,String,String,char[]),
to generate a key pair as a PKCS #12 file will then be created.
The openssl equivalent to
iskeytool -genkey -keyalg EC -groupname secp256r1 \ -sigalg SHA256withECDSA -dname CN=nobody@nowhere.com \ -alias key -keypass password -storepass password \ -keystore ecstore.pfx
although the choice of a signature algorithm (used to self sign) may be different. To add to the confusion, for the elliptic curve used in this example, keytool prefers the name secp256r1 whereas openssl prefers prime256v1. When openssl is given the name secp256r1, it will indicate that is is using prime256v1, whereas when keytool is given the name prime256v1, it generates an error message. Also keytool must use the same password for the file as for each entry it stores if the file is to be compatible with openssl.openssl ecparam -name prime256v1 -genkey -noout -out eckey.pem openssl req -new -x509 -key eckey.pem -out eccert.pem -days 360 openssl pkcs12 -export -inkey eckey.pem -in eccert.pem \ -name key -out ecstore.pfx
- See Also:
-
Nested Class Summary
Nested ClassesNested classes/interfaces inherited from class org.bzdev.ejws.EjwsAuthenticator
EjwsAuthenticator.AddStatus, EjwsAuthenticator.BiConsumer1, EjwsAuthenticator.BiConsumer2, EjwsAuthenticator.GPGKeyIDs, EjwsAuthenticator.UserInfoNested classes/interfaces inherited from class com.sun.net.httpserver.Authenticator
Authenticator.Failure, Authenticator.Result, Authenticator.Retry, Authenticator.Success -
Field Summary
Fields inherited from class org.bzdev.ejws.EjwsAuthenticator
authFunction, loginFunction, logoutFunction, onAccountActive, onAccountPending, onAccountRemoval, onAccountRequest, tracerFields inherited from class com.sun.net.httpserver.BasicAuthenticator
realm -
Constructor Summary
ConstructorsConstructorDescriptionEjwsSecureBasicAuth(EmbeddedWebServer ews, String realm) Constructor forSecureBasicUtilities.Mode.DIGESTmode.EjwsSecureBasicAuth(EmbeddedWebServer ews, String realm, Map<String, EjwsSecureBasicAuth.Entry> map) Constructor forSecureBasicUtilities.Mode.DIGESTmode, specifying a map.EjwsSecureBasicAuth(EmbeddedWebServer ews, String realm, SecureBasicUtilities.Mode mode) Constructor forSecureBasicUtilities.Mode.SIGNATURE_WITHOUT_CERTmode andSecureBasicUtilities.Mode.SIGNATURE_WITH_CERTmode given multiple certificates.EjwsSecureBasicAuth(EmbeddedWebServer ews, String realm, SecureBasicUtilities.Mode mode, Map<String, EjwsSecureBasicAuth.Entry> map) Constructor forSecureBasicUtilities.Mode.SIGNATURE_WITHOUT_CERTmode andSecureBasicUtilities.Mode.SIGNATURE_WITH_CERTmode given multiple certificates, specifying a map. -
Method Summary
Modifier and TypeMethodDescriptionvoidAdd a user name and password for this authenticator's HTTP realm.voidAdd a user name, the user's password, the user's public key, and the user's signature algorithm for this authenticator's HTTP realm.voidAdd a user name, the user's password, the user's public key, the user's signature algorithm and the user's roles for this authenticator's HTTP realm.voidAdd a user name, the user's password and the user's roles for this authenticator's HTTP realm.voidAdd a user specified by an instance ofEjwsAuthenticator.UserInfo.Authenticate an HTTP request.booleancheckCredentials(String username, String password) Check credentials.protected Map<String,? extends EjwsAuthenticator.Entry> Get the authentication map association user names with authentication data..Get the default certificate chain.getMode()Get the mode.static SecureBasicUtilities.ModegetMode(Certificate[][] certs) Get theSecureBasicUtilities.Modeappropriate the use of digital signatures.byte[]Get the SBL file for a usergetUsers()Get the names of all users known to this authenticator.getUsers(boolean active) Get selected users known to this authenticator.Get this authenticator's user tablevoidhandleError(HttpExchange t, Exception e) Handle exceptions by sending an error responsebooleanDetermine if a user is currently active.booleanisSBLCompressed(String user) Determine if the SBL file is compresssed using GZIP.Load user-account data obtained from GPG or an SBL directorybooleanmakeUserActive(String name) Make a user active.booleanmakeUserActive(String name, boolean gpg) Make a user active, specifying if the user is one for whom GPG is used to provide the data needed to log in.protected booleanmakeUserActiveInMap(String name) Make a user active, modifying only the authenticator's map.booleanmakeUserPending(String name) Make a user pendijng.booleanmakeUserPending(String name, boolean gpg) Make a user pending, specifying if the user is one for whom GPG is used to provide the data needed to log in.protected booleanmakeUserPendingInMap(String name) Make a user pending, modifying only the authenticator's map.voidprune()Remove cached passwords whose timeout has expired.voidremovePWInfo(String username) Remove an entry from the password map.booleanremoveUser(String name) Remove a user.booleanremoveUser(String name, boolean gpg) Remove a user.protected booleanremoveUserFromMap(String name) Remove a user, modifying only the authenticator's map.setCertificateChain(InputStream ksis, char[] password, String alias) Set a default certificate chain given a keystore and alias.setCertificateChain(URI proxy) Set a default certificate chain by using a proxy's certificate chain.setCertificateChain(Certificate[] chain) Set a default certificate chain.setTimeLimits(int lowerTimeDiffLimit, int upperTimeDiffLimit, int passphraseTimeout) Set time-offset limits.Set this authenticator's user table.Methods inherited from class org.bzdev.ejws.EjwsAuthenticator
addToAdminMap, addToDeleteSet, closeSBLStore, createAuthCode, createAuthCookie, createServerCookie, createUser, createUser, createUser, createUser, createUser, deleteWithFingerprint, findAuthServerCookie, findServerCookie, generateAdminURI, generateRequestURI, getActiveGPGUsers, getAdminFingerprint, getAdminUsers, getAuthCode, getCanAddAccount, getFingerprint, getGPGUsers, getLoginAlias, getLoginPath, getPendingGPGUsers, getReverseProxy, getSBLStore, getSBLUsers, getTrustedKeyIDs, getUserNameFromSBL, getUsersExcept, getUserStatus, gpghome, hasGPGKey, inDeleteSet, isActiveDefault, isEmailAddress, isTrustedKey, processAdminRequests, readSBLData, removeFromDeleteSet, requestFromUser, setAllowLoopback, setAuthorizedFunction, setCanAddAccount, setCookie, setDefaultActive, setGPGHome, setLoginFunction, setLogoutFunction, setOnAccountActive, setOnAccountPending, setOnAccountRemoval, setOnAccountRequest, setReverseProxy, setSBLStore, setSBLStore, setSelfSigned, setThisObject, setTracer, setTruststore, setTruststorePW, setupKeySigner, setUserStatusFunction, showGPGKey, signKey, signKey, storeGPGKey, storeSBLData, trustGPGKey, validGPGUserMethods inherited from class com.sun.net.httpserver.BasicAuthenticator
getRealm
-
Constructor Details
-
EjwsSecureBasicAuth
Constructor forSecureBasicUtilities.Mode.DIGESTmode.- Parameters:
ews- theEmbeddedWebServerto which this authenticator will be addedrealm- the HTTP realm
-
EjwsSecureBasicAuth
public EjwsSecureBasicAuth(EmbeddedWebServer ews, String realm, Map<String, EjwsSecureBasicAuth.Entry> map) Constructor forSecureBasicUtilities.Mode.DIGESTmode, specifying a map.A user-supplied map can be implemented so as to allow one to obtain passwords and roles from a database or some other form of persistent storage. If entries can be added while a server using this authenticator is running, the map should have a thread-safe implementation.
- Parameters:
realm- the HTTP realmmap- a map associating user names with entries containing a password, roles, and optionally a public key and related data
-
EjwsSecureBasicAuth
Constructor forSecureBasicUtilities.Mode.SIGNATURE_WITHOUT_CERTmode andSecureBasicUtilities.Mode.SIGNATURE_WITH_CERTmode given multiple certificates.If the second argument is null or does not contain any certificates, the mode is
SecureBasicUtilities.Mode.SIGNATURE_WITHOUT_CERT; otherwise the mode isSecureBasicUtilities.Mode.SIGNATURE_WITH_CERT- Parameters:
mode-PASSWORD,DIGEST,SIGNATURE_WITH_CERT,SIGNATURE_WITHOUT_CERTrealm- the HTTP realm
-
EjwsSecureBasicAuth
public EjwsSecureBasicAuth(EmbeddedWebServer ews, String realm, SecureBasicUtilities.Mode mode, Map<String, EjwsSecureBasicAuth.Entry> map) Constructor forSecureBasicUtilities.Mode.SIGNATURE_WITHOUT_CERTmode andSecureBasicUtilities.Mode.SIGNATURE_WITH_CERTmode given multiple certificates, specifying a map.If the second argument is null or does not contain any certificates, the mode is
SecureBasicUtilities.Mode.SIGNATURE_WITHOUT_CERT; otherwise the mode isSecureBasicUtilities.Mode.SIGNATURE_WITH_CERTA user-supplied map can be implemented so as to allow one to obtain passwords and roles from a database or some other form of persistent storage. If entries can be added while a server using this authenticator is running, the map should have a thread-safe implementation.
- Parameters:
realm- the HTTP realmmode-PASSWORD,DIGEST,SIGNATURE_WITH_CERT,SIGNATURE_WITHOUT_CERTmap- a map associating user names with entries containing a password, roles, and optionally a public key and related data
-
-
Method Details
-
getAuthMap
Get the authentication map association user names with authentication data..- Specified by:
getAuthMapin classEjwsAuthenticator<EjwsSecureBasicAuth>- Returns:
- the map
-
getUsers
Get the names of all users known to this authenticator. The value returned is an unmodifiable set.- Specified by:
getUsersin classEjwsAuthenticator<EjwsSecureBasicAuth>- Returns:
- the users
-
getUsers
Get selected users known to this authenticator.- Specified by:
getUsersin classEjwsAuthenticator<EjwsSecureBasicAuth>- Parameters:
active- true if the users are active; false if they are not active
-
isActive
Determine if a user is currently active. The authenticator's internal tables are tested, not values in persistent storage.- Specified by:
isActivein classEjwsAuthenticator<EjwsSecureBasicAuth>- Returns:
- true if the user exists and is active; false otherwise
-
getSBL
Get the SBL file for a user- Specified by:
getSBLin classEjwsAuthenticator<EjwsSecureBasicAuth>- Parameters:
user- the user- Returns:
- the SBL file as a byte array; null if there is none
-
isSBLCompressed
Determine if the SBL file is compresssed using GZIP.- Specified by:
isSBLCompressedin classEjwsAuthenticator<EjwsSecureBasicAuth>- Returns:
- true if the SBL file is compressed; false otherwise
- See Also:
-
getMode
Get the mode.- Specified by:
getModein classEjwsAuthenticator<EjwsSecureBasicAuth>- Returns:
- the mode
-
setTimeLimits
public EjwsSecureBasicAuth setTimeLimits(int lowerTimeDiffLimit, int upperTimeDiffLimit, int passphraseTimeout) throws IllegalArgumentException Set time-offset limits. For the modesSecureBasicUtilities.Mode.DIGEST,SecureBasicUtilities.Mode.SIGNATURE_WITH_CERT, andSecureBasicUtilities.Mode.SIGNATURE_WITHOUT_CERT, each password that is generated contains a time stamp in units of seconds. The time difference is the difference between the current time and the time stamp associated with a password.The first argument will generally be negative to handle the case in which the clock for the client generating the password is ahead of the server's clock. The second argument will generally be positive to handle the case in which the client's clock is behind the server's clock and to additionally account for propagation delay and to limit the number of times a password has to be recomputed. To allow for software that does not implement secure basic authentication, the value should be above the expected maximum length of a user's session.
- Parameters:
lowerTimeDiffLimit- the lower limit for the time difference in seconds (the default is -10 seconds).upperTimeDiffLimit- the upper limit for the time difference in seconds (the default is 150 seconds)passphraseTimeout- the time interval in seconds for which a password is valid (the default is 1200); 0 to disable this timeout- Returns:
- this authenticator
- Throws:
IllegalArgumentException- if the first argument is larger than zero, if the second argument is less than zero, or if the third argument, when not zero, is less than the second argument
-
getMode
public static SecureBasicUtilities.Mode getMode(Certificate[][] certs) throws IllegalArgumentException Get theSecureBasicUtilities.Modeappropriate the use of digital signatures.- Parameters:
certs- a certificate chain; null or an array of length 0 if there are no certificates- Returns:
- SecureBasicUtilities.Mode.SIGNATURE_WITHOUT_CERT if the argument is null or an array of length 0; SecureBasicUtilities.Mode.SIGNATURE_WITH_CERT otherwise
- Throws:
IllegalArgumentException- if one certificate chain's length is zero and another's length is not zero
-
setCertificateChain
Set a default certificate chain. This method allows passwords to be checked or generated when a reverse proxy provides SSL encryption. When HTTPS is used and this method is called with a non-null argument, that certificate chain will override the certificate provided by an SSL connection.- Parameters:
chain- the certificate chain- Returns:
- this authenticator
-
setCertificateChain
public EjwsSecureBasicAuth setCertificateChain(InputStream ksis, char[] password, String alias) throws KeyStoreException, IOException, CertificateException Set a default certificate chain given a keystore and alias. This method allows passwords to be checked or generated when a reverse proxy provides SSL encryption. When HTTPS is used and this method is called with a non-null argument, that certificate chain will override the certificate provided by an SSL connection.- Parameters:
ksis- the input stream used to read a Java key storepassword- the store password for the keystorealias- the alias used to find the certificate chain- Returns:
- this authenticator
- Throws:
KeyStoreException- if a keystore exception occurredIOException- if an IO error occurred while reading the input streamCertificateException- if a certificate chain could not be created- See Also:
-
setCertificateChain
public EjwsSecureBasicAuth setCertificateChain(URI proxy) throws CertificateException, IllegalArgumentException Set a default certificate chain by using a proxy's certificate chain. This method allows passwords to be checked or generated when a reverse proxy provides SSL encryption. When HTTPS is used and this method is called with a non-null argument, that certificate chain will override the certificate provided by an SSL connection. In addition, when a reverse proxy is configured, the ".base" field in an SBL file provided by the server will be a URI whose host name and port matches that of the reverse proxy and whose path starts with the reverse proxy's path.Note: the current implementation assumes that the proxy's certificate can be obtained by opening a TCP connection the proxy itself based on its host and port. In addition, the certificate must be available before the server used by this authenticator has started.
If there is an error, the certificate chain will be set to null;
- Parameters:
proxy- the URI of the proxy- Returns:
- this authenticator
- Throws:
CertificateException- if the certificate chain could not be computed or obtainedIllegalArgumentException- if an argument was incorrect
-
getDefaultCertChain
Get the default certificate chain.This method is provided mainly for debugging.
- Returns:
- the default certificate chain; null if there is none
-
add
public void add(String username, String password) throws UnsupportedOperationException, IllegalStateException Add a user name and password for this authenticator's HTTP realm. The new entry will use password authentication.- Parameters:
username- the user namepassword- the password- Throws:
UnsupportedOperationException- if the map does not allow entries to be added (the default map does not throw this exception)IllegalStateException- if the mode is not appropriate or if the user has already been added
-
add
public void add(String username, String password, Set<String> roles) throws UnsupportedOperationException, IllegalStateException Add a user name, the user's password and the user's roles for this authenticator's HTTP realm. The new entry will use password authentication.- Parameters:
username- the user namepassword- the user's passwordroles- the user's roles- Throws:
UnsupportedOperationException- if the map does not allow entries to be added (the default map does not throw this exception)IllegalStateException- if the mode is not appropriate or if the user has already been added
-
add
Add a user name, the user's password, the user's public key, and the user's signature algorithm for this authenticator's HTTP realm. If the argument pem is not null, the type of authentication used is determined by the default authentication mode configured for this authenticator.- Parameters:
username- the user namepem- A PEM file providing the signature algorithm and the user's certificate or public key; null for secure-basic digest authenticationpassword- the user's password- Throws:
UnsupportedOperationException- if the map does not allow entries to be added (the default map does not throw this exception)IllegalStateException- if the mode is not appropriate or if the user has already been added
-
add
public void add(String username, String pem, String password, Set<String> roles) throws UnsupportedOperationException Add a user name, the user's password, the user's public key, the user's signature algorithm and the user's roles for this authenticator's HTTP realm. If the argument pem is not null, the type of authentication used is determined by the default authentication mode configured for this authenticator.- Parameters:
username- the user namepem- A PEM file providing the signature algorithm and the user's certificate or public key; null for secure-basic digest authenticationpassword- the user's passwordroles- the user's roles- Throws:
UnsupportedOperationException- if the map does not allow entries to be added (the default map does not throw this exception)IllegalStateException- if the mode is not appropriate or if the user has already been added
-
removeUser
Remove a user.- Specified by:
removeUserin classEjwsAuthenticator<EjwsSecureBasicAuth>- Parameters:
name- the user namegpg- true to delete GPG permanent entries; false for SBL permanent entries
-
removeUser
Remove a user.- Specified by:
removeUserin classEjwsAuthenticator<EjwsSecureBasicAuth>- Parameters:
name- the name of the user
-
makeUserActive
Make a user active, specifying if the user is one for whom GPG is used to provide the data needed to log in.- Specified by:
makeUserActivein classEjwsAuthenticator<EjwsSecureBasicAuth>- Parameters:
name- the user's namegpg- true if GPG is used; false if an SBL directory is used
-
makeUserPending
Make a user pending, specifying if the user is one for whom GPG is used to provide the data needed to log in.- Specified by:
makeUserPendingin classEjwsAuthenticator<EjwsSecureBasicAuth>- Parameters:
name- the user's namegpg- true if GPG is used; false if an SBL directory is used
-
makeUserActiveInMap
Make a user active, modifying only the authenticator's map.- Specified by:
makeUserActiveInMapin classEjwsAuthenticator<EjwsSecureBasicAuth>- Parameters:
name- the user name- Returns:
- true on success; false if there is no such user
-
makeUserPendingInMap
Make a user pending, modifying only the authenticator's map.- Specified by:
makeUserPendingInMapin classEjwsAuthenticator<EjwsSecureBasicAuth>- Parameters:
name- the user name- Returns:
- true on success; false if there is no such user
-
removeUserFromMap
Remove a user, modifying only the authenticator's map.- Specified by:
removeUserFromMapin classEjwsAuthenticator<EjwsSecureBasicAuth>- Parameters:
name- the user name- Returns:
- true on success; false if there is no such user
-
makeUserActive
Make a user active.- Specified by:
makeUserActivein classEjwsAuthenticator<EjwsSecureBasicAuth>- Parameters:
name- the user's name
-
makeUserPending
Make a user pendijng.- Specified by:
makeUserPendingin classEjwsAuthenticator<EjwsSecureBasicAuth>- Parameters:
name- the user's name
-
loadFromDirs
Load user-account data obtained from GPG or an SBL directory- Overrides:
loadFromDirsin classEjwsAuthenticator<EjwsSecureBasicAuth>- Returns:
- this object
- Throws:
UnsupportedOperationException- See Also:
-
setUserTable
public EjwsSecureBasicAuth setUserTable(EjwsUserTable<EjwsSecureBasicAuth, EjwsSecureBasicAuth.Entry> utable) Set this authenticator's user table.- Parameters:
utable- the user table- Returns:
- this authenticator
-
getUserTable
Get this authenticator's user table- Specified by:
getUserTablein classEjwsAuthenticator<EjwsSecureBasicAuth>- Returns:
- the user table.
-
add
Add a user specified by an instance ofEjwsAuthenticator.UserInfo.- Specified by:
addin classEjwsAuthenticator<EjwsSecureBasicAuth>- Parameters:
info- the user data- Throws:
IllegalStateException
-
handleError
Handle exceptions by sending an error response- Parameters:
t- theHttpExchangebeing processede- an exception that is being handled- Throws:
IOException
-
authenticate
Authenticate an HTTP request.- Overrides:
authenticatein classBasicAuthenticator- Parameters:
t- the HTTP exchange object- Returns:
- the authentication result
- See Also:
-
removePWInfo
Remove an entry from the password map. This is called when logging out.- Overrides:
removePWInfoin classEjwsAuthenticator<EjwsSecureBasicAuth>- Parameters:
username- the user name
-
prune
public void prune()Remove cached passwords whose timeout has expired. The method can be called periodically to eliminate passwords when a user has not explicitly logged out and has not sent any HTTP requests for some time. -
checkCredentials
Check credentials. This method is called for each incoming request to verify the given name and password in the context of this Authenticator's realm.- Specified by:
checkCredentialsin classBasicAuthenticator- Parameters:
username- the user namepassword- the password- Returns:
- true if credentials are valid; false otherwise
-