Ejemplo n.º 1
0
 def _check_token():
     token = request.headers.get('AUTHORIZATION')
     from keycloak import KeycloakOpenID
     keycloak_openid = KeycloakOpenID(
         server_url=app.config.get("SERVER_URL"),
         client_id=app.config.get("CLIENT_ID"),
         realm_name=app.config.get("REALM_NAME"),
         client_secret_key=app.config.get("CLIENT_SECRET_KEY"))
     token_info = keycloak_openid.introspect(token)
     return True
Ejemplo n.º 2
0
class AuthEndpoint:
    def __init__(self, app):
        self.app = app
        self.url = self.app.config['KEYCLOAK_URL']
        self.client_id = self.app.config['CLIENT_ID']
        self.client_secret = self.app.config['CLIENT_SECRET']
        self.keycloak_openid = KeycloakOpenID(
            server_url=self.url,
            client_id=self.client_id,
            realm_name='apartments',
            client_secret_key=self.client_secret,
            verify=False)

    def require_token(self, roles=None):
        def decorator(f):
            @wraps(f)
            def decorated_function(*args, **kwargs):
                auth_header = request.headers.get('Authorization')
                if not auth_header:
                    return 'Authorization required', 401
                if 'Bearer ' not in auth_header:
                    return 'Bearer token required', 401
                token = auth_header.replace('Bearer ', '')
                try:
                    user = self.keycloak_openid.introspect(token)
                    missing_roles = set(roles) - set(
                        user['resource_access']['api-gateway']['roles'])
                    if missing_roles:
                        return F'Unauthorized, missing roles. {missing_roles}', 401
                except Exception:
                    return 'Unauthorized', 401
                return f(*args, **kwargs)

            return decorated_function

        return decorator
Ejemplo n.º 3
0
class _Keycloak(AuthProvider):
    f"""
    Redis key-value pair database implementation of KeyValueStore
    
    Defines methods for getting, deleting and putting key value pairs
    
    :param host, port, db (see also `https://github.com/andymccurdy/redis-py)`
    Example:
    ```
        db = KeyValueDatabase.instance(provider='redis', host='localhost', port=6379, db=0)
    ```
    """
    def __init__(self,
                 domain: Optional[str] = None,
                 audience: Optional[str] = None):

        super().__init__()
        self._domain = domain or os.getenv('KEYCLOAK_DOMAIN')
        self._client_secret_key = os.getenv('KEYCLOAK_CLIENT_SECRET_KEY')
        self._client_secret_id = os.getenv('KEYCLOAK_CLIENT_SECRET_ID')
        self._realm = os.getenv('KEYCLOAK_REALM')
        self._audience = audience or os.getenv('XCUBE_HUB_OAUTH_AUD')
        self._algorithms = ["RS256"]

        if self._domain is None:
            raise Unauthorized(description="Keycloak error: Domain not set")

        if self._audience is None:
            raise Unauthorized(description="Keycloak error: Audience not set")

        self._keycloak_openid = KeycloakOpenID(
            server_url=f"https://{self._domain}/auth/",
            client_id=self._client_secret_id,
            realm_name=self._realm,
            client_secret_key=self._client_secret_key,
            verify=True)

    def get_email(self, claims):
        if 'email' not in claims:
            return "no email"
        return claims['email']

    def verify_token(self, token: str) -> Dict:
        """
        Get a key value
        :param token:
        :return:
        """

        try:
            self._keycloak_openid.introspect(token)
        except KeycloakGetError as e:
            raise Unauthorized(description="invalid token: " + str(e))

        certs = self._keycloak_openid.certs()
        rsa_key = {}
        for key in certs["keys"]:
            rsa_key = {
                "kty": key["kty"],
                "kid": key["kid"],
                "use": key["use"],
                "n": key["n"],
                "e": key["e"]
            }

        try:
            self._claims = self._keycloak_openid.decode_token(token=token,
                                                              key=rsa_key)
        except Exception as e:
            raise Unauthorized(description=str(e))

        return self._claims
