Esempio n. 1
0
 def test_perform_service_validate_separate_url(self):
     cas_client = CASClient('https://dummy.url',
                            validate_url='https://validate.url')
     assert not cas_client.headers
     with mock.patch('cas_client.CASClient._perform_get') as m:
         m.return_value = self.response_text
         response = cas_client.perform_service_validate(
             ticket='FOO',
             service_url='BAR',
         )
         m.assert_called_once_with(
             'https://validate.url/cas/serviceValidate?ticket=FOO&service=BAR',
             headers=None)
     self.assertTrue(response.success)
     self.assertEqual(
         response.attributes, {
             u'i2a2characteristics': u'0,3592,2000',
             u'puid': u'0012345678',
             u'firstname': u'Jeffrey A',
             u'lastname': u'Ott',
             u'fullname': u'Jeffrey A Ott',
             u'email': u'*****@*****.**',
         })
     self.assertEqual(response.response_type, 'authenticationSuccess')
     self.assertEqual(response.user, 'jott')
Esempio n. 2
0
    def test_perform_service_validate_headers_init(self):
        class MockResponse(object):
            text = self.response_text

        cas_client = CASClient('https://dummy.url', headers={'baz': 'quux'})
        assert cas_client.headers == {'baz': 'quux'}
        with mock.patch('requests.get') as m:
            m.return_value = MockResponse()
            cas_client.perform_service_validate(
                ticket='FOO',
                service_url='BAR',
            )
        m.assert_called_with(
            'https://dummy.url/cas/serviceValidate?ticket=FOO&service=BAR',
            headers={'baz': 'quux'},
            verify=False,
        )
Esempio n. 3
0
class CASAuthProvider(AuthProvider):
    """Provides authentication using CAS

    The type name to instantiate this provider is *cas*.
    """
    def __init__(self, *args, **kwargs):
        super(CASAuthProvider, self).__init__(*args, **kwargs)
        self.settings.setdefault('callback_uri',
                                 '/cas_auth/{}'.format(self.name))
        if not self.settings.get('cas_url_base'):
            raise MultipassException(
                "`cas_url_base` must be specified in the provider settings")
        self.cas_client = CASClient(self.settings['cas_url_base'],
                                    auth_prefix='')
        self.cas_endpoint = '_flaskmultipass_cas_' + self.name
        current_app.add_url_rule(self.settings['callback_uri'],
                                 self.cas_endpoint,
                                 self._authorize_callback,
                                 methods=('GET', 'POST'))

    @property
    def cas_callback_url(self):
        return request.url_root + self.settings['callback_uri']

    def initiate_external_login(self):
        cas_login_url = self.cas_client.get_login_url(
            service_url=self.cas_callback_url)
        return redirect(cas_login_url)

    def process_logout(self, return_url):
        cas_logout_url = self.cas_client.get_logout_url(
            service_url=self.cas_callback_url)
        return redirect(cas_logout_url)

    def _make_auth_info(self, resp):
        return AuthInfo(self, token=resp[self.settings['token_field']])

    @login_view
    def _authorize_callback(self):
        ticket = request.args.get('ticket')

        if not ticket:
            raise AuthenticationFailed('ticket is not provided')

        cas_response = self.cas_client.perform_service_validate(
            ticket=ticket,
            service_url=self.cas_callback_url,
        )

        if cas_response and cas_response.success:
            auth_info = cas_response.attributes
            auth_info['_username'] = cas_response.user
            return self.multipass.handle_auth_success(
                AuthInfo(self, **auth_info))

        raise AuthenticationFailed("CAS result: Access denied")
