public class ClientSecurity
extends java.lang.Object
The MapR challenge-response handshake follows the RFC 7235/2616 standard. A brief description of the handshake is given here. More information can be found in https://tools.ietf.org/html/rfc7235#section-4.1 and RFC 2616 - Hypertext Transfer Protocol. See https://tools.ietf.org/html/rfc2616#page-107. If the server receives a request for an access-protected object, and if an acceptable "Authorization" header has not been sent, the server responds with a "401 Unauthorized" status code, and a "WWW- Authenticate:" header as per the framework described in [RFC2616]. For MapR ticket authentication, the value of WWW-Authenticate include MAPR-Negotiate. For example:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: MAPR-Negotiate
If the client application receives a "401 Unauthorized" response for a REST API
request, it should parse the header to see if it contains the WWW-Authenticate property
with the value starting with MAPR-Negotiate, and start the negotiation process to obtain
an authentication token. The client should also start the negotiation process to obtain an
authentication token for the first time.
Assuming that the client has already done a "maprlogin password" to obtain a valid ticket for the cluster, the first phase of the two-phase MapR challenge-response authentication is to call the generateChallenge() method:
ClientSecurity cs = new ClientSecurity();
String challengeString = cs.generateChallenge ();
The returned challenge string and encrypted ticket is sent as an HTTP option ("OPTIONS")
using the "Authorization" header with the MAPR-Negotiate property to the MapR service.
An example of how to do this can be found in the com.mapr.security.client.examples.MapRClient
class, but is outside the scope of this API. An example of a Base64 encoded challenge string
is as follows:
CihNcW/sDyVx63r25FJF0vuWNjAsdVrL1HrUivPYY8vdSelThGOPnd8zEmYCCAEVPQhUXvfjiFLP9xOIBsEGjZv4wwhZsk3ho2+lrDKFjWAHjnBqd7yQuqa+YSY7etfxkg1XK+izqqRjXkFo7zNST6swW7VmMJyo27CftvXv6wV3EFmJqcHV6ugJ3EjlHqtxlqY=
Using this sample challenge string, the request header looks something like this:
Authorization: MAPR-Negotiate CihNcW/sDyVx63r25FJF0vuWNjAsdVrL1HrUivPYY8vdSelThGOPnd8zEmYCCAEVPQhUXvfjiFLP9xOIBsEGjZv4wwhZsk3ho2+lrDKFjWAHjnBqd7yQuqa+YSY7etfxkg1XK+izqqRjXkFo7zNST6swW7VmMJyo27CftvXv6wV3EFmJqcHV6ugJ3EjlHqtxlqY=
If the server successfully validates the challenge, it will return
a status of HTTP/1.1 200 OK, together with a response to the challenge in using the
"Authorization" header with the "MAPR-Negotiate" property. This would look something like
this:
HTTP/1.1 200 OK
Authorization: MAPR-Negotiate WMlqqIt8Q5dcVo9wOtfVgBoSsbW8v/WQS0JWfGElUtPDb04hkQ/Zf26Fw7k=
Upon receiving the response from the server, the client application should verify that
the response is HTTP/1.1 200 OK, and that the response message contains the "Authorization"
header with the "MAPR-Negotiate" property. It should then extract the Base64-encoded response
to the challenge that is in the "MAPR-Negotiate" property from the response message. In our
example, this is the string
WMlqqIt8Q5dcVo9wOtfVgBoSsbW8v/WQS0JWfGElUtPDb04hkQ/Zf26Fw7k=
The client application should then pass this string into the validateServerResponseToChallenge
method:
boolean isValidResponseToChallenge = validateServerResponseToChallenge (responseToChallenge);
If this method returns without throwing an exception, then the server response is successfully
validated, and this completes the second and final phase of the challenge-response authentication.| Modifier and Type | Field and Description |
|---|---|
static java.lang.String |
AUTHORIZATION
The HTTP "Authorization" request header.
|
static java.lang.String |
CLUSTER_CONFIG_LOCATION
Location of the mapr-clusters.conf file relative to the installation directory.
|
static java.lang.String |
DEFAULT_INSTALL_LOCATION
Default installation location if the MAPR_HOME environment variable is not set.
|
static java.lang.String |
NEGOTIATE
HTTP header prefix used by the MAPR client/server end-points during an authentication sequence.
|
static java.lang.String |
WWW_AUTHENTICATE
The "WWW-Authenticate" response header.
|
static java.lang.String |
WWW_ERR_AUTHENTICATE
HTTP header used by the MAPR server end-point during an authentication sequence in case of error.
|
| Constructor and Description |
|---|
ClientSecurity()
Constructor.
|
ClientSecurity(java.lang.String clusterName)
Constructor.
|
| Modifier and Type | Method and Description |
|---|---|
java.lang.String |
generateChallenge()
Evaluates the challenge from the MapR user ticket.
|
java.lang.String |
getClusterName()
Returns the cluster name.
|
java.lang.String |
getUserTicketAndKeyFileLocation()
Obtains the full path name of the file containing the user ticket.
|
boolean |
hasValidTicket()
Determines if the user has a valid ticket for the cluster specified in the parameter.
|
boolean |
isClusterNameValid()
Returns true if the cluster name is valid, false otherwise.
|
boolean |
isSecurityEnabled()
Returns the security status for the current cluster.
|
boolean |
validateServerResponseToChallenge(java.lang.String responseToChallenge)
Given the response from the server to the challenge, validates the response to the challenge.
|
public static final java.lang.String WWW_AUTHENTICATE
HTTP/1.1 401 Unauthorized
WWW-Authenticate: MAPR-Negotiate
The client should parse the header to see if it contains the WWW-Authenticate
property with the value starting with MAPR-Negotiate, and start the negotiation
process.public static final java.lang.String AUTHORIZATION
public static final java.lang.String WWW_ERR_AUTHENTICATE
public static final java.lang.String NEGOTIATE
public static final java.lang.String CLUSTER_CONFIG_LOCATION
public static final java.lang.String DEFAULT_INSTALL_LOCATION
public ClientSecurity()
public ClientSecurity(java.lang.String clusterName)
clusterName - The cluster namepublic boolean isSecurityEnabled()
public boolean isClusterNameValid()
public java.lang.String getUserTicketAndKeyFileLocation()
throws MapRClientSecurityException
MapRClientSecurityException - Thrown when the location of the user ticket cannot be determinedpublic java.lang.String generateChallenge()
throws MapRClientSecurityException
ClientSecurity cs = new ClientSecurity();
String authRequestBytes = cs.generateChallenge();
MapRClientSecurityException - Thrown for various errors, such as user ticket is invalid or cannot
be found, or the challenge cannot be derived from the user ticketpublic boolean hasValidTicket()
throws MapRClientSecurityException
MapRClientSecurityException - Thrown for various error situations, for example, when
the ticket cannot be found, or the cluster name is invalid.public java.lang.String getClusterName()
public boolean validateServerResponseToChallenge(java.lang.String responseToChallenge)
throws MapRClientSecurityException
HTTP/1.1 200 OK
Authorization: MAPR-Negotiate M0GtfTQNSVVzOOtTFI8cgA5MON5cb1beloL+C3k6tl9lY16VRrA6GEJCSag=
In this example, the input to this method would be the following Base64-encoded string:
M0GtfTQNSVVzOOtTFI8cgA5MON5cb1beloL+C3k6tl9lY16VRrA6GEJCSag=
responseToChallenge - The Base64-encoded string giving the server response to the challengeMapRClientSecurityException - If the server response to the challenge-response negotiation
is either not present or not valid