コード例 #1
0
    def _get_authentication_cookie(self, security_token, federated=False):
        """Retrieve auth cookie from STS

        :type federated: bool
        :type security_token: str
        """
        logger = self.logger(self._get_authentication_cookie.__name__)

        session = requests.session()
        logger.debug_secrets("session: %s\nsession.post(%s, data=%s)", session,
                             self._sts_profile.signin_page_url, security_token)
        if not federated:
            session.post(
                self._sts_profile.signin_page_url,
                data=security_token,
                headers={'Content-Type': 'application/x-www-form-urlencoded'})
        else:
            idcrl_endpoint = "https://{}/_vti_bin/idcrl.svc/".format(
                self._sts_profile.tenant)
            session.get(idcrl_endpoint,
                        headers={
                            'User-Agent': 'Office365 Python Client',
                            'X-IDCRL_ACCEPTED': 't',
                            'Authorization':
                            'BPOSIDCRL {0}'.format(security_token)
                        })
        logger.debug_secrets("session.cookies: %s", session.cookies)
        cookies = requests.utils.dict_from_cookiejar(session.cookies)
        logger.debug_secrets("cookies: %s", cookies)
        if not is_valid_auth_cookies(cookies):
            self.error = "An error occurred while retrieving auth cookies from {0}".format(
                self._sts_profile.signin_page_url)
            logger.error(self.error)
            raise ValueError(self.error)
        return cookies
コード例 #2
0
    def process_service_token_response(self, response):
        logger = self.logger(self.process_service_token_response.__name__)
        logger.debug_secrets('response: %s\nresponse.content: %s', response,
                             response.content)

        xml = ElementTree.fromstring(response.content)
        ns_prefixes = {
            'S':
            '{http://www.w3.org/2003/05/soap-envelope}',
            'psf':
            '{http://schemas.microsoft.com/Passport/SoapServices/SOAPFault}',
            'wst':
            '{http://schemas.xmlsoap.org/ws/2005/02/trust}',
            'wsse':
            '{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}'
        }
        logger.debug_secrets("ns_prefixes: %s", ns_prefixes)

        # check for errors
        if xml.find('{0}Body/{0}Fault'.format(ns_prefixes['S'])) is not None:
            error = xml.find(
                '{0}Body/{0}Fault/{0}Detail/{1}error/{1}internalerror/{1}text'.
                format(ns_prefixes['S'], ns_prefixes['psf']))
            self.error = 'An error occurred while retrieving token: {0}'.format(
                error.text)
            logger.error(self.error)
            return None

        # extract token
        token = xml.find(
            '{0}Body/{1}RequestSecurityTokenResponse/{1}RequestedSecurityToken/{2}BinarySecurityToken'
            .format(ns_prefixes['S'], ns_prefixes['wst'], ns_prefixes['wsse']))
        logger.debug_secrets("token: %s", token)
        return token.text
コード例 #3
0
    def acquire_authentication_cookie(self, options):
        """Retrieve SPO auth cookie"""
        #logger = self.logger(self.acquire_authentication_cookie.__name__)
        logger.info("Executing acquire_authentication_cookie")

        # dwang_DEBUG
        # url = options['endpoint']
        # url = options['msftlogin']

        # session = requests.session()
        # logger.debug_secrets("session: %s\nsession.post(%s, data=%s)", session, url, self.token)
        # logger.info("session: %s\nsession.post(%s, data=%s)" % (session, url, self.token))
        # session.post(url, data=self.token, headers={'Content-Type': 'application/x-www-form-urlencoded'})
        # logger.debug_secrets("session.cookies: %s", session.cookies)
        # logger.info("session.cookies: %s" % session.cookies)
        # cookies = requests.utils.dict_from_cookiejar(session.cookies)
        # logger.debug_secrets("cookies: %s", cookies)

        response = self.cookieRequest.post(
            self.msftlogin,
            self.token,
            contentType='application/x-www-form-urlencoded')
        logger.info("After calling cookie request post")
        logger.info(str(response.getStatus()))
        # logger.info(str(response.getResponse())) # Unicode problems # dwang_DEBUG
        cookies = {}
        # logger.info("cookies: %s" % str(cookies))
        if 'FedAuth' in cookies and 'rtFa' in cookies:
            self.FedAuth = cookies['FedAuth']
            self.rtFa = cookies['rtFa']
            return True
        self.error = "An error occurred while retrieving auth cookies"
        logger.error(self.error)
        return False
