def get(self): """ .. :quickref: OIDC; Authenticate with OIDC :status 200: OK :status 401: Unauthorized :resheader X-Rucio-OIDC-Auth-URL: User & Rucio OIDC Client specific Authorization URL """ headers = Headers() headers.set('Access-Control-Allow-Origin', request.environ.get('HTTP_ORIGIN')) headers.set('Access-Control-Allow-Headers', request.environ.get('HTTP_ACCESS_CONTROL_REQUEST_HEADERS')) headers.set('Access-Control-Allow-Methods', '*') headers.set('Access-Control-Allow-Credentials', 'true') headers.set('Content-Type', 'application/octet-stream') headers.set('Cache-Control', 'no-cache, no-store, max-age=0, must-revalidate') headers.add('Cache-Control', 'post-check=0, pre-check=0') headers.set('Pragma', 'no-cache') vo = request.headers.get('X-Rucio-VO', default='def') account = request.environ.get('HTTP_X_RUCIO_ACCOUNT', 'webui') auth_scope = request.environ.get('HTTP_X_RUCIO_CLIENT_AUTHORIZE_SCOPE', "") audience = request.environ.get('HTTP_X_RUCIO_CLIENT_AUTHORIZE_AUDIENCE', "") auto = request.environ.get('HTTP_X_RUCIO_CLIENT_AUTHORIZE_AUTO', False) issuer = request.environ.get('HTTP_X_RUCIO_CLIENT_AUTHORIZE_ISSUER', None) polling = request.environ.get('HTTP_X_RUCIO_CLIENT_AUTHORIZE_POLLING', False) refresh_lifetime = request.environ.get('HTTP_X_RUCIO_CLIENT_AUTHORIZE_REFRESH_LIFETIME', None) auto = (auto == 'True' or auto == 'true') polling = (polling == 'True' or polling == 'true') if refresh_lifetime == 'None': refresh_lifetime = None ip = request.headers.get('X-Forwarded-For', default=request.remote_addr) try: kwargs = {'auth_scope': auth_scope, 'audience': audience, 'issuer': issuer, 'auto': auto, 'polling': polling, 'refresh_lifetime': refresh_lifetime, 'ip': ip} result = get_auth_oidc(account, vo=vo, **kwargs) except AccessDenied: return generate_http_error_flask(401, 'CannotAuthenticate', 'Cannot get authentication URL from Rucio Authentication Server for account %(account)s' % locals(), headers=headers) except RucioException as error: return generate_http_error_flask(500, error.__class__.__name__, error.args[0], headers=headers) except Exception as error: logging.exception("Internal Error") return str(error), 500, headers if not result: return generate_http_error_flask(401, 'CannotAuthenticate', 'Cannot get authentication URL from Rucio Authentication Server for account %(account)s' % locals(), headers=headers) headers.set('X-Rucio-OIDC-Auth-URL', result) return '', 200, headers
def get(self): """ .. :quickref: OIDC; Authenticate with OIDC :status 200: OK :status 401: Unauthorized :resheader X-Rucio-OIDC-Auth-URL: User & Rucio OIDC Client specific Authorization URL """ headers = self.get_headers() headers.set('Content-Type', 'application/octet-stream') headers.set('Cache-Control', 'no-cache, no-store, max-age=0, must-revalidate') headers.add('Cache-Control', 'post-check=0, pre-check=0') headers.set('Pragma', 'no-cache') vo = request.headers.get('X-Rucio-VO', default='def') account = request.environ.get('HTTP_X_RUCIO_ACCOUNT', 'webui') auth_scope = request.environ.get('HTTP_X_RUCIO_CLIENT_AUTHORIZE_SCOPE', "") audience = request.environ.get('HTTP_X_RUCIO_CLIENT_AUTHORIZE_AUDIENCE', "") auto = request.environ.get('HTTP_X_RUCIO_CLIENT_AUTHORIZE_AUTO', False) issuer = request.environ.get('HTTP_X_RUCIO_CLIENT_AUTHORIZE_ISSUER', None) polling = request.environ.get('HTTP_X_RUCIO_CLIENT_AUTHORIZE_POLLING', False) refresh_lifetime = request.environ.get('HTTP_X_RUCIO_CLIENT_AUTHORIZE_REFRESH_LIFETIME', None) auto = (auto == 'True' or auto == 'true') polling = (polling == 'True' or polling == 'true') if refresh_lifetime == 'None': refresh_lifetime = None ip = request.headers.get('X-Forwarded-For', default=request.remote_addr) try: kwargs = {'auth_scope': auth_scope, 'audience': audience, 'issuer': issuer, 'auto': auto, 'polling': polling, 'refresh_lifetime': refresh_lifetime, 'ip': ip} result = get_auth_oidc(account, vo=vo, **kwargs) except AccessDenied: return generate_http_error_flask( status_code=401, exc=CannotAuthenticate.__name__, exc_msg=f'Cannot get authentication URL from Rucio Authentication Server for account {account}', headers=headers ) if not result: return generate_http_error_flask( status_code=401, exc=CannotAuthenticate.__name__, exc_msg=f'Cannot get authentication URL from Rucio Authentication Server for account {account}', headers=headers ) headers.set('X-Rucio-OIDC-Auth-URL', result) return '', 200, headers
def oidc_auth(account, issuer, ui_vo=None): """ Open ID Connect Login :param account: Rucio account string :param issuer: issuer key (e.g. xdc, wlcg) as in the idpsecrets.json file :param ui_vo: 3 character string to identify the VO, if None will attempt to deduce it from `account` :returns: rendered final page or a page with error message """ if not account: account = 'webui' if ui_vo is None: all_vos = [vo['vo'] for vo in vo_core.list_vos()] valid_vos = [] for vo in all_vos: if account_exists(account, vo): valid_vos.append(vo) if len(valid_vos) == 0: return RENDERER.problem( ('Cannot find any Rucio account %s at any VO.' % html_escape(account))) elif len(valid_vos) == 1: ui_vo = valid_vos[0] else: vos_with_desc = get_vo_descriptions(valid_vos) return RENDERER.select_login_method(AUTH_ISSUERS, SAML_SUPPORT, vos_with_desc) if not issuer: return RENDERER.problem("Please provide IdP issuer.") kwargs = { 'audience': None, 'auth_scope': None, 'issuer': issuer.lower(), 'auto': True, 'polling': False, 'refresh_lifetime': None, 'ip': None, 'webhome': ctx.realhome + '/oidc_final' } auth_url = auth.get_auth_oidc(account, vo=ui_vo, **kwargs) if not auth_url: return RENDERER.problem( "It was not possible to get the OIDC authentication url from the Rucio auth server. " + "In case you provided your account name, make sure it is known to Rucio." ) # NOQA: W503 return seeother(auth_url)
def GET(self): """ HTTP Success: 200 OK HTTP Error: 401 Unauthorized :param Rucio-Account: Account identifier as a string. :returns: User & Rucio OIDC Client specific Authorization URL as a string. """ header('Access-Control-Allow-Origin', ctx.env.get('HTTP_ORIGIN')) header('Access-Control-Allow-Headers', ctx.env.get('HTTP_ACCESS_CONTROL_REQUEST_HEADERS')) header('Access-Control-Allow-Methods', '*') header('Access-Control-Allow-Credentials', 'true') header('Content-Type', 'application/octet-stream') header('Cache-Control', 'no-cache, no-store, max-age=0, must-revalidate') header('Cache-Control', 'post-check=0, pre-check=0', False) header('Pragma', 'no-cache') vo = ctx.env.get('HTTP_X_RUCIO_VO', 'def') account = ctx.env.get('HTTP_X_RUCIO_ACCOUNT', 'webui') auth_scope = ctx.env.get('HTTP_X_RUCIO_CLIENT_AUTHORIZE_SCOPE', "") audience = ctx.env.get('HTTP_X_RUCIO_CLIENT_AUTHORIZE_AUDIENCE', "") auto = ctx.env.get('HTTP_X_RUCIO_CLIENT_AUTHORIZE_AUTO', False) issuer = ctx.env.get('HTTP_X_RUCIO_CLIENT_AUTHORIZE_ISSUER', None) polling = ctx.env.get('HTTP_X_RUCIO_CLIENT_AUTHORIZE_POLLING', False) refresh_lifetime = ctx.env.get( 'HTTP_X_RUCIO_CLIENT_AUTHORIZE_REFRESH_LIFETIME', None) auto = (auto == 'True' or auto == 'true') polling = (polling == 'True' or polling == 'true') if refresh_lifetime == 'None': refresh_lifetime = None ip = ctx.env.get('HTTP_X_FORWARDED_FOR') if ip is None: ip = ctx.ip try: kwargs = { 'auth_scope': auth_scope, 'audience': audience, 'issuer': issuer, 'auto': auto, 'polling': polling, 'refresh_lifetime': refresh_lifetime, 'ip': ip } result = get_auth_oidc(account, vo=vo, **kwargs) except AccessDenied: raise generate_http_error( 401, 'CannotAuthenticate', 'Cannot get authentication URL from Rucio Authentication Server for account %(account)s' % locals()) except RucioException as error: raise generate_http_error(500, error.__class__.__name__, error.args[0]) except Exception as error: print(format_exc()) raise InternalError(error) if not result: raise generate_http_error( 401, 'CannotAuthenticate', 'Cannot get authentication URL from Rucio Authentication Server for account %(account)s' % locals()) header('X-Rucio-OIDC-Auth-URL', result) return str()