Class ClientSecurity


  • public class ClientSecurity
    extends java.lang.Object
    The ClientSecurity class. This is the pure Java implementation of the client-side API using MapR ticket authentication, used for REST API calls. The MapR challenge-response handshake allows for mutual authentication of both server and client using the MapR ticket-based security model.

    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.
    • Field Summary

      Fields 
      Modifier and Type Field 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 Summary

      Constructors 
      Constructor Description
      ClientSecurity()
      Constructor.
      ClientSecurity​(java.lang.String clusterName)
      Constructor.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method 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.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • WWW_AUTHENTICATE

        public static final java.lang.String WWW_AUTHENTICATE
        The "WWW-Authenticate" response header. Used to determine if we are in the negotiation phase. 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 relevant headers would look like this:
         
         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.
        See Also:
        Constant Field Values
      • AUTHORIZATION

        public static final java.lang.String AUTHORIZATION
        The HTTP "Authorization" request header. As per RFC 2616 (superseded by 7235), a user agent that wishes to authenticate itself with a server usually, but not necessarily, after receiving a 401 response, does so by including an Authorization request-header field with the request. The Authorization field value consists of credentials containing the authentication information of the user agent for the realm of the resource being requested. For MapR ticket authentication, this is the token obtained after successfully completing the challenge-response authentication. Upon receipt of the response containing a "WWW-Authenticate" header from the server, the client is expected to retry the HTTP request, passing a HTTP "Authorization" header line. See https://tools.ietf.org/html/rfc2616#page-107.
        See Also:
        Constant Field Values
      • WWW_ERR_AUTHENTICATE

        public static final java.lang.String WWW_ERR_AUTHENTICATE
        HTTP header used by the MAPR server end-point during an authentication sequence in case of error. Example: HTTP/1.1 403 Forbidden WWW-MAPR-Err-Authenticate Value: [Bad server key]
        See Also:
        Constant Field Values
      • NEGOTIATE

        public static final java.lang.String NEGOTIATE
        HTTP header prefix used by the MAPR client/server end-points during an authentication sequence. See the comments for WWW_AUTHENTICATE (WWW-Authenticate).
        See Also:
        Constant Field Values
      • CLUSTER_CONFIG_LOCATION

        public static final java.lang.String CLUSTER_CONFIG_LOCATION
        Location of the mapr-clusters.conf file relative to the installation directory. The first line of this file is used to determine the default cluster name and whether or not the cluster is secure. This is at /conf/mapr-clusters.conf.
        See Also:
        Constant Field Values
      • DEFAULT_INSTALL_LOCATION

        public static final java.lang.String DEFAULT_INSTALL_LOCATION
        Default installation location if the MAPR_HOME environment variable is not set. This is /opt/mapr
        See Also:
        Constant Field Values
    • Constructor Detail

      • ClientSecurity

        public ClientSecurity()
        Constructor. Parses the mapr-clusters.conf to determine the cluster name and whether security is enabled Since no cluster is specified, the default cluster that appears in the first line of mapr-clusters.conf is used
      • ClientSecurity

        public ClientSecurity​(java.lang.String clusterName)
        Constructor. Parses the mapr-clusters.conf to determine the cluster name and whether security is enabled. Uses the cluster name passed into the parameter as the cluster for all methods in the class. You need a different instance of this class to access different clusters
        Parameters:
        clusterName - The cluster name
    • Method Detail

      • isSecurityEnabled

        public boolean isSecurityEnabled()
        Returns the security status for the current cluster. To determine this, we look line of mapr-clusters.conf with the cluster name matching the cluster name passed in the constructor, and look for the secure=true flag. If set to true, then security is enabled for the cluster, otherwise security is not enabled. The ClientSecurity class is only applicable for secure clusters.
        Returns:
        Returns true if security is enabled for the cluster, false otherwise.
      • isClusterNameValid

        public boolean isClusterNameValid()
        Returns true if the cluster name is valid, false otherwise. The cluster name is valid if there is an entry in mapr-cluster.conf for this cluster
        Returns:
        Returns true if the cluster name is valid, false otherwise.
      • getUserTicketAndKeyFileLocation

        public java.lang.String getUserTicketAndKeyFileLocation()
                                                         throws MapRClientSecurityException
        Obtains the full path name of the file containing the user ticket. This is determined as follows:
        • If the environment variable MAPR_TICKETFILE_LOCATION is set, then return the value of this environment variable.
        • Otherwise, the default location of the user ticket is as follows:
          • For Windows, this is at %TEMP%\maprticket_<username>. Example: C:\Temp\maprticket_joe.
          • For all other operating systems, this is at /tmp/maprticket_<uid> where <uid> is the effective UID of calling process.
        Pure Java implementation of the Security::GetUserTicketAndKeyFileLocation C API in src/fs/common/credentials.h
        Returns:
        The full path name of the file containing the user ticket.
        Throws:
        MapRClientSecurityException - Thrown when the location of the user ticket cannot be determined
      • generateChallenge

        public java.lang.String generateChallenge()
                                           throws MapRClientSecurityException
        Evaluates the challenge from the MapR user ticket. Call this method to return a Base64-encoded string that can be used as an authentication string in a REST API call with the MAPR-Negotiate property. For example:
         
         ClientSecurity cs = new ClientSecurity();
         String authRequestBytes = cs.generateChallenge();
         
        Returns:
        The encrypted challenge string as a Base-64 encoded string
        Throws:
        MapRClientSecurityException - Thrown for various errors, such as user ticket is invalid or cannot be found, or the challenge cannot be derived from the user ticket
      • hasValidTicket

        public boolean hasValidTicket()
                               throws MapRClientSecurityException
        Determines if the user has a valid ticket for the cluster specified in the parameter.
        Returns:
        Returns true if the user has a valid ticket for the cluster, false otherwise.
        Throws:
        MapRClientSecurityException - Thrown for various error situations, for example, when the ticket cannot be found, or the cluster name is invalid.
      • getClusterName

        public java.lang.String getClusterName()
        Returns the cluster name. This is the cluster name that is set in the constructor
        Returns:
        The cluster name as an ASCII string. This is the cluster name from the first line of mapr-clusters.conf
      • validateServerResponseToChallenge

        public boolean validateServerResponseToChallenge​(java.lang.String responseToChallenge)
                                                  throws MapRClientSecurityException
        Given the response from the server to the challenge, validates the response to the challenge. The server response is the Base-64 encoded string after the MAPR-Negotiate property in the Authorization header. It is the responsibility of the client application to extract the response to the challenge from the header and pass it in to this method as the second phase of the challenge-response negotiation. A sample header looks like this:
         
         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=
         
         
        Parameters:
        responseToChallenge - The Base64-encoded string giving the server response to the challenge
        Returns:
        Returns true if the server response is present and valid. Otherwise, a MapRClientSecurityException is thrown with the error message.
        Throws:
        MapRClientSecurityException - If the server response to the challenge-response negotiation is either not present or not valid