コード例 #4
0
    def acquire_service_token_from_adfs(self, adfs_url, username, password):
        logger = self.logger(self.acquire_service_token_from_adfs.__name__)
        payload = self._prepare_request_from_template(
            'FederatedSAML.xml', {
                'auth_url': adfs_url,
                'username': username,
                'password': password,
                'message_id': str(uuid.uuid4()),
                'created': self.__sts_profile.created,
                'expires': self.__sts_profile.expires,
                'issuer': self.__sts_profile.federationTokenIssuer
            })
        response = requests.post(
            adfs_url,
            data=payload,
            headers={'Content-Type': 'application/soap+xml; charset=utf-8'})
        try:
            xml = ElementTree.fromstring(response.content)
            # 1.find assertion
            assertion_node = xml.find(
                '{0}Body/{1}RequestSecurityTokenResponse/{1}RequestedSecurityToken/{2}Assertion'
                .format(self.__ns_prefixes['s'], self.__ns_prefixes['wst'],
                        self.__ns_prefixes['saml']))
            if assertion_node is None:
                self.error = 'Cannot get security assertion for user {0} from {1}'.format(
                    self.__username, adfs_url)
                logger.error(self.error)
                return None
            # 2. prepare & submit token request
            self.__sts_profile.signInPage = '_vti_bin/idcrl.svc'
            self.__sts_profile.securityTokenServicePath = 'rst2.srf'
            template = self._prepare_request_from_template(
                'RST2.xml', {
                    'auth_url':
                    self.__sts_profile.authorityUrl,
                    'serviceTokenUrl':
                    self.__sts_profile.security_token_service_url
                })
            template_xml = ElementTree.fromstring(template)
            security_node = template_xml.find('{0}Header/{1}Security'.format(
                self.__ns_prefixes['s'], self.__ns_prefixes['wsse']))

            security_node.insert(1, assertion_node)
            payload = ElementTree.tostring(template_xml).decode()
            # 3. get token
            response = requests.post(
                self.__sts_profile.security_token_service_url,
                data=payload,
                headers={'Content-Type': 'application/soap+xml'})
            token = self._process_service_token_response(response)
            logger.debug_secrets('security token: %s', token)
            return token
        except ElementTree.ParseError as e:
            self.error = 'An error occurred while parsing the server response: {}'.format(
                e)
            logger.error(self.error)
            return None
コード例 #5
0
    def acquire_service_token_from_adfs(self, adfs_url, username, password):
        logger = self.logger(self.acquire_service_token_from_adfs.__name__)

        now = datetime.now(tz=timezone.utc)
        created = now.astimezone(timezone.utc).isoformat('T')[:-9] + 'Z'
        expires = (now + timedelta(minutes=10)).astimezone(
            timezone.utc).isoformat('T')[:-9] + 'Z'

        payload = self._prepare_request_from_template(
            'FederatedSAML.xml', {
                'auth_url': adfs_url,
                'message_id': str(uuid.uuid4()),
                'username': username,
                'password': password,
                'created': created,
                'expires': expires,
                'issuer': self.__sts_profile.federationTokenIssuer
            })

        response = requests.post(
            adfs_url,
            data=payload,
            headers={'Content-Type': 'application/soap+xml; charset=utf-8'})
        dom = minidom.parseString(response.content.decode())
        assertion_node = dom.getElementsByTagNameNS(
            "urn:oasis:names:tc:SAML:1.0:assertion", 'Assertion')[0].toxml()

        try:
            self.tenant = urlparse(self.__sts_profile.authorityUrl).netloc

            payload = self._prepare_request_from_template(
                'RST2.xml', {
                    'auth_url': self.tenant,
                    'serviceTokenUrl':
                    self.__sts_profile.security_token_service_url,
                    'assertion_node': assertion_node
                })

            # 3. get token
            response = requests.post(
                self.__sts_profile.security_token_service_url,
                data=payload,
                headers={'Content-Type': 'application/soap+xml'})
            token = self._process_service_token_response(response)
            logger.debug_secrets('security token: %s', token)
            return token
        except ElementTree.ParseError as e:
            self.error = 'An error occurred while parsing the server response: {}'.format(
                e)
            logger.error(self.error)
            return None
コード例 #6
0
    def _acquire_service_token_from_adfs(self, adfs_url):
        logger = self.logger(self._acquire_service_token_from_adfs.__name__)

        payload = self._prepare_request_from_template(
            'FederatedSAML.xml', {
                'auth_url': adfs_url,
                'message_id': str(uuid.uuid4()),
                'username': self._username,
                'password': self._password,
                'created': self._sts_profile.created,
                'expires': self._sts_profile.expires,
                'issuer': self._sts_profile.tokenIssuer
            })

        response = requests.post(
            adfs_url,
            data=payload,
            headers={'Content-Type': 'application/soap+xml; charset=utf-8'})
        dom = minidom.parseString(response.content.decode())
        assertion_node = dom.getElementsByTagNameNS(
            "urn:oasis:names:tc:SAML:1.0:assertion", 'Assertion')[0].toxml()

        try:
            payload = self._prepare_request_from_template(
                'RST2.xml', {
                    'auth_url': self._sts_profile.tenant,
                    'serviceTokenUrl':
                    self._sts_profile.security_token_service_url,
                    'assertion_node': assertion_node
                })

            # 3. get security token
            response = requests.post(
                self._sts_profile.security_token_service_url,
                data=payload,
                headers={'Content-Type': 'application/soap+xml'})
            token = self._process_service_token_response(response)
            logger.debug_secrets('security token: %s', token)
            return token
        except ElementTree.ParseError as e:
            self.error = 'An error occurred while parsing the server response: {}'.format(
                e)
            logger.error(self.error)
            return None
