Beispiel #1
0
    def tokenIssue(self, ticket, subject, properties):
        """Call /api/auth/token/issue API.

        Args:
            ticket (str)  : The ticket which has been issued previously from /api/auth/token API.
            subject (str) : The unique identifier of the resource owner.
            properties (list of authlete.dto.Property)

        Returns:
            django.http.HttpResponse

        Raises:
            authlete.api.AuthleteApiException
        """

        # Call /api/auth/token/issue API.
        res = self.__callTokenIssue(ticket, subject, properties)

        # 'action' in the response denotes the next action which the
        # implementation of the token endpoint should take.
        action = res.action

        # The content of the response to the client application.
        content = res.responseContent

        if action == TokenIssueAction.INTERNAL_SERVER_ERROR:
            # 500 Internal Server Error
            return ResponseUtility.internalServerError(content)
        elif action == TokenIssueAction.OK:
            # 200 OK
            return ResponseUtility.okJson(content)
        else:
            # 500 Internal Server Error
            # The /api/auth/token/issue API returned an unknown action.
            return self.unknownAction('/api/auth/token/issue')
Beispiel #2
0
    def tokenFail(self, ticket, reason):
        """Call /api/auth/authorization/fail API.

        Args:
            ticket (str) : The ticket which has been issued previously from /api/auth/token API.
            reason (authlete.dto.TokenFailReason) : The reason of the failure of the request.

        Returns:
            django.http.HttpResponse

        Raises:
            authlete.api.AuthleteApiException
        """

        # Call /api/auth/token/fail API.
        res = self.__callTokenFail(ticket, reason)

        # 'action' in the response denotes the next action which the
        # implementation of the token endpoint should take.
        action = res.action

        # The content of the response to the client application.
        content = res.responseContent

        if action == TokenFailAction.INTERNAL_SERVER_ERROR:
            # 500 Internal Server Error
            return ResponseUtility.internalServerError(content)
        elif action == TokenFailAction.BAD_REQUEST:
            # 400 Bad Request
            return ResponseUtility.badRequest(content)
        else:
            # 500 Internal Server Error
            # The /api/auth/token/fail API returned an unknown action.
            return self.unknownAction('/api/auth/token/fail')
Beispiel #3
0
    def handle(self, request):
        """Handle a userinfo request.

        This method calls Authlete's /api/auth/userinfo API and conditionally
        /api/auth/userinfo/issue API.

        Args:
            request (django.http.HttpRequest)

        Returns:
            django.http.HttpResponse

        Raises:
            authlete.api.AuthleteApiException
        """

        # Extract the access token from 'Authorization: Bearer {accessToken}'.
        accessToken = RequestUtility.extractBearerToken(request)

        if accessToken is None:
            # 400 Bad Request with a WWW-Authenticate header.
            return ResponseUtility.wwwAuthenticate(
                400,
                'Bearer error="invalid_token",error_description="An access token is required."'
            )

        # Call Authlete's /api/auth/userinfo API.
        res = self.__callUserInfoApi(accessToken)

        # 'action' in the response denotes the next action which the
        # implementation of the userinfo endpoint should take.
        action = res.action

        # The content of the response to the client application.
        content = res.responseContent

        if action == UserInfoAction.INTERNAL_SERVER_ERROR:
            # 500 Internal Server Error
            return ResponseUtility.wwwAuthenticate(500, content)
        elif action == UserInfoAction.BAD_REQUEST:
            # 400 Bad Request
            return ResponseUtility.wwwAuthenticate(400, content)
        elif action == UserInfoAction.UNAUTHORIZED:
            # 401 Unauthorized
            return ResponseUtility.wwwAuthenticate(401, content)
        elif action == UserInfoAction.FORBIDDEN:
            # 403 Forbidden
            return ResponseUtility.wwwAuthenticate(403, content)
        elif action == UserInfoAction.OK:
            # Return the user information.
            return self.__getUserInfo(res)
        else:
            # 500 Internal Server Error
            # /api/auth/userinfo API returns an unknown action.
            return self.unknownAction('/api/auth/userinfo')
    def handle(self, response):
        """Handle an error case of an authorization request.

        This method returns None when response.action returns
        AuthorizationAction.INTERACTION or AuthorizationAction.NO_INTERACTION.
        In other cases, an instance of django.http.HttpResponse is returned.

        Args:
            response (authlete.dto.AuthorizationResponse)

        Returns:
            django.http.HttpResponse : An error response

        Raises:
            authlete.api.AuthleteApiException
        """

        # 'action' in the response denotes the next action which the
        # implementation of the authorization endpoint should take.
        action = response.action

        # The content of the response which should be returned to the
        # user agent. The format varies depending on the action.
        content = response.responseContent

        if action == AuthorizationAction.INTERNAL_SERVER_ERROR:
            # 500 Internal Server Error
            return ResponseUtility.internalServerError(content)
        elif action == AuthorizationAction.BAD_REQUEST:
            # 400 Bad Request
            return ResponseUtility.badRequest(content)
        elif action == AuthorizationAction.LOCATION:
            # 302 Found
            return ResponseUtility.location(content)
        elif action == AuthorizationAction.FORM:
            # 200 OK
            return ResponseUtility.okHtml(content)
        elif action == AuthorizationAction.INTERACTION:
            # This is not an error case. The implementation of the
            # authorization endpoint should show an authorization
            # page to the user.
            return None
        elif action == AuthorizationAction.NO_INTERACTION:
            # This is not an error case. The implementation of the
            # authorization endpoint should handle the authorization
            # request without user interaction.
            return None
        else:
            # 500 Internal Server Error
            # Authlete's /api/auth/authorization API returned an unknown action.
            return self.unknownAction('/api/auth/authorization')
