示例#1
0
文件: ssl.py 项目: cern-fts/fts-rest
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
示例#2
0
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
示例#3
0
        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
示例#4
0
    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