コード例 #7
0
    def acquire_authentication_cookie(self, options):
        """Retrieve SPO auth cookie"""
        logger = self.logger(self.acquire_authentication_cookie.__name__)

        url = options['endpoint']

        session = requests.session()
        logger.debug_secrets("session: %s\nsession.post(%s, data=%s)", session, url, self.token)
        session.post(url, data=self.token, headers={'Content-Type': 'application/x-www-form-urlencoded'})
        logger.debug_secrets("session.cookies: %s", session.cookies)
        cookies = requests.utils.dict_from_cookiejar(session.cookies)
        logger.debug_secrets("cookies: %s", cookies)
        if 'FedAuth' in cookies and 'rtFa' in cookies:
            self.FedAuth = cookies['FedAuth']
            self.rtFa = cookies['rtFa']
            return True
        self.error = "An error occurred while retrieving auth cookies"
        logger.error(self.error)
        return False
コード例 #8
0
    def get_authentication_cookie(self):
        """Acquire authentication cookie
        """
        logger = self.logger(self.ensure_authentication_cookie.__name__)
        logger.debug('get_authentication_cookie called')

        try:
            logger.debug("Acquiring Access Token..")
            user_realm = self._get_user_realm()
            if user_realm.IsFederated:
                token = self._acquire_service_token_from_adfs(
                    user_realm.STSAuthUrl)
            else:
                token = self._acquire_service_token()
            return self._get_authentication_cookie(token,
                                                   user_realm.IsFederated)
        except requests.exceptions.RequestException as e:
            logger.error(e.response.text)
            self.error = "Error: {}".format(e)
            raise ValueError(e.response.text)
コード例 #9
0
 def _acquire_authentication_cookie(self, security_token, federated=False):
     """Retrieve auth cookie from STS"""
     logger = self.logger(self._acquire_authentication_cookie.__name__)
     session = requests.session()
     logger.debug_secrets("session: %s\nsession.post(%s, data=%s)", session,
                          self.__sts_profile.signin_page_url,
                          security_token)
     if not federated:
         self._auth_cookies['FedAuth'] = None
         self._auth_cookies['rtFa'] = None
         session.post(
             self.__sts_profile.signin_page_url,
             data=security_token,
             headers={'Content-Type': 'application/x-www-form-urlencoded'})
     else:
         self._auth_cookies['SPOIDCRL'] = None
         session.head(self.__sts_profile.signin_page_url,
                      headers={
                          'User-Agent':
                          'Office365 Python Client',
                          'X-IDCRL_ACCEPTED':
                          't',
                          'Authorization':
                          'BPOSIDCRL {0}'.format(security_token),
                          'Content-Type':
                          'application/x-www-form-urlencoded'
                      })
     logger.debug_secrets("session.cookies: %s", session.cookies)
     cookies = requests.utils.dict_from_cookiejar(session.cookies)
     logger.debug_secrets("cookies: %s", cookies)
     if not cookies:
         self.error = "An error occurred while retrieving auth cookies from {0}".format(
             self.__sts_profile.signin_page_url)
         logger.error(self.error)
         return False
     for name in self._auth_cookies.keys():
         self._auth_cookies[name] = cookies[name]
     return True
コード例 #10
0
    def _process_service_token_response(self, response):
        logger = self.logger(self._process_service_token_response.__name__)
        logger.debug_secrets('response: %s\nresponse.content: %s', response,
                             response.content)

        try:
            xml = ElementTree.fromstring(response.content)
        except ElementTree.ParseError as e:
            self.error = 'An error occurred while parsing the server response: {}'.format(
                e)
            logger.error(self.error)
            return None

        # check for errors
        if xml.find('{0}Body/{0}Fault'.format(
                self.__ns_prefixes['s'])) is not None:
            error = xml.find(
                '{0}Body/{0}Fault/{0}Detail/{1}error/{1}internalerror/{1}text'.
                format(self.__ns_prefixes['s'], self.__ns_prefixes['psf']))
            if error is None:
                self.error = 'An error occurred while retrieving token from XML response.'
            else:
                self.error = 'An error occurred while retrieving token from XML response: {0}'.format(
                    error.text)
            logger.error(self.error)
            return None

        # extract token
        token = xml.find(
            '{0}Body/{1}RequestSecurityTokenResponse/{1}RequestedSecurityToken/{2}BinarySecurityToken'
            .format(self.__ns_prefixes['s'], self.__ns_prefixes['wst'],
                    self.__ns_prefixes['wsse']))
        if token is None:
            self.error = 'Cannot get binary security token for from {0}'.format(
                self.__sts_profile.security_token_service_url)
            logger.error(self.error)
            return None
        logger.debug_secrets("token: %s", token)
        return token.text