Beispiel #5
0
    def handle(self, request):
        """Handle a revocation request.

        This method calls Authlete's /api/auth/revocation API.

        Args:
            request (django.http.HttpRequest)

        Returns:
            django.http.HttpResponse

        Raises:
            authlete.api.AuthleteApiException
        """

        # Request Body and Authorization Header
        params = RequestUtility.extractRequestBody(request)
        auth = RequestUtility.extractAuthorization(request)

        # BasicCredentials that represents the value of the Authorization header.
        credentials = self.__parseCredentials(auth)

        # Call Authlete's /api/auth/revocation API.
        res = self.__callRevocationApi(params, credentials)

        # 'action' in the response denotes the next action which the
        # implementation of the revocation endpoint should take.
        action = res.action

        # The content of the response to the client application.
        content = res.responseContent

        if action == RevocationAction.INVALID_CLIENT:
            # 401 Unauthorized.
            return ResponseUtility.unauthorized('Basic realm="revocation"',
                                                content)
        elif action == RevocationAction.INTERNAL_SERVER_ERROR:
            # 500 Internal Server Error
            return ResponseUtility.internalServerError(content)
        elif action == RevocationAction.BAD_REQUEST:
            # 400 Bad Request
            return ResponseUtility.badRequest(content)
        elif action == RevocationAction.OK:
            # 200 OK
            return ResponseUtility.okJavaScript(content)
        else:
            # 500 Internal Server Error
            # /api/auth/revocation API returns an unknown action.
            return self.unknownAction('/api/auth/revocation')
    def authorizationIssue(self, ticket, subject, authTime, acr, claims,
                           properties, scopes, sub):
        """Call /api/auth/authorization/issue API.

        Args:
            ticket (str)      : The ticket which has been issued previously from /api/auth/authorization API.
            subject (str)     : The unique identifier of the user who has granted permissions to the client.
            authTime (int)    : The time at which the user was authenticated. Seconds since the Unix epoch.
            acr (str)         : The Authentication Context Class Reference performed for user authentication.
            claims (dict)     : Claims about the user.
            properties (list) : list of authlete.dto.Property. Arbitrary properties to be associated with tokens.
            scopes (list)     : list of str. Scopes to be associated with tokens.
            sub (str)         : The value of the "sub" claim in an ID token.

        Returns:
            django.http.HttpResponse

        Raises:
            authlete.api.AuthleteApiException
        """

        # Call /api/auth/authorization API.
        res = self.__callAuthorizationIssue(ticket, subject, authTime, acr,
                                            claims, properties, scopes, sub)

        # 'action' in the response denotes the next action which the
        # implementation of the authorization endpoint should take.
        action = res.action

        # The content of the response to the user agent. The format
        # of the content varies depending on the action.
        content = res.responseContent

        if action == AuthorizationIssueAction.INTERNAL_SERVER_ERROR:
            # 500 Internal Server Error
            return ResponseUtility.internalServerError(content)
        elif action == AuthorizationIssueAction.BAD_REQUEST:
            # 400 Bad Request
            return ResponseUtility.badRequest(content)
        elif action == AuthorizationIssueAction.LOCATION:
            # 302 Found
            return ResponseUtility.location(content)
        elif action == AuthorizationIssueAction.FORM:
            # 200 OK
            return ResponseUtility.okHtml(content)
        else:
            # 500 Internal Server Error
            # The /api/auth/authorization/issue API returned an unknown action.
            return self.unknownAction('/api/auth/authorization/issue')
    def handle(self, request):
        """Handle an introspection request.

        This method calls Authlete's /api/auth/introspection/starndard API.

        Args:
            request (django.http.HttpRequest)

        Returns:
            django.http.HttpResponse

        Raises:
            authlete.api.AuthleteApiException
        """

        # Request parameters in the request body.
        params = RequestUtility.extractRequestBody(request)

        # Call Authlete's /api/auth/introspection/standard API.
        res = self.__callStandardIntrospectionApi(params)

        # 'action' in the response denotes the next action which the
        # implementation of the introspection endpoint should take.
        action = res.action

        # The content of the response to the client application.
        content = res.responseContent

        if action == StandardIntrospectionAction.INTERNAL_SERVER_ERROR:
            # 500 Internal Server Error
            return ResponseUtility.internalServerError(content)
        elif action == StandardIntrospectionAction.BAD_REQUEST:
            # 400 Bad Request
            return ResponseUtility.badRequest(content)
        elif action == StandardIntrospectionAction.OK:
            # 200 OK
            return ResponseUtility.okJson(content)
        else:
            # 500 Internal Server Error
            # /api/auth/introspection/standard API returns an unknown action.
            return self.unknownAction('/api/auth/introspection/standard')
    def authorizationFail(self, ticket, reason):
        """Call /api/auth/authorization/fail API.

        Args:
            ticket (str) : The ticket which has been issued previously from /api/auth/authorization API.
            reason (authlete.dto.AuthorizationFailReason) : The reason of the failure of the request.

        Returns:
            django.http.HttpResponse

        Raises:
            authlete.api.AuthleteApiException
        """

        # Call /api/auth/authorization/fail API.
        res = self.__callAuthorizationFail(ticket, reason)

        # 'action' in the response denotes the next action which the
        # implementation of the authorization endpoint should take.
        action = res.action

        # The content of the response to the user agent. The format
        # of the content varies depending on the action.
        content = res.responseContent

        if action == AuthorizationFailAction.INTERNAL_SERVER_ERROR:
            # 500 Internal Server Error
            return ResponseUtility.internalServerError(content)
        elif action == AuthorizationFailAction.BAD_REQUEST:
            # 400 Bad Request
            return ResponseUtility.badRequest(content)
        elif action == AuthorizationFailAction.LOCATION:
            # 302 Found
            return ResponseUtility.location(content)
        elif action == AuthorizationFailAction.FORM:
            # 200 OK
            return ResponseUtility.okHtml(content)
        else:
            # 500 Internal Server Error
            # The /api/auth/authorization/fail API returned an unknown action.
            return self.unknownAction('/api/auth/authorization/fail')
