def authenticate(self, req): token = req.headers.get('X-Auth-Token') if not token: raise exc.UnauthorizedException('Auth token is not provided.') data = {'token': token} headers = {'St2-Api-Key': cfg.CONF.st2.api_key} url = cfg.CONF.st2.auth_url + '/tokens/validate' resp = http.post(url, data, headers=headers) if (resp.status_code != http_client.OK or not resp.json().get('valid', False)): LOG.error('Unable to verify auth token. %s' % str(resp.content)) raise exc.UnauthorizedException('Unable to verify auth token.')
def obtain_service_catalog(ctx): token = ctx.auth_token if ctx.is_trust_scoped and is_token_trust_scoped(token): if ctx.trust_id is None: raise Exception( "'trust_id' must be provided in the admin context.") # trust_client = client_for_trusts(ctx.trust_id) # Using trust client, it can't validate token # when cron trigger running because keystone policy # don't allow do this. So we need use admin client to # get token data token_data = _admin_client().tokens.get_token_data( token, include_catalog=True) response = token_data['token'] else: response = ctx.service_catalog # Target service catalog may not be passed via API. # If we don't have the catalog yet, it should be requested. if not response: response = client().tokens.get_token_data( token, include_catalog=True)['token'] if not response: raise exceptions.UnauthorizedException() service_catalog = ks_service_catalog.ServiceCatalog.factory(response) return service_catalog
def obtain_service_catalog(ctx): token = ctx.auth_token if ctx.is_trust_scoped and is_token_trust_scoped(token): if ctx.trust_id is None: raise Exception( "'trust_id' must be provided in the admin context." ) trust_client = client_for_trusts(ctx.trust_id) token_data = trust_client.tokens.get_token_data( token, include_catalog=True ) response = token_data['token'] else: response = ctx.service_catalog # Target service catalog may not be passed via API. # If we don't have the catalog yet, it should be requested. if not response: response = client().tokens.get_token_data( token, include_catalog=True )['token'] if not response: raise exceptions.UnauthorizedException() service_catalog = ks_service_catalog.ServiceCatalog.factory(response) return service_catalog
def authenticate(self, req): # Note(nmakhotkin): Since we have deferred authentication, # need to check for auth manually (check for corresponding # headers according to keystonemiddleware docs. identity_status = req.headers.get('X-Identity-Status') service_identity_status = req.headers.get('X-Service-Identity-Status') if (identity_status == 'Confirmed' or service_identity_status == 'Confirmed'): return if req.headers.get('X-Auth-Token'): msg = 'Auth token is invalid: %s' % req.headers['X-Auth-Token'] else: msg = 'Authentication required' raise exc.UnauthorizedException(msg)
def authenticate(self, req): certfile = CONF.keycloak_oidc.certfile keyfile = CONF.keycloak_oidc.keyfile cafile = CONF.keycloak_oidc.cafile or self.get_system_ca_file() insecure = CONF.keycloak_oidc.insecure if 'X-Auth-Token' not in req.headers: msg = _("Auth token must be provided in 'X-Auth-Token' header.") LOG.error(msg) raise exc.UnauthorizedException(message=msg) access_token = req.headers.get('X-Auth-Token') try: decoded = jwt.decode(access_token, algorithms=['RS256'], verify=False) except Exception as e: msg = _("Token can't be decoded because of wrong format %s")\ % str(e) LOG.error(msg) raise exc.UnauthorizedException(message=msg) # Get user realm from parsed token # Format is "iss": "http://<host>:<port>/auth/realms/<realm_name>", __, __, realm_name = decoded['iss'].strip().rpartition('/realms/') # Get roles from from parsed token roles = ','.join(decoded['realm_access']['roles']) \ if 'realm_access' in decoded else '' # NOTE(rakhmerov): There's a special endpoint for introspecting # access tokens described in OpenID Connect specification but it's # available in KeyCloak starting only with version 1.8.Final so we have # to use user info endpoint which also takes exactly one parameter # (access token) and replies with error if token is invalid. user_info_endpoint = ("%s/realms/%s/protocol/openid-connect/userinfo" % (CONF.keycloak_oidc.auth_url, realm_name)) verify = None if urllib.parse.urlparse(user_info_endpoint).scheme == "https": verify = False if insecure else cafile cert = (certfile, keyfile) if certfile and keyfile else None try: resp = requests.get( user_info_endpoint, headers={"Authorization": "Bearer %s" % access_token}, verify=verify, cert=cert) except requests.ConnectionError: msg = _("Can't connect to keycloak server with address '%s'." ) % CONF.keycloak_oidc.auth_url LOG.error(msg) raise exc.MistralException(message=msg) if resp.status_code == 401: LOG.warning( "HTTP response from OIDC provider:" " [%s] with WWW-Authenticate: [%s]", pprint.pformat(resp.text), resp.headers.get("WWW-Authenticate")) else: LOG.debug("HTTP response from OIDC provider: %s", pprint.pformat(resp.text)) resp.raise_for_status() LOG.debug("HTTP response from OIDC provider: %s", pprint.pformat(resp.json())) req.headers["X-Identity-Status"] = "Confirmed" req.headers["X-Project-Id"] = realm_name req.headers["X-Roles"] = roles
def authenticate(self, req): if 'X-Auth-Token' not in req.headers: msg = _("Auth token must be provided in 'X-Auth-Token' header.") LOG.error(msg) raise exc.UnauthorizedException(message=msg) access_token = req.headers.get('X-Auth-Token') try: decoded = jwt.decode(access_token, algorithms=['RS256'], verify=False) except Exception as e: msg = _("Token can't be decoded because of wrong format %s")\ % str(e) LOG.error(msg) raise exc.UnauthorizedException(message=msg) # Get user realm from parsed token # Format is "iss": "http://<host>:<port>/auth/realms/<realm_name>", __, __, realm_name = decoded['iss'].strip().rpartition('/realms/') audience = decoded.get('aud') # Get roles from parsed token roles = ','.join(decoded['realm_access']['roles']) \ if 'realm_access' in decoded else '' # NOTE(rakhmerov): There's a special endpoint for introspecting # access tokens described in OpenID Connect specification but it's # available in KeyCloak starting only with version 1.8.Final so we have # to use user info endpoint which also takes exactly one parameter # (access token) and replies with error if token is invalid. user_info_endpoint_url = CONF.keycloak_oidc.user_info_endpoint_url if user_info_endpoint_url.startswith(('http://', 'https://')): self.send_request_to_auth_server(url=user_info_endpoint_url, access_token=access_token) else: public_key = self.get_public_key(realm_name) keycloak_iss = None try: if CONF.keycloak_oidc.keycloak_iss: keycloak_iss = CONF.keycloak_oidc.keycloak_iss % realm_name jwt.decode(access_token, public_key, audience=audience, issuer=keycloak_iss, algorithms=['RS256'], verify=True) except Exception: LOG.exception('The request access token is invalid.') raise exc.UnauthorizedException() req.headers["X-Identity-Status"] = "Confirmed" req.headers["X-Project-Id"] = realm_name req.headers["X-Roles"] = roles
def authenticate(self, req): raise exc.UnauthorizedException()