def callback(): """ Callback method required by Google's OAuth 2.0 """ if current_user is not None and current_user.is_authenticated: return redirect(url_for('index')) if 'error' in request.args: if request.args.get('error') == 'access_denied': return 'You denied access.' return 'Error encountered.' if 'code' not in request.args and 'state' not in request.args: return redirect(url_for('login')) else: google = get_google_auth(state=session['oauth_state']) try: token = google.fetch_token(Auth.TOKEN_URI, client_secret=Auth.CLIENT_SECRET, authorization_response=request.url) except HTTPError: return 'HTTPError occurred.' # Testing the token verification step. try: # jwt = verify_id_token(token['id_token'], Auth.CLIENT_ID) verify_id_token(token['id_token'], Auth.CLIENT_ID) except AppIdentityError: return 'Could not verify token.' # Check if you have the appropriate domain # Commenting this section out to let anyone with # a google account log in. # if 'hd' not in jwt or jwt['hd'] != 'ucsc.edu': # flash('You must login with a ucsc.edu account. \ # Please try again.', 'error') # return redirect(url_for('index')) google = get_google_auth(token=token) resp = google.get(Auth.USER_INFO) if resp.status_code == 200: user_data = resp.json() email = user_data['email'] user = User.query.filter_by(email=email).first() if user is None: user = User() user.email = email user.name = user_data['name'] print(token) user.tokens = json.dumps(token) user.access_token = token['access_token'] user.avatar = user_data['picture'] user.redwood_token = get_redwood_token(user) db.session.add(user) db.session.commit() login_user(user) # Empty flashed messages get_flashed_messages() # Set a new success flash message flash('You are now logged in!', 'success') return redirect(url_for('index')) return 'Could not fetch your information.'
def test_verify_id_token_with_certs_uri_fails(self): jwt = self._create_signed_jwt() test_email = '*****@*****.**' http = HttpMockSequence([ ({'status': '404'}, datafile('certs.json')), ]) with self.assertRaises(VerifyJwtTokenError): verify_id_token(jwt, test_email, http=http)
def test_verify_id_token_with_certs_uri_fails(self): jwt = self._create_signed_jwt() test_email = '*****@*****.**' http = http_mock.HttpMock(headers={'status': http_client.NOT_FOUND}, data=datafile('certs.json')) with self.assertRaises(client.VerifyJwtTokenError): client.verify_id_token(jwt, test_email, http=http) # Verify mocks. self._verify_http_mock(http)
def test_verify_id_token_with_certs_uri_fails(self): jwt = self._create_signed_jwt() test_email = '*****@*****.**' http = HttpMockSequence([ ({ 'status': '404' }, datafile('certs.json')), ]) with self.assertRaises(client.VerifyJwtTokenError): client.verify_id_token(jwt, test_email, http=http)
def test_verify_id_token_with_certs_uri_fails(self): jwt = self._create_signed_jwt() test_email = '*****@*****.**' http = http_mock.HttpMock( headers={'status': http_client.NOT_FOUND}, data=datafile('certs.json')) with self.assertRaises(client.VerifyJwtTokenError): client.verify_id_token(jwt, test_email, http=http) # Verify mocks. self._verify_http_mock(http)
def login(request, access_token): """ Validate a google access token and retrieve user's email. Returns ------- user : str User email. permissions : list List of permissions that the user has. """ try: idinfo = client.verify_id_token(access_token, request.registry.GOOGLE_WEB_CLIENT_ID) if idinfo['aud'] not in [request.registry.GOOGLE_WEB_CLIENT_ID]: raise crypt.AppIdentityError("Unrecognized client.") if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: raise crypt.AppIdentityError("Wrong issuer.") except crypt.AppIdentityError as e: return request.error('token', e.message, 400) email = idinfo.get('email') if email is None: return request.error('google_data', "Could not find Google email") request.response.headers.extend(remember(request, email)) return { 'user': email, 'permissions': request.user_principals(email), }
def google_info_from_token(token): idinfo = client.verify_id_token(token, settings.GOOGLE_CLIENT_ID) if idinfo['aud'] != settings.GOOGLE_CLIENT_ID: raise crypt.AppIdentityError('aud dont match') if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: raise crypt.AppIdentityError("Wrong issuer.") return idinfo
def getUserEmail(token): jwt = getJwt(token) user_info = verify_id_token(\ id_token=jwt, \ audience=AUD) return user_info['email']
def resolve_google_oauth(request): # token should be passed as an object {'ID_Token' : id_token } # to this view token = request.data.get('ID_Token') CLIENT_ID = os.environ.get('CLIENT_ID') token.replace(" ", "") try: idinfo = client.verify_id_token(token, CLIENT_ID) if 'hd' not in idinfo: raise AuthenticationFailed('Sorry, only Andelans can sign in') if idinfo['hd'] != 'andela.com': raise AuthenticationFailed('Sorry, only Andelans can sign in') if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: raise PermissionDenied('Wrong Issuer') if idinfo['email_verified'] == 'True' and idinfo['aud'] == CLIENT_ID: return idinfo except crypt.AppIdentityError: raise PermissionDenied('Invalid Token') return idinfo
def verify_admin(): if DEBUG: return token = request.cookies.get('starbook-token') or (request.json and request.json.pop('starbook-token')) google_email = client.verify_id_token(token, CLIENT_ID)['email'] if google_email not in ADMINS: return jsonify({'error': 'You are not allowed to do that'}), 403
def authenticate(self, token=None): try: idinfo = client.verify_id_token(token, settings.CLIENT_ID) # If multiple clients access the backend server: if idinfo['iss'] not in [ 'accounts.google.com', 'https://accounts.google.com' ]: raise crypt.AppIdentityError("Wrong issuer.") return None ''' if idinfo['aud'] not in [ANDROID_CLIENT_ID, IOS_CLIENT_ID, WEB_CLIENT_ID]: raise crypt.AppIdentityError("Unrecognized client.") if idinfo['hd'] != APPS_DOMAIN_NAME: raise crypt.AppIdentityError("Wrong hosted domain.") ''' except crypt.AppIdentityError: # Invalid token raise crypt.AppIdentityError("Invalid token.") return None userid = idinfo['sub'] print(idinfo.items()) try: user = User.objects.get(username=userid) except User.DoesNotExist: user = User(username=userid, email=idinfo['email'], first_name=idinfo['given_name'], last_name=idinfo['family_name']) user.set_unusable_password() user.save() student = Student(user=user) student.save() return user
def verify_google_token(): token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6IjgwNDhmNDQ3YzVjNmRiZGI4ODIwOTYyOTJmYTFiNzk2ZWUzZGMyMTUifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhdWQiOiI4OTIzMTQ4NjIzMzQtcDA4OHVzNnNmY2NvNjhtdWQ1dmJsMnRnODY2dDRxZDAuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMDA2NDQzODQzNTIzNTk4MzMyNDIiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXpwIjoiODkyMzE0ODYyMzM0LW1uazBqZm9ydnFzMGhyYXVsOWE0bTJtdXBhNDdvZGZqLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiZW1haWwiOiJhbGV4YnVpY2VzY3VAZ21haWwuY29tIiwiaWF0IjoxNDQ3MjU0NzE0LCJleHAiOjE0NDcyNTgzMTQsInBpY3R1cmUiOiJodHRwczovL2xoNC5nb29nbGV1c2VyY29udGVudC5jb20vLUItUGptaXlDZWs0L0FBQUFBQUFBQUFJL0FBQUFBQUFBRjRjL21nYk1ndlJfbFhFL3M5Ni1jL3Bob3RvLmpwZyIsImxvY2FsZSI6ImVuIiwibmFtZSI6IkFsZXhhbmRydSBCdWljZXNjdSIsImdpdmVuX25hbWUiOiJBbGV4YW5kcnUiLCJmYW1pbHlfbmFtZSI6IkJ1aWNlc2N1In0.hVMhMMvLcmMRVrVaG0-zuqJhq_bm6VZ-YVe8ygK1p0Z4Wb46yzhSKu7HFDuGJ6dIbS5yM88LH9yaK-3AUCGdElVSjV3bochZR302xYSNjtT2UC70F_tRLaY5KJiA-6e7bPHfEdljgBhrwaspXxV-sVeCUj6nBW5j2UoJZD2tMWHZzfUlXs8_42UEQ_yqzNQ5BEiGZ2LzW61-6gHIOVuazNAh6Pyly4A6-jycHoMthk2d-wwOdJ6ITMcTdPTDiR52SsQbDMJIDz330yYAp_ct5dFYZsvrwqimy1uibysQw7iQuO7MVEt6p1IY2IYkNtJd1N5J9oQx42-9wBJMGXmtQw' CLIENT_ID = 'insert_client_id_here.apps.googleusercontent.com' ANDROID_CLIENT_ID = 'insert_android_client_id_here.apps.googleusercontent.com' WEB_CLIENT_ID = 'insert_web_client_id_here.apps.googleusercontent.com' if cache.get(token) != None: print 'From cache:', cache.get(token) # print 'time:', cache.get(token)['exp'], current_milli_time() return 'From cache:\n ' + ', '.join("%s=%r" % (key,val) for (key,val) in cache.get(token).iteritems()) else: # (Receive token by HTTPS POST) try: idinfo = client.verify_id_token(token, CLIENT_ID) # If multiple clients access the backend server: if idinfo['aud'] not in [ANDROID_CLIENT_ID, WEB_CLIENT_ID]: raise crypt.AppIdentityError("Unrecognized client.") if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: raise crypt.AppIdentityError("Wrong issuer.") userid = idinfo['sub'] cache.set(token, idinfo, idinfo['exp'] - current_milli_time()) print 'Not from cache', idinfo return 'Not from cache:\n ' + ', '.join("%s=%r" % (key,val) for (key,val) in idinfo.iteritems()) except crypt.AppIdentityError: # Invalid token print 'Invalid Token' return 'Invalid Token'
def login_google_callback(request): url = 'https://www.googleapis.com/oauth2/v3/token?code=' url += request.GET.get('code') url += '&client_id=' url += settings.GA_CLIENT_ID url += '&client_secret=' url += settings.GA_CLIENT_SECRET url += '&redirect_uri=' url += request.build_absolute_uri(reverse('login_google_callback')) url += '&grant_type=authorization_code' r = requests.post(url) jwt = verify_id_token(r.json().get('id_token'), settings.GA_CLIENT_ID) email = jwt.get('email').lower() try: user = User.objects.get(email=email) except User.DoesNotExist: user = User(email=email) user.save() user.backend = 'django.contrib.auth.backends.ModelBackend' try: connection = UserConnection.objects.get(token=request.GET.get('state'), user__isnull=True) except UserConnection.DoesNotExist: return redirect('home') manual_login(request, user) connection.user = user connection.save() if connection.referrer_path: return redirect(connection.referrer_path) return redirect('home')
def tokensignin(request): token = request.POST['idtoken'] try: idinfo = client.verify_id_token(token, CLIENT_ID) if idinfo['iss'] not in [ 'accounts.google.com', 'https://accounts.google.com' ]: return HttpResponse("Wrong issuer") except (crypt.AppIdentityError): # Invalid token return HttpResponse("Invalid token") m = User.objects.filter(username=idinfo['email']) if not m.exists(): new_user = User.objects.create_user(idinfo['email'], idinfo['email'], 'opinawefoinawlkn') new_user.last_name = idinfo['family_name'] new_user.first_name = idinfo['given_name'] new_user.save() user_balance = UserBalance(email=idinfo['email']) user_balance.save() request.session['member_name'] = idinfo['given_name'] request.session['member_email'] = idinfo['email'] request.session['google_account'] = True return HttpResponse("ok")
def verify_id_token(self, token): idinfo = client.verify_id_token(token, self.client_id) if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: raise AuthenticationError("Wrong issuer.") return idinfo['email']
def validate_token(): """ Validate token from google """ id_token = request.form['idtoken'] idinfo = client.verify_id_token(id_token, current_app.config['GOOGLE_APP_ID']) user_id = idinfo['sub'] email = idinfo['email'] username = email validuser = False user = User(username) print email if user.is_anonymous() == True: error = 'Unregistered User' redirect = url_for('user_control.login') else: if idinfo['iss'] not in [ 'accounts.google.com', 'https://accounts.google.com' ]: error = 'Wrong client' redirect = url_for('user_control.login') else: login_user(user) identity_changed.send(current_app._get_current_object(), identity=Identity(user.get_userid())) redirect = url_for('home.homepage') validuser = True error = 'No error' print error return json.dumps({'redirect_url': redirect, 'validuser': validuser})
def gconnect(): """Endpoint that authenticates user.""" try: idinfo = client.verify_id_token( request.data, '1014623565180-lm2sl4gftjv5r8jhgikg0ti9lcldol8c' '.apps.googleusercontent.com') if idinfo['iss'] not in [ 'accounts.google.com', 'https://accounts.google.com' ]: raise crypt.AppIdentityError("Wrong issuer.") except crypt.AppIdentityError: return (jsonify({ 'data': 'Invalid authentication issuer', 'error': '401' }), 401) user = get_user(idinfo['email']) if user is None: user = add_user(idinfo['email'], idinfo['name']) if user is None: return (jsonify({'data': 'Internal Error', 'error': '500'}), 500) login_session['userid'] = user.id return Response({ 'user_id': user.id, 'user_name': idinfo['name'], 'user_picture': idinfo['picture'] })
def login(request): template = loader.get_template('search/afterlogin.html') if request.method=='POST': token=request.POST.get('idtoken','deftok77') CLIENT_ID='535075582690-pianvlpvq9lm07lbv71dh5fdgklvoe8n.apps.googleusercontent.com' try: idinfo = client.verify_id_token(token, CLIENT_ID) # Or, if multiple clients access the backend server: #idinfo = client.verify_id_token(token, None) #if idinfo['aud'] not in [CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]: # raise crypt.AppIdentityError("Unrecognized client.") if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: raise crypt.AppIdentityError("Wrong issuer.") user = User.objects.create_user('luis') user.save() # If auth request is from a G Suite domain: #if idinfo['hd'] != GSUITE_DOMAIN_NAME: # raise crypt.AppIdentityError("Wrong hosted domain.") except crypt.AppIdentityError: print("ivalid token") #nothing here # Invalid token user2 = User.objects.create_user('mike12') user2.save() userid=idinfo['sub'] user3 = User.objectes.create_user(userid) user3.save() context={'userid':userid} return HttpResponse(template.render(context,request))
def resolve_google_oauth(request): # token should be passed as an object {'ID_Token' : id_token } # to this view token = request.GET['ID_Token'] CLIENT_ID = os.environ.get('CLIENT_ID') # though we need to configure this token.replace(" ", "") try: idinfo = client.verify_id_token(token, CLIENT_ID) if 'hd' not in idinfo: return not_allowed() if idinfo['iss'] not in [ 'accounts.google.com', 'https://accounts.google.com' ]: return unauthorized('Wrong Issuer') if idinfo['hd'] == 'andela.com' and \ idinfo['email_verified'] == 'True' and \ idinfo['aud'] == CLIENT_ID: return idinfo except crypt.AppIdentityError: return unauthorized('Invalid Token') return idinfo
def oauth2callback(request): if request.GET.get('state') != unicode(csrf(request)['csrf_token']): payload = { 'error': 'CSRF token verification failed. Your CSRF token is not valid' } return redirect('results?' + urllib.urlencode(payload)) endpoints = requests.get('https://accounts.google.com/.well-known/openid-configuration').json() payload = { 'code': request.GET.get('code'), 'client_id': config.GOOGLE.get('clientID'), 'client_secret': config.GOOGLE.get('clientSecret'), 'response_type': 'code', 'scope': 'openid email', 'redirect_uri': config.HOST + '/google_login/oauth2callback', 'grant_type': 'authorization_code' } r = requests.post(endpoints.get('token_endpoint'), data=payload) id_token = r.json().get('id_token') user_data = verify_id_token(id_token, config.GOOGLE.get('clientID')) user = get_or_create_user(user_data) if user is None: payload = { 'error': 'Error creating user' } return redirect('results?' + urllib.urlencode(payload)) else: login(request, user) return redirect(results)
def verify_token(): """Verifies the identify of the user through their oauth token Returns a 200 HTTP response if the token is valid Returns a 401 HTTP response on error. """ token = request.form.get('token') csrftoken = request.form.get('csrftoken') provider = request.form.get('provider') if csrftoken != session['csrf']: response = make_response(json.dumps('Invalid CSRF token.'), 401) response.headers['Content-Type'] = 'application/json' return response session['csrf'] = '' try: token_info = client.verify_id_token( token, config.oauth['google']['client_id']) if token_info['iss'] not in [ 'accounts.google.com', 'https://accounts.google.com' ]: raise crypt.AppIdentityError("Wrong issuer.") session['provider'] = 'google' session['name'] = token_info['name'] session['email'] = token_info['email'] user = User.by_email(token_info['email']) or User.create_user(session) session['user_id'] = user.id response = make_response(json.dumps('You have logged in.'), 200) response.headers['Content-Type'] = 'application/json' return response except crypt.AppIdentityError: response = make_response(json.dumps('Invalid token.'), 401) response.headers['Content-Type'] = 'application/json' return response
def check_user(token): try: idinfo = client.verify_id_token(token, CLIENT_ID) return True except crypt.AppIdentityError as e: print e return False
def do_auth(better_data): pprint(better_data) CLIENT_ID = "711592045166-4o6ndv014o7l0jfq6dce74n3bh4l6o59.apps.googleusercontent.com" token = str(better_data['token']) try: idinfo = client.verify_id_token(token, CLIENT_ID) if idinfo['iss'] not in [ 'accounts.google.com', 'https://accounts.google.com' ]: raise crypt.AppIdentityError("Wrong issuer.") print("Wrong Issuer.") else: print("Beginning query for authen") # do we add a user ? i don't know. we could try usr = User.query.filter_by(uid=int(idinfo['sub'])) pprint(usr) if usr is None or usr.count() < 0: print("User is not in count! Attemping to add") # add user u = User(int(idinfo['sub']), idinfo['family_name'], idinfo['given_name'], idinfo['picture']) db.session.add(u) db.session.commit() return json.dumps({'type': 'auth', 'success': 1}) else: print("User exists... now what?") return json.dumps({'type': 'auth', 'success': 1}) return json.dumps({'type': 'auth', 'success': 0}) except crypt.AppIdentityError: return json.dumps({'type': 'auth', 'success': 0})
def googleOAuthTokenVerify(): # authenticate with Google for Icahn accounts '''from https://developers.google.com/identity/sign-in/web/backend-auth''' token = request.values.get('idtoken', None) try: idinfo = gauthclient.verify_id_token(token, vm_client_id) # If multiple clients access the backend server: if idinfo['aud'] not in [vm_client_id]: raise crypt.AppIdentityError("Unrecognized client.") if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: raise crypt.AppIdentityError("Wrong issuer.") except crypt.AppIdentityError: # Invalid token sys.stderr.write("Bad token from client.\n") return None # okay, now we're logged in. yay! userid = idinfo['sub'] useremail = idinfo['email'] sys.stderr.write("Token sign in user: "******", ".join([useremail, userid]) + "\n") user = User.query.get(useremail) if user: # if user has been here before user.authenticated=True # log them in in DB db_session.add(user) db_session.commit() flask_login.login_user(user, remember=True) # log them in in their browser else: if ('@icahn.mssm.edu' not in useremail) & ('@mssm.edu' not in useremail): # not ISMMS account return 'Unauthorized e-mail address. You must be a MSSM affiliate with an @icahn.mssm.edu or @mssm.edu address!' else: user = User(email = useremail, google_token=userid) # create new user in DB user.authenticated=True # log them in in DB db_session.add(user) db_session.commit() flask_login.login_user(user, remember=False) # log them in in their browser return useremail # return logged in email to user
def post(self): data = json.loads(self.request.body) user_type = self.get_argument('user_type') if 'access_token' in data: try: details = client.verify_id_token( data['access_token'], config.GOOGLE_OAUTH2_CLIENT_ID ) user = handle_user_authentication( self.dbsession, details, user_type ) self.session['user_type'] = user_type if user_type == 'admin': self.session['buid'] = user.id self.session['admin'] = "true" elif user_type in ('service_provider', 'service_user'): self.session['buid'] = user.user_id self.session['uid'] = user.id self.send_model_response(user) except crypt.AppIdentityError: self.set_status(403) else: self.set_status(400)
def post(self): """Post method for GoogleLogin resource""" args = self.reqparse.parse_args() token = args['id_token'] try: idinfo = client.verify_id_token(token, CLIENT_ID) # Or, if multiple clients access the backend server: # idinfo = client.verify_id_token(token, None) # if idinfo['aud'] not in [CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]: # raise crypt.AppIdentityError("Unrecognized client.") if idinfo['iss'] not in [ 'accounts.google.com', 'https://accounts.google.com' ]: raise crypt.AppIdentityError("Wrong issuer.") # If auth request is from a G Suite domain: # if idinfo['hd'] != GSUITE_DOMAIN_NAME: # raise crypt.AppIdentityError("Wrong hosted domain.") except crypt.AppIdentityError: # Invalid token pass else: userid = idinfo['sub'] user, created = User.get_or_create(user_id=userid, user_type='google') return make_response( jsonify({ "message": "Login successful!", "token": user.generate_auth_token().decode('ascii') }), 200)
def validate_user_id(userId): # (Receive token by HTTPS POST) if userId == -1: print('USER ID ENTERED AS -1') return -1 try: idinfo = client.verify_id_token(userId, CLIENT_ID) # Or, if multiple clients access the backend server: # idinfo = client.verify_id_token(token, None) # if idinfo['aud'] not in [CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]: # raise crypt.AppIdentityError("Unrecognized client.") if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: raise crypt.AppIdentityError("Wrong issuer.") # If auth request is from a G Suite domain: # if idinfo['hd'] != GSUITE_DOMAIN_NAME: # raise crypt.AppIdentityError("Wrong hosted domain.") except crypt.AppIdentityError: print('USER ID PARSED TO -1') return -1 return idinfo['sub']
def validate(request): if str(Config.get('CLIENT_AUTH_ENABLED')) == 'True': token = request.headers.get('google_id_token') client_id = Config.get('ALLOWED_CLIENT_ID') if token is None: if 'google_id_token' not in request.cookies: raise ForbiddenException() token = request.cookies.get("google_id_token") try: logging.info("token: %s, client_id: %s" % (token, client_id)) id_info = client.verify_id_token(token, client_id) logging.info(id_info) if Config.get('DOMAIN_CHECK') is True: if id_info.get('hd') not in Config.get('ALLOWED_DOMAIN').split( ','): raise ForbiddenException() if id_info['iss'] not in [ 'accounts.google.com', 'https://accounts.google.com' ]: raise ForbiddenException() except crypt.AppIdentityError: # Invalid token raise ForbiddenException()
def inner(requestHandler): headers = requestHandler.request.headers if "Authorization" in headers and headers["Authorization"].split( )[0] == "Bearer:": id_token = headers["Authorization"].split()[1] else: oauth_failed(requestHandler) return try: idinfo = client.verify_id_token(id_token, credentials.client_id) if idinfo["iss"] not in [ "accounts.google.com", "https://accounts.google.com" ]: raise crypt.AppIdentityError("Wrong issuer.") except crypt.AppIdentityError: oauth_failed(requestHandler) return current_time = int(time.time()) if not (int(idinfo["iat"]) < current_time and current_time < int(idinfo["exp"])): oauth_failed(requestHandler) return userid = idinfo["sub"] logging.debug("Request authentication success") return http_handler_function(requestHandler)
def SecurityCheck(self, func, request, *args, **kwargs): """Check if access should be allowed for the request.""" try: auth_header = request.headers.get("Authorization", "") if not auth_header.startswith(self.BEARER_PREFIX): raise crypt.AppIdentityError("JWT token is missing.") token = auth_header[len(self.BEARER_PREFIX):] auth_domain = config.CONFIG["AdminUI.firebase_auth_domain"] project_id = auth_domain.split(".")[0] idinfo = client.verify_id_token(token, project_id, cert_uri=self.CERT_URI) if idinfo["iss"] != self.SECURE_TOKEN_PREFIX + project_id: raise crypt.AppIdentityError("Wrong issuer.") request.user = idinfo["email"] except crypt.AppIdentityError as e: # For a homepage, just do a pass-through, otherwise JS code responsible # for the Firebase auth won't ever get executed. This approach is safe, # because wsgiapp.HttpRequest object will raise on any attempt to # access uninitialized HttpRequest.user attribute. if request.path != "/": return self.AuthError("JWT token validation failed: %s" % e) return func(request, *args, **kwargs)
def google_auth(self, request): data = request.data if 'auth_token' not in data: return Response(status=status.HTTP_400_BAD_REQUEST) try: idinfo = client.verify_id_token(data['auth_token'], '92340928633-a2lv6k929j34994pjcfmpdm9a8kc9lme.apps.googleusercontent.com') # If multiple clients access the backend server: # if idinfo['aud'] not in [ANDROID_CLIENT_ID, IOS_CLIENT_ID, WEB_CLIENT_ID]: # raise crypt.AppIdentityError("Unrecognized client.") if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: raise crypt.AppIdentityError("Wrong issuer.") # if idinfo['hd'] != APPS_DOMAIN_NAME: # raise crypt.AppIdentityError("Wrong hosted domain.") except crypt.AppIdentityError as e: print e # Invalid token userid = idinfo['sub'] if User.objects.filter(google_auth_id=userid).exists(): user = User.objects.filter(google_auth_id=userid).get() user.save() else: serializer = self.get_serializer(data={'google_auth_id': userid, 'email': idinfo['email']}) # try: serializer.is_valid(raise_exception=True) # except ValidationError as e: # print e user = serializer.save() serializer = UserSerializer(user) return Response(serializer.data,status=200)
def login_google_callback(request): url = "https://www.googleapis.com/oauth2/v3/token?code=" url += request.GET.get("code") url += "&client_id=" url += settings.GA_CLIENT_ID url += "&client_secret=" url += settings.GA_CLIENT_SECRET url += "&redirect_uri=" url += request.build_absolute_uri(reverse("login_google_callback")) url += "&grant_type=authorization_code" r = requests.post(url) jwt = verify_id_token(r.json().get("id_token"), settings.GA_CLIENT_ID) email = jwt.get("email").lower() try: user = User.objects.get(email=email) except User.DoesNotExist: user = User(email=email) user.save() user.backend = "django.contrib.auth.backends.ModelBackend" try: connection = UserConnection.objects.get(token=request.GET.get("state"), user__isnull=True) except UserConnection.DoesNotExist: return redirect("home") manual_login(request, user) connection.user = user connection.save() if connection.referrer_path: return redirect(connection.referrer_path) return redirect("home")
def SecurityCheck(self, func, request, *args, **kwargs): """Check if access should be allowed for the request.""" try: auth_header = request.headers.get("Authorization", "") if not auth_header.startswith(self.BEARER_PREFIX): raise crypt.AppIdentityError("JWT token is missing.") token = auth_header[len(self.BEARER_PREFIX):] auth_domain = config_lib.CONFIG["AdminUI.firebase_auth_domain"] project_id = auth_domain.split(".")[0] idinfo = client.verify_id_token(token, project_id, cert_uri=self.CERT_URI) if idinfo["iss"] != self.SECURE_TOKEN_PREFIX + project_id: raise crypt.AppIdentityError("Wrong issuer.") request.user = idinfo["email"] except crypt.AppIdentityError as e: # For a homepage, just do a pass-through, otherwise JS code responsible # for the Firebase auth won't ever get executed. This approach is safe, # because wsgiapp.HttpRequest object will raise on any attempt to # access uninitialized HttpRequest.user attribute. if request.path != "/": return self.AuthError("JWT token validation failed: %s" % e) return func(request, *args, **kwargs)
def resolve_google_oauth(request): # token should be passed as an object {'ID_Token' : id_token } # to this view token = request.data.get('ID_Token') CLIENT_ID = os.environ.get('CLIENT_ID') token.replace(" ", "") try: idinfo = client.verify_id_token(token, CLIENT_ID) if 'hd' not in idinfo: raise AuthenticationFailed('Sorry, only Andelans can sign in') if idinfo['hd'] != 'andela.com': raise AuthenticationFailed('Sorry, only Andelans can sign in') if idinfo['iss'] not in [ 'accounts.google.com', 'https://accounts.google.com' ]: raise PermissionDenied('Wrong Issuer') if idinfo['email_verified'] == 'True' and idinfo['aud'] == CLIENT_ID: return idinfo except crypt.AppIdentityError: raise PermissionDenied('Invalid Token') return idinfo
def authenticate_credentials(self, token): User = get_user_model() _token = self.request.session.get('token') email = self.request.session.get('email') if token != _token: try: idinfo = client.verify_id_token(token, settings.GOOGLE_CLIENT_ID) auth_domains = [ 'accounts.google.com', 'https://accounts.google.com' ] if idinfo['iss'] not in auth_domains: raise crypt.AppIdentityError("Wrong issuer.") email = idinfo['email'] except crypt.AppIdentityError: raise AuthenticationFailed('Invalid token.') try: user = User.objects.get(username=email) self.request.session['token'] = token self.request.session['email'] = email return (user, token) except User.DoesNotExist: raise AuthenticationFailed('User does not exist.')
def google_validate(self, token): """ Validates if the request actually comes from Google. :param token: :return: payload in the format azp:GOOGLE_USER_ID, (Unused, for android app) aud:GOOGLE_USER_ID, (Used) sub: Unused (and not sure what it does) email: User email, email_verified:bool, at_hash: string iss: Always accounts.google.com iat: timestamp exp: timestamp name: name family name picture: URL, given_name: Name, family_name: Family name, locale: en """ try: payload = client.verify_id_token(token, GOOGLE_USER_ID) if payload['iss'] not in [ 'accounts.google.com', 'https://accounts.google.com' ] or payload['aud'] != GOOGLE_USER_ID: return False else: return payload except crypt.AppIdentityError: return False
def gauth(): # The POST should include `id_token` id_token = request.form.get('id_token', '')[:3072] # Verify the `id_token` using API Client Library idinfo = client.verify_id_token(id_token, CLIENT_ID) # Additional verification: See if `iss` matches Google issuer string if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: return make_response('Authentication failed', 401) id = idinfo['sub'] # For now, we'll always store profile data after successfully # verifying the token and consider the user authenticated. store = CredentialStore.get_by_id(id) if store is None: store = CredentialStore(id=id) # Construct a profile object store.profile = { 'id': id, 'imageUrl': idinfo.get('picture', None), 'name': idinfo.get('name', None), 'email': idinfo.get('email', None) } store.put() session['id'] = id # Not making a session for demo purpose/simplicity return make_response('Authenticated', 200)
def signin(): """ This function handles the signin process """ if request.method == 'POST': token = request.form['id_token'] try: idinfo = client.verify_id_token( token, '1072405718300-7kdr08dkvn4hkg' + 'ceimh4c7p679rbsmol.apps.goog' + 'leusercontent.com') if idinfo['iss'] not in [ 'accounts.google.com', 'https://accounts.google.com' ]: raise crypt.AppIdentityError("Wrong issuer.") except crypt.AppIdentityError: return 'Error AppIdentityError' userid = idinfo['sub'] username = idinfo['name'] user_exists = db_get('SELECT id, name FROM users WHERE' + ' id = ? ', [userid]) if not user_exists: db_insert('INSERT INTO users VALUES (?, ?)', [(username, userid)]) user_exists = db_get( 'SELECT id, name FROM users WHERE' + ' id = ? ', [userid]) user = User(user_exists[0][0], user_exists[0][1]) login_user(user) return redirect(url_for('landing_page'))
def _google_authenticate(self, token_id): try: id_info = client.verify_id_token(token_id, GOOGLE_SSO_CLIENT_ID) except crypt.AppIdentityError as error: flask.abort(401, "Mauvais jeton d'authentification : %s" % error) if id_info.get('iss') not in _GOOGLE_SSO_ISSUERS: flask.abort( 401, "Fournisseur d'authentification invalide : %s." % id_info.get('iss', '<none>')) response = user_pb2.AuthResponse() user_dict = self._db.user.find_one({'googleId': id_info['sub']}) user_id = str(user_dict['_id']) if user_dict else '' if proto.parse_from_mongo(user_dict, response.authenticated_user): response.authenticated_user.user_id = user_id else: self._assert_user_not_existing(id_info['email']) response.authenticated_user.profile.email = id_info['email'] response.authenticated_user.profile.picture_url = id_info.get( 'picture', '') response.authenticated_user.google_id = id_info['sub'] self._save_new_user(response.authenticated_user) response.is_new_user = True return response
def login(): # To verify using ID Token and send access, refresh tokens content=request.get_json(force=True) token=content['idToken'] print(token) try: idinfo = client.verify_id_token(token, CLIENT_ID) if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: raise crypt.AppIdentityError("Wrong issuer.") except crypt.AppIdentityError: #Invalid ID token return 'fail' print(idinfo['sub']) #Create refresh and access token refreshKey=random.getrandbits(32); secs=int(time.time()) refreshToken = jwt.encode({'refreshSecret': refreshKey}, SIGNING_SECRET_KEY, algorithm='HS256') accessToken = jwt.encode( {'userID': idinfo['sub'],'iat':secs,'exp':secs+3000}, SIGNING_SECRET_KEY, algorithm='HS256') print('refreshtoken') print(refreshToken) #New User if not user_datastore.find_user(userID=idinfo['sub']): user_datastore.create_user(email=idinfo['email'], picture=idinfo['picture'], userID=idinfo['sub'], name=idinfo['name'], refreshSecret=refreshKey) print('new user created') return refreshToken #Existing User else : user=user_datastore.find_user(userID=idinfo['sub']) refreshKey=user.refreshSecret print(refreshKey) return jwt.encode({'refreshSecret': refreshKey}, SIGNING_SECRET_KEY, algorithm='HS256')
def get_info_from_google(token = None): try: if session['signin_party'] != 'google': print 'login_required: Do not verified by Google.' return False, {} except KeyError: print 'login_required: signin_party is missed.' return False, {} if token == None: try: token = session['token'] except KeyError: print 'login_required: token is missed.' return False, {} try: idinfo = client.verify_id_token(token, config.CLIENT_ID) # If multiple clients access the backend server: #if idinfo['aud'] not in [ANDROID_CLIENT_ID, IOS_CLIENT_ID, WEB_CLIENT_ID]: # raise crypt.AppIdentityError("Unrecognized client.") if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: raise crypt.AppIdentityError("Wrong issuer.") #if idinfo['hd'] != APPS_DOMAIN_NAME: # raise crypt.AppIdentityError("Wrong hosted domain.") except crypt.AppIdentityError as e: # Invalid token print e return False, {} return True, idinfo
def process_request(self, request): # do not affect the admin api requests if request.get_full_path().startswith('/admin'): return None try: google_sign_in_token = request.META['HTTP_' + GOOGLE_SIGN_IN_TOKEN_HEADER] # verify the google id token user_info = client.verify_id_token(google_sign_in_token, GOOGLE_OAUTH_WEB_CLIENT_ID) if user_info['aud'] != GOOGLE_OAUTH_WEB_CLIENT_ID: raise crypt.AppIdentityError("unrecognized client") if user_info['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: raise crypt.AppIdentityError("wrong issuer") email = user_info['email'] if not email: return self.unauthorize() request.META['jrn-email'] = email # for all apis, except user creation, verify the requested user exists in db if not request.get_full_path().startswith('/users') or request.method != 'POST': user = User.objects.filter(email=email) if user: request.META['jrn-user-id'] = user[0].user_id else: return self.unauthorize() return None # return None to continue with middleware and handling the request except Exception as e: return self.unauthorize()
def gSignin(): token = request.data try: idinfo = client.verify_id_token(token, CLIENT_ID) if idinfo['aud'] not in [WEB_CLIENT_ID]: raise crypt.AppIdentityError("Unrecognized client.") if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: raise crypt.AppIdentityError("Wrong issuer.") except crypt.AppIdentityError: return json.dumps('No se pudo ingresar al sistema') userid = idinfo['sub'] user = sess.query(User).filter(User.guid == userid).first() if user != None: session['user_id'] = user.id session['guid'] = user.guid session['gfolder'] = user.gfolder flash('Bienvenido %s' % user.name) return json.dumps("%s" % user.name) else: session['error'] = "eroor" return redirect(url_for('auth.signin'))
def authenticating(request): #connect to our local mongodb print "About to Authenticate user" if request.method == 'GET': #get our collection print "Inside GET" return HttpResponse("OK") elif request.method == 'POST': #get data from the request and insert the record print "Inside POST" print request.body print "PRINTED PAYLOAD" received_json_data=json.loads(request.body) token = received_json_data.get("token",False) print token CLIENT_ID = "979314773329-m6j6e9la8u2o9rt15q8655uqnuuolko5.apps.googleusercontent.com" ANDROID_CLIENT_ID = "979314773329-e7kl7cavu9e85hclbbfscruhmtb4t685.apps.googleusercontent.com" IOS_CLIENT_ID = ' ' WEB_CLIENT_ID = ' ' try: idinfo = client.verify_id_token(token, CLIENT_ID) if idinfo['aud'] not in [ANDROID_CLIENT_ID, IOS_CLIENT_ID, WEB_CLIENT_ID]: raise crypt.AppIdentityError("Unrecognized client.") if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: raise crypt.AppIdentityError("Wrong issuer.") if idinfo['hd'] != APPS_DOMAIN_NAME: raise crypt.AppIdentityError("Wrong hosted domain.") except crypt.AppIdentityError: traceback.print_exc() # Invalid token print "Returning Failure of user auth" return HttpResponse("ERROR") userid = idinfo['sub'] print "Returning Success of user auth" return HttpResponse(userid)
def verify_google_id_token(id_token): """ Verifies if id_token is a valid google account token :param id_token: :return: None or sub """ try: # id_info = client.verify_id_token(id_token, CLIENT_ID) # Or, if multiple clients access the backend server: id_info = client.verify_id_token(id_token, None) # if id_info['aud'] not in [CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]: # raise crypt.AppIdentityError("Unrecognized client.") if id_info['iss'] not in [ 'accounts.google.com', 'https://accounts.google.com' ]: raise crypt.AppIdentityError("Wrong issuer.") # If auth request is from a G Suite domain: # if idinfo['hd'] != GSUITE_DOMAIN_NAME: # raise crypt.AppIdentityError("Wrong hosted domain.") except crypt.AppIdentityError: # Invalid token return None user_id = id_info['sub'] return user_id
def _validate_gapi_token(token): import api_helper idinfo = client.verify_id_token(token, api_helper.API_CLIENT_ID) now = anticsrf.microtime() for key in ["exp", "iat"]: idinfo[key] *= (10**6) # to microseconds from seconds # print("idinfo:", idinfo) if idinfo["iss"] not in [ "accounts.google.com", "https://accounts.google.com" ]: raise crypt.AppIdentityError("Token has wrong issuer: {}".format( idinfo["iss"])) elif ((not DEV_VARS["no_check_timestamp"]) and (idinfo["iat"] >= now) or (idinfo["exp"] <= now)): raise client.AccessTokenCredentialsError( "Token has expired or invalid timestamps: issued-at {} expires {}". format(idinfo["iat"], idinfo["exp"])) elif idinfo["aud"] != api_helper.API_CLIENT_ID: # or idinfo["azd"] != API_CLIENT_ID: raise crypt.AppIdentityError("Token has wrong API token id") hd = None if "hd" in idinfo: hd = idinfo["hd"] idinfo["is_elevated"] = \ api_helper.is_elevated_id(idinfo["email"], hd=hd) # print(idinfo) return idinfo
def authenticate(self, token=None): try: idinfo = client.verify_id_token(token, settings.GOOGLE_CLIENT_ID) if idinfo['iss'] not in [ 'accounts.google.com', 'https://accounts.google.com' ]: raise crypt.AppIdentityError("Wrong issuer.") except crypt.AppIdentityError: return None user = User.objects.filter(email=idinfo['email']).first() if not user: user = User.objects.create(username=idinfo['sub'], email=idinfo['email']) user.is_active = idinfo['email_verified'] user.set_unusable_password() user.username_set = False user.save() user.profile.first_name = idinfo['given_name'] user.profile.last_name = idinfo['family_name'] user.profile.email_confirmed = idinfo['email_verified'] user.profile.save() return user
def google_auth(): try: data = json.loads(request.data.decode()) idinfo = client.verify_id_token( data['data'], '192085420693-gnet8a4sjhn89ll6ejjho1tudv3l2oaa.apps.googleusercontent.com' ) if idinfo['iss'] not in [ 'accounts.google.com', 'https://accounts.google.com' ]: raise crypt.AppIdentityError("Wrong issuer.") else: userid = idinfo['sub'] registered_user = User.query.filter_by( email=idinfo['email']).first() if not registered_user: user = User(email=idinfo['email']) db.session.add(user) db.session.commit() registered_user = User.query.filter_by( email=idinfo['email']).first() return login_registered_user(registered_user) except crypt.AppIdentityError: return json.dumps({'message': 'Invalid token'}), 400
def validate_oauth_token(token): """Validate the token code from a mobile client SSO login, then return the user's DRF token for use in authenticating future requests to this API. https://developers.google.com/identity/sign-in/android/backend-auth#using-a-google-api-client-library """ try: idinfo = client.verify_id_token(token, settings.GOOGLE_OAUTH_CLIENT_ID) if idinfo['aud'] not in [settings.GOOGLE_OAUTH_CLIENT_ID]: return JsonResponse({'error': 'Unrecognized client.'}, status=status.HTTP_403_FORBIDDEN) if idinfo['iss'] not in [ 'accounts.google.com', 'https://accounts.google.com' ]: return JsonResponse({'error': 'Wrong issuer.'}, status=status.HTTP_403_FORBIDDEN) # have a good token; get API token now user = authenticate(**idinfo) if user: logger.debug('validated SSO token code for user: {email}'.format( email=user.email)) token, created = Token.objects.get_or_create(user=user) return Response({'token': token.key, 'user': token.user_id}) else: return JsonResponse( {'error': 'This login is not valid in this application'}, status=status.HTTP_403_FORBIDDEN) except crypt.AppIdentityError: return JsonResponse({'error': 'Invalid token'}, status=status.HTTP_403_FORBIDDEN)
def test_verify_id_token_with_certs_uri(self): jwt = self._create_signed_jwt() http = HttpMockSequence([({"status": "200"}, datafile("certs.json"))]) contents = verify_id_token(jwt, "*****@*****.**", http) self.assertEqual("billy bob", contents["user"]) self.assertEqual("data", contents["metadata"]["meta"])
def fetch_info_from_login_token(token): google_api_shmidusic_project_id = "521166378127-6hmr4e9rspkj2amipftmkt4qukb1ljr4.apps.googleusercontent.com" try: user_info = client.verify_id_token(token, google_api_shmidusic_project_id) return user_info except crypt.AppIdentityError as exc: # log maybe? return None
def signIn(): data = request.get_json() provider_user = {} if(data["provider"] == "google"): provider_user = client.verify_id_token(data['id'], '1058234090303-derenhna8oi3h32bf47j77rqtrfalrcd.apps.googleusercontent.com') user = User(name="<name>", provider="google", provider_id=provider_user['sub']) create_user_if_needed(user) return jsonify(provider_user)
def verify(): id_token = request.headers.get('Authorization') if not id_token: abort(400) try: jwt = verify_id_token(id_token, app.config.get('GOOGLE_ID')) return jsonify(jwt) except AppIdentityError as e: print "error", e abort(403)
def verify_email_from_request(): if DEBUG: return token = request.cookies.get('starbook-token') or (request.json and request.json.pop('starbook-token')) google_email = client.verify_id_token(token, CLIENT_ID)['email'] request_email = request.json.get(PERSON_UNIQUE_KEY, None) if request_email is None: return if request_email != google_email and google_email not in ADMINS: return jsonify({'error': 'You are not allowed to do that'}), 403
def get(self): user_type = self.get_argument('user_type', None) next_url = self.get_argument('next', None) if next_url: self.session['next'] = next_url #self.set_secure_cookie('next', next_url) if user_type: self.session['user_type'] = user_type #self.set_secure_cookie('user_type', user_type) if self.get_argument('code', False): user = yield self.get_authenticated_user( redirect_uri=self.REDIRECT_URL, code=self.get_argument('code')) try: details = client.verify_id_token( user['id_token'], config.GOOGLE_OAUTH2_CLIENT_ID ) user_type = self.session['user_type'] user = handle_user_authentication( self.dbsession, details, user_type ) #self.session['user_type'] = user_type if user_type == 'admin': self.session['buid'] = user.id self.session['uid'] = user.id self.session['admin'] = "true" elif user_type in ('service_provider', 'service_user'): self.session['buid'] = user.user_id self.session['uid'] = user.id next_url = self.session['next'] if next_url: self.redirect(next_url) else: self.send_model_response(user) except crypt.AppIdentityError: self.set_status(403) except AppException: self.set_status(400) self.write('User is not admin') else: yield self.authorize_redirect( redirect_uri=self.REDIRECT_URL, client_id=self.settings['google_oauth']['key'], scope=['email', 'profile'], response_type='code', extra_params={'approval_prompt': 'auto'})
def test_verify_id_token_with_certs_uri(self): jwt = self._create_signed_jwt() http = HttpMockSequence([ ({'status': '200'}, datafile('certs.json')), ]) contents = verify_id_token(jwt, '*****@*****.**', http=http) self.assertEqual('billy bob', contents['user']) self.assertEqual('data', contents['metadata']['meta'])
def verify(self, id_token): try: idinfo = client.verify_id_token(id_token, self._client_id) # If multiple clients access the backend server: if idinfo['aud'] not in self._client_ids: raise crypt.AppIdentityError("Unrecognized client.") if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: raise crypt.AppIdentityError("Wrong issuer.") except crypt.AppIdentityError: return (False, None) return (True, idinfo)
def getIdInfo(token): try: idinfo = client.verify_id_token(token, CLIENT_ID) if idinfo['aud'] not in [CLIENT_ID]: # raise crypt.AppIdentityError("Unrecognized client.") return None if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: # raise crypt.AppIdentityError("Wrong issuer.") return None except crypt.AppIdentityError: return None return idinfo
def request_google_auth_service(client_id, token): idinfo = client.verify_id_token(token, client_id) if idinfo['aud'] not in GOOGLE_ACCEPT_CLIENT_IDS: raise crypt.AppIdentityError("Unrecognized client.") if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: raise crypt.AppIdentityError("Wrong issuer.") idinfo['uid'] = idinfo['sub'] for (x, y) in (('name', 'username'), ('given_name', 'first_name'), ('family_name', 'last_name')): idinfo[y] = idinfo[x] if x in idinfo else '' idinfo['provider'] = 'google-oauth2' logger.debug('idinfo = {}'.format(idinfo)) return idinfo