Beispiel #9
0
    def __userInfoIssue(self, token, claims, sub):
        # Call Authlete's /api/auth/userinfo/issue API.
        res = self.__callUserInfoIssueApi(token, claims, sub)

        # 'action' in the response denotes the next action which the
        # implementation of the userinfo endpoint should take.
        action = res.action

        # The content of the response to the client application.
        content = res.responseContent

        if action == UserInfoIssueAction.INTERNAL_SERVER_ERROR:
            # 500 Internal Server Error
            return ResponseUtility.wwwAuthenticate(500, content)
        elif action == UserInfoIssueAction.BAD_REQUEST:
            # 400 Bad Request
            return ResponseUtility.wwwAuthenticate(400, content)
        elif action == UserInfoIssueAction.UNAUTHORIZED:
            # 401 Unauthorized
            return ResponseUtility.wwwAuthenticate(401, content)
        elif action == UserInfoIssueAction.FORBIDDEN:
            # 403 Forbidden
            return ResponseUtility.wwwAuthenticate(403, content)
        elif action == UserInfoIssueAction.JSON:
            # 200 OK, application/json; charset=UTF-8
            return ResponseUtility.okJson(content)
        elif action == UserInfoIssueAction.JWT:
            # 200 OK, application/jwt
            return ResponseUtility.okJwt(content)
        else:
            # 500 Internal Server Error
            # /api/auth/userinfo/issue API returns an unknown action.
            return self.unknownAction('/api/auth/userinfo/issue')
