Ejemplo n.º 1
0
class OAuth2Middleware(AuthenticationMiddleware):
    """
    Two Legged OAuth authenticator. 
    
    This Authentication method checks for a provided HTTP_AUTHORIZATION
    and looks up to see if this is a valid OAuth Consumer
    """

    # Authentication server
    # Create a Python Globus client
    client = Client(
        config_file=os.path.join(os.path.dirname(__file__), 'nexus/nexus.yml'))

    try:
        authsvc = "https://%s/" % client.config['server']
    except:
        authsvc = 'https://nexus.api.globusonline.org/'

    # Set the salt used for computing a session hash from the signature hash
    salt = "(African || European)?"

    def __init__(self, realm='API'):
        self.realm = realm
        self.user = None
        self.http = httplib2.Http(disable_ssl_certificate_validation=True)
        # The shortcut option will bypass token validation if we already have a django session
        self.shortcut = False

    def process_request(self, request):
        """
        Verify 2-legged oauth request. Parameters accepted as
        values in "Authorization" header, or as a GET request
        or in a POST body.
        """
        # AuthenticationMiddleware is required so that request.user exists.
        if not hasattr(request, 'user'):
            raise ImproperlyConfigured(
                "The Django remote user auth middleware requires the"
                " authentication middleware to be installed.  Edit your"
                " MIDDLEWARE_CLASSES setting to insert"
                " 'django.contrib.auth.middleware.AuthenticationMiddleware'"
                " before the RemoteUserMiddleware class.")
        try:
            if 'HTTP_AUTHORIZATION' in request.META:
                auth_header = request.META.get('HTTP_AUTHORIZATION')
            else:
                logging.debug("No authorization header found.")
                return None
            # Extract the token based on whether it is an OAuth or Bearer
            # token
            if auth_header[:6] == 'OAuth ':
                token = auth_header[6:]
            elif auth_header[:7] == 'Bearer ':
                token = auth_header[7:]
            else:
                logging.info(
                    "Authorization header did not contain OAuth or Bearer type token"
                )
                return None
            # Push the token into the META for future reference
            request.META['KBASEtoken'] = token
            if (request.user.is_authenticated() and self.shortcut):
                return

            user_id = OAuth2Middleware.client.authenticate_user(token)
            if not user_id:
                logging.error("Authentication token failed validation")
                return None
            else:
                logging.info("Validated as user " + user_id)
            token_map = {}
            for entry in token.split('|'):
                key, value = entry.split('=')
                token_map[key] = value
            profile = self.get_profile(token)
            if (profile == None):
                logging.error(
                    "Token validated, but could not retrieve user profile")
                return None
            # For now, compute a sessionid based on hashing the
            # the signature with the salt
            request.META['KBASEsessid'] = hashlib.sha256(
                token_map['sig'] + OAuth2Middleware.salt).hexdigest()
            # Add in some useful details that came in from the token validation
            request.META['KBASEprofile'] = profile
            # See if the username is already associated with any currently logged
            # in user, if so just pass over the rest
            # Raises exception if it doesn't pass
            user = authenticate(remote_user=profile['username'])
            if user:
                request.user = user
                # For now, compute a sessionid based on hashing the
                # the signature with the salt
                request.META['KBASEsessid'] = hashlib.sha256(
                    token_map['sig'] + OAuth2Middleware.salt).hexdigest()
                print pformat(request.META['KBASEsessid'])
                # Add in some useful details that came in from the token validation
                request.META['KBASEprofile'] = profile
                login(request, user)
            else:
                logging.error(
                    "Failed to return user from call to authenticate() with username "
                    + profile['username'])
        except KeyError, e:
            logging.exception("KeyError in TwoLeggedOAuthMiddleware: %s" % e)
            request.user = AnonymousUser()
        except Exception, e:
            logging.exception("Error in TwoLeggedOAuthMiddleware: %s" % e)