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")
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)
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())
def test_get_login_url(self): cas_client = CASClient("dummy.url") service_url = "app.url" url = cas_client.get_login_url(service_url=service_url) self.assertEqual(url, "dummy.url/cas/login?service=app.url")
def test_get_login_url(self): cas_client = CASClient('https://dummy.url') service_url = 'https://app.url' url = cas_client.get_login_url(service_url=service_url) self.assertEqual( url, 'https://dummy.url/cas/login?service=https://app.url')