Beispiel #10
0
    def unknownAction(self, apiPath):
        """Create a response indicating that an unknown action was received.

        Args:
            apiPath (str) : The path of an Authlete API.

        Returns:
            django.http.HttpResponse
        """

        content = \
            '{"error":"server_error","error_description":"Authlete\'s " + \
            "{} API returned an unknown action."}'                                                  .format(apiPath)

        return ResponseUtility.internalServerError(content)
Beispiel #11
0
    def __buildResponse(self):
        # This simple example generates JSON that holds information about
        # the current time.

        # The current time in UTC.
        current = datetime.utcnow()

        # Build JSON manually.
        lines = [
            '{', '  "year":   {},'.format(current.year),
            '  "month":  {},'.format(current.month),
            '  "day":    {},'.format(current.day),
            '  "hour":   {},'.format(current.hour),
            '  "minute": {},'.format(current.minute),
            '  "second": {}'.format(current.second), '}'
        ]

        content = '\n'.join(lines) + '\n'

        # "200 OK", "application/json;charset=UTF-8"
        return ResponseUtility.okJson(content)
    def __buildErrorFromResponse(self, response):
        action = response.action

        if action == IntrospectionAction.INTERNAL_SERVER_ERROR:
            statusCode = 500
        elif action == IntrospectionAction.BAD_REQUEST:
            statusCode = 400
        elif action == IntrospectionAction.UNAUTHORIZED:
            statusCode = 401
        elif action == IntrospectionAction.FORBIDDEN:
            statusCode = 403
        else:
            statusCode = 500

        # In error cases, the 'responseContent' parameter in the response
        # from Authlete's /api/auth/introspection API contains a value for
        # the WWW-Authenticate header.
        challenge = response.responseContent

        # Build a response that complies with RFC 6749.
        return ResponseUtility.wwwAuthenticate(statusCode, challenge)
Beispiel #13
0
    def handle(self, request):
        # "1.1. Introspection Request" in RFC 7662 says as follows:
        #
        #   To prevent token scanning attacks, the endpoint MUST also require
        #   some form of authorization to access this endpoint, such as client
        #   authentication as described in OAuth 2.0 [RFC6749] or a separate
        #   OAuth 2.0 access token such as the bearer token described in OAuth
        #   2.0 Bearer Token Usage [RFC6750]. The methods of managing and
        #   validating these authentication credentials are out of scope of
        #   this specification.
        #
        # Therefore, this API must be protected in some way or other. Let's
        # perform authentication of the API caller.
        authenticated = self.__authenticate_api_caller(request)

        # If the API caller does not have necessary privilages to call this API.
        if authenticated == False:
            # 401 Unauthorized
            return ResponseUtility.unauthorized('Basic realm="/api/introspection"')

        # Call Authlete's /api/auth/introspection/standard API.
        return IntrospectionRequestHandler(self.api).handle(request)
    def handle(self, request, pretty=True):
        """Handle a request to a configuration endpoint.

        This method calls Authlete's /api/service/configuration API.

        Args:
            requet (django.http.HttpRequest)
            pretty (bool)

        Returns:
            django.http.HttpResponse

        Raises:
            authlete.api.AuthleteApiException
        """

        # Call Authlete's /api/service/configuration API. The API returns
        # JSON that complies with OpenID Connect Discovery 1.0.
        jsn = self.api.getServiceConfiguration(pretty)

        # 200 OK, application/json;charset=UTF-8
        return ResponseUtility.okJson(jsn)
    def __buildErrorFromException(self, cause):
        # The value for the WWW-Authenticate header.
        challenge = 'Bearer error="server_error",error_description="Introspection API call failed."'

        # Build a response that complies with RFC 6749.
        return ResponseUtility.wwwAuthenticate(500, challenge)