def do_authentication(credentials, env, config=None): """ Try with a proxy or certificate, via mod_gridsite or mod_ssl """ got_creds = _mod_gridsite_authn(credentials, env) or _mod_ssl_authn( credentials, env) if not got_creds: return False # If more than one dn, pick first one if len(credentials.dn) > 0: credentials.user_dn = credentials.dn[0] # Generate the delegation ID if credentials.user_dn is not None: credentials.delegation_id = generate_delegation_id( credentials.user_dn, credentials.voms_cred) # If no vo information is available, build a 'virtual vo' for this user if not credentials.vos and credentials.user_dn: credentials.vos.append(build_vo_from_dn(credentials.user_dn)) credentials.method = 'certificate' # If the user's DN matches the host DN, then grant all host_dn = env.get('SSL_SERVER_S_DN', None) if host_dn and host_dn == credentials.user_dn: credentials.is_root = True else: if '/' not in str(host_dn): host_dn = str(host_dn).replace(',', '/') host_dn = '/' + '/'.join(reversed(str(host_dn).split('/'))) if host_dn == credentials.user_dn: credentials.is_root = True return True
def do_authentication(credentials, env): """ Try with a proxy or certificate, via mod_gridsite or mod_ssl """ got_creds = _mod_gridsite_authn(credentials, env) or _mod_ssl_authn(credentials, env) if not got_creds: return False # If more than one dn, pick first one if len(credentials.dn) > 0: credentials.user_dn = credentials.dn[0] # Generate the delegation ID if credentials.user_dn is not None: credentials.delegation_id = generate_delegation_id(credentials.user_dn, credentials.voms_cred) # If no vo information is available, build a 'virtual vo' for this user if not credentials.vos and credentials.user_dn: credentials.vos.append(build_vo_from_dn(credentials.user_dn)) credentials.method = 'certificate' return True
log.info("Trying to verify the proxy") if not ctx.validate_certificate(chain): log.info("Certificate verification failed") raise InvalidCredentials("Certificate verification failed") elif not ctx.validate_certificate(x509): log.info("Certificate verification failed") raise InvalidCredentials("Certificate verification failed") credentials.user_dn = certDN if proxy: credentials.dn.append(proxyDN) credentials.dn.append(credentials.user_dn) if 'SSL_CLIENT_S_DN' in env: credentials.dn.append(urllib.unquote_plus(env['SSL_CLIENT_S_DN'])) if proxy: voms_client = VomsClient(chain_pem) log.info("proxy path: " + voms_client.proxy_path) fqans = voms_client.get_proxy_fqans() for fqan in fqans: vo = vo_from_fqan(fqan) credentials.voms_cred.append(fqan) if vo not in credentials.vos and vo: credentials.vos.append(vo) # Generate the delegation ID credentials.delegation_id = generate_delegation_id(credentials.user_dn, credentials.voms_cred) # If no vo information is available, build a 'virtual vo' for this user if not credentials.vos: credentials.vos.append(build_vo_from_dn(credentials.user_dn)) credentials.method = 'certificate' return True
def validate_access_token(self, access_token, authorization): """ Validate access token offline or online Description of the algorithm: - Validate access token offline (using cached keys) or online (using introspection RFC 7662). - If a credential already exists in the DB and has not expired, the new token is discarded and the old credential is used. - If a credential already exists in the DB but has expired, delete it. - If there's no credential, Instrospect the token to get additional information (if not done before). Then, exchange the access token with a refresh token. Store both tokens in the DB. :param access_token: :param authorization: attribute .is_valid is set to True if validation successful """ authorization.is_valid = False if self._should_validate_offline(): valid, credential = self._validate_token_offline(access_token) else: valid, credential = self._validate_token_online(access_token) if not valid: log.warning("Access token provided is not valid") return # Check if a credential already exists in the DB credential_db = Session.query(Credential).filter(Credential.dn == credential['sub']).first() if credential_db and credential_db.expired(): log.debug("credential_db_has_expired") Session.delete(credential_db) Session.commit() credential_db = None if not credential_db: if self._should_validate_offline(): log.debug("offline and not in db") # Introspect to obtain additional information valid, credential = self._validate_token_online(access_token) if not valid: log.debug("Access token provided is not valid") return # Store credential in DB log.debug("Store credential in DB") dlg_id = generate_delegation_id(credential['sub'], "") try: if 'wlcg' in credential['iss']: # Hardcoded scope and audience for wlcg tokens. To change once the wlcg standard evolves scope = 'offline_access openid storage.read:/ storage.modify:/ wlcg.groups' audience = 'https://wlcg.cern.ch/jwt/v1/any' access_token, refresh_token = oidc_manager.generate_token_with_scope(credential['iss'], access_token, scope, audience, ) else: refresh_token = oidc_manager.generate_refresh_token(credential['iss'], access_token) except Exception: return credential_db = self._save_credential(dlg_id, credential['sub'], str(access_token) + ':' + str(refresh_token), self._generate_voms_attrs(credential), datetime.utcfromtimestamp(credential['exp'])) authorization.is_oauth = True authorization.token = credential_db.proxy.split(':')[0] authorization.dlg_id = credential_db.dlg_id authorization.expires_in = credential_db.termination_time - datetime.utcnow() if authorization.expires_in > timedelta(seconds=0): authorization.credentials = self._get_credentials(credential_db.dlg_id) if authorization.credentials: authorization.is_valid = True