Esempio n. 4
0
    def get(self, request, *args):
        # 统一身份认证登录
        ticket = request.GET.get('ticket')
        cas_url = 'https://passport.ustc.edu.cn'
        app_login_url = 'http://home.ustc.edu.cn/~via'
        cas_client = CASClient(cas_url, auth_prefix='')
        if ticket:
            try:
                cas_response = cas_client.perform_service_validate(
                    ticket=ticket,
                    service_url=app_login_url,
                )
            except Exception:
                # CAS server is currently broken, try again later.
                return Response('CAS server is currently broken, try again later.', status.HTTP_503_SERVICE_UNAVAILABLE)
            if cas_response and cas_response.success:
                student_id = cas_response.user
                try:
                    user = User.objects.get(student_id=student_id)
                    # request.session['username'] = user.username
                    # request.session['userid'] = user.id
                    # request.session['isadmin'] = user.is_superuser
                    login(request, user)
                except:
                    gid = cas_response.data.get('attributes', {}).get('gid')
                    username = str(gid)
                    
                    while True:
                        try:
                            user = {'username':username, 'student_id':student_id, 'password':student_id}
                            serializer = UserSerializer(data=user)
                            serializer.is_valid(True)
                            serializer.save()
                            user = User.objects.get(student_id=student_id)
                            # request.session['username'] = user.username
                            # request.session['userid'] = user.id
                            # request.session['isadmin'] = user.is_superuser
                            login(request, user)
                            break
                        except Exception:
                            # import sys
                            # exc_type, exc_obj, exc_tb = sys.exc_info()
                            # print(f"{exc_type.__name__}: {exc_obj}")
                            username = "".join(random.choices('0123456789abcdefghijklmnopqrstuvwxyz@.+-_', k=10))

                # rep = Response('OK', status.HTTP_200_OK)        # 更换为 rep = redirect('home')
                rep = redirect('http://202.38.75.113/')
                rep.set_cookie('userid', user.id)
                return rep
        cas_login_url = cas_client.get_login_url(service_url=app_login_url)
        return redirect(cas_login_url)
Esempio n. 5
0
 def test_perform_service_validate(self):
     cas_client = CASClient("dummy.url")
     cas_client._request_cas_response = lambda url: self.response_text
     response = cas_client.perform_service_validate(ticket="FOO", service_url="BAR")
     self.assertTrue(response.success)
     self.assertEqual(
         response.attributes,
         {
             u"i2a2characteristics": u"0,3592,2000",
             u"puid": u"0012345678",
             u"firstname": u"Jeffrey A",
             u"lastname": u"Ott",
             u"fullname": u"Jeffrey A Ott",
             u"email": u"*****@*****.**",
         },
     )
     self.assertEqual(response.response_type, "authenticationSuccess")
     self.assertEqual(response.user, "jott")
Esempio n. 6
0
def cas():
    """Handles the login page, logging a user in on correct authentication."""

    #CAS client init
    cas_client = CASClient(app.config['CAS_SERVER_URL'],
                           app.config['CAS_SERVICE_URL'],
                           verify_certificates=True)

    #SLO
    if request.method == 'POST' and session.get(
            'cas_ticket') is not None and 'logoutRequest' in request.form:
        #check the verify the ticket to prevent cross orign attacks
        message = cas_client.parse_logout_request(
            request.form.get('logoutRequest'))
        if message.get('session_index', None) == session.get('cas_ticket'):
            cortex.lib.user.clear_session()
            return ('', 200)

        abort(400)

    # If the user is already logged in, just redirect them to their dashboard
    if cortex.lib.user.is_logged_in():
        return redirect(url_for('dashboard'))

    ticket = request.args.get('ticket', None)
    if ticket is not None:
        try:
            cas_response = cas_client.perform_service_validate(ticket=ticket)
        except Exception:
            return root()
        if cas_response and cas_response.success:
            try:
                # keep the ticket for SLO
                session['cas_ticket'] = ticket
                return cortex.lib.user.logon_ok(
                    cas_response.attributes.get('uid'))
            except KeyError:
                # required user attributes not returned
                flash(
                    "CAS SSO authentication successful but missing required information consider using LDAP authentication",
                    'alert-warning')
                return root()

    return redirect(cas_client.get_login_url())