Ejemplo n.º 4
0
class KeycloakClient:
    """Wrapper for Keycloak OpenID and admin clients."""
    def __init__(self, server, resource, realm, secret, admin_user,
                 admin_pass):
        self.openid = KeycloakOpenID(
            server_url=server,
            client_id=resource,
            realm_name=realm,
            client_secret_key=secret,
        )
        self.admin = _KeycloakAdmin(
            server_url=server,
            client_id=resource,
            realm_name=realm,
            client_secret_key=secret,
            username=admin_user,
            password=admin_pass,
            auto_refresh_token=['get', 'put', 'post', 'delete'],
        )

    def login(self, username, password):
        return self.openid.token(username, password, totp=None)

    def token_refresh(self, refresh_token):
        return self.openid.refresh_token(refresh_token)

    def token_info(self, token):
        return self.openid.introspect(token)

    def user_list(self, query=None):
        return self.admin.get_users(query)

    def user_get(self, user_id):
        return self.admin.get_user(user_id)

    def user_create(self, data):
        data = data.copy()
        data.setdefault('enabled', True)

        if 'password' in data:
            data['credentials'] = [
                {
                    'type': 'password',
                    'value': data['password']
                },
            ]
            del data['password']

        return self.admin.create_user(data)

    def user_update(self, user_id, data):
        data = data.copy()

        if 'password' in data:
            data['credentials'] = [
                {
                    'type': 'password',
                    'value': data['password']
                },
            ]
            del data['password']

        self.admin.update_user(user_id, data)

    def user_delete(self, user_id):
        self.admin.delete_user(user_id)

    def user_group_list(self, user_id):
        """Get list of groups user belongs to."""
        return self.admin.get_user_groups(user_id)

    def user_role_list(self, user_id):
        """
        Get set of all user roles (**role names**), directly assigned and also
        inherited from a group.
        """
        roles = set()

        # directly assigned roles
        roles = {
            i['name']
            for i in self.admin.get_realm_roles_of_user(user_id)
        }

        # iherited roles from group
        for group in self.user_group_list(user_id):
            roles |= {
                i['name']
                for i in self.admin.get_group_realm_roles(group['id'])
            }

        return roles

    def user_check_group(self, user_id, group_id):
        """Check if user belongs to the given group."""
        return self.user_check_group_any(user_id, [group_id])

    def user_check_group_any(self, user_id, group_id_list):
        """Check if user belongs to any of the given groups."""
        return any(group['id'] in group_id_list
                   for group in self.user_group_list(user_id))

    def user_check_role(self, user_id, role_name):
        """Check if user has role."""
        return role_name in self.user_role_list(user_id)

    def group_list(self):
        return self.admin.get_groups()

    def group_get(self, group_id):
        return self.admin.get_group(group_id)

    def group_create(self, data):
        # `create_group` always returns b''
        self.admin.create_group(data)

        for group in self.group_list():
            if group['name'] == data['name']:
                return group['id']

    def group_update(self, group_id, data):
        self.admin.update_group(group_id, data)

    def group_delete(self, group_id):
        self.admin.delete_group(group_id)

    def group_user_list(self, group_id):
        """Get list of users in group."""
        return self.admin.get_group_members(group_id)

    def group_user_add(self, user_id, group_id):
        """Add user to group."""
        self.admin.group_user_add(user_id, group_id)

    def group_user_remove(self, user_id, group_id):
        """Remove user from group."""
        self.admin.group_user_remove(user_id, group_id)

    def group_role_list(self, group_id):
        return self.admin.get_group_realm_roles(group_id)

    def group_role_add(self, role_name, group_id):
        """Add role to group. **Role NAME, not ID.**"""
        role = self.role_get(role_name)
        self.admin.assign_group_realm_roles(group_id, [role])

    def group_role_remove(self, role_name, group_id):
        """Remove role from group. **Role NAME, not ID.**"""
        role = self.role_get(role_name)
        self.admin.delete_group_realm_roles(group_id, [role])

    def role_list(self):
        return self.admin.get_realm_roles()

    def role_get(self, role_name):
        """Get role by name. **NAME, not ID.**"""
        return self.admin.get_realm_role(role_name)

    def role_create(self, data):
        # `create_role` always returns b''
        self.admin.create_realm_role(data)

        for role in self.role_list():
            if role['name'] == data['name']:
                return role['name']

    def role_update(self, role_id, data):
        self.admin.update_realm_role(role_id, data)

    def role_delete(self, role_id):
        self.admin.delete_realm_role(role_id)
Ejemplo n.º 5
0
# Refresh token
token = keycloak_openid.refresh_token(token['refresh_token'])

# Logout
keycloak_openid.logout(token['refresh_token'])

# Get Certs
certs = keycloak_openid.certs()

# Get RPT (Entitlement)
token = keycloak_openid.token("user", "password")
rpt = keycloak_openid.entitlement(token['access_token'], "resource_id")

# Instropect RPT
token_rpt_info = keycloak_openid.introspect(keycloak_openid.introspect(token['access_token'], rpt=rpt['rpt'],
                                     token_type_hint="requesting_party_token"))

# Introspect Token
token_info = keycloak_openid.introspect(token['access_token']))

# Decode Token
KEYCLOAK_PUBLIC_KEY = keycloak_openid.public_key()
options = {"verify_signature": True, "verify_aud": True, "exp": True}
token_info = keycloak_openid.decode_token(token['access_token'], key=KEYCLOAK_PUBLIC_KEY, options=options)

# Get permissions by token
token = keycloak_openid.token("user", "password")
keycloak_openid.load_authorization_config("example-authz-config.json")
policies = keycloak_openid.get_policies(token['access_token'], method_token_info='decode', key=KEYCLOAK_PUBLIC_KEY)
permissions = keycloak_openid.get_permissions(token['access_token'], method_token_info='introspect')