mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-09-04 23:38:24 -04:00
work on logout
This commit is contained in:
@@ -27,20 +27,15 @@ from app.utils.login import is_safe_redirect_url
|
|||||||
|
|
||||||
|
|
||||||
def _get_access_token(code, state):
|
def _get_access_token(code, state):
|
||||||
current_app.logger.info(
|
client_id = os.getenv("LOGIN_DOT_GOV_CLIENT_ID")
|
||||||
f"HURRAY! THIS IS REDIRECT FROM LOGIN DOT GOV AND WE HAVE CODE {code} and STATE {state}"
|
access_token_url = os.getenv("LOGIN_DOT_GOV_ACCESS_TOKEN_URL")
|
||||||
)
|
|
||||||
# TODO use the code to get the access_token with jwt
|
|
||||||
# Using the access_token get the email from the user info
|
|
||||||
# Use the call five lines down to look up the user from the email
|
|
||||||
# activate the user and redirect as five lines down
|
|
||||||
pemfile = open("./private.pem", "r")
|
pemfile = open("./private.pem", "r")
|
||||||
keystring = pemfile.read()
|
keystring = pemfile.read()
|
||||||
pemfile.close()
|
pemfile.close()
|
||||||
payload = {
|
payload = {
|
||||||
"iss": "urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:test_notify_gov",
|
"iss": client_id,
|
||||||
"sub": "urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:test_notify_gov",
|
"sub": client_id,
|
||||||
"aud": "https://idp.int.identitysandbox.gov/api/openid_connect/token",
|
"aud": access_token_url,
|
||||||
"jti": str(uuid.uuid4()),
|
"jti": str(uuid.uuid4()),
|
||||||
# JWT expiration time (10 minute maximum)
|
# JWT expiration time (10 minute maximum)
|
||||||
"exp": int(time.time()) + (10 * 60),
|
"exp": int(time.time()) + (10 * 60),
|
||||||
@@ -48,7 +43,7 @@ def _get_access_token(code, state):
|
|||||||
|
|
||||||
jwt_instance = jwt.PyJWT()
|
jwt_instance = jwt.PyJWT()
|
||||||
token = jwt_instance.encode(payload, keystring, algorithm="RS256")
|
token = jwt_instance.encode(payload, keystring, algorithm="RS256")
|
||||||
base_url = "https://idp.int.identitysandbox.gov/api/openid_connect/token?"
|
base_url = f"{access_token_url}?"
|
||||||
cli_assert = f"client_assertion={token}"
|
cli_assert = f"client_assertion={token}"
|
||||||
cli_assert_type = "client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer"
|
cli_assert_type = "client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer"
|
||||||
code_param = f"code={code}"
|
code_param = f"code={code}"
|
||||||
@@ -57,17 +52,16 @@ def _get_access_token(code, state):
|
|||||||
response = requests.post(url, headers=headers)
|
response = requests.post(url, headers=headers)
|
||||||
current_app.logger.info(f"GOT A RESPONSE {response.json()}")
|
current_app.logger.info(f"GOT A RESPONSE {response.json()}")
|
||||||
access_token = response.json()["access_token"]
|
access_token = response.json()["access_token"]
|
||||||
current_app.logger.info(f"HURRAY GOT THE ACCESS TOKEN! {access_token}")
|
|
||||||
return access_token
|
return access_token
|
||||||
|
|
||||||
|
|
||||||
def _get_user_email(access_token):
|
def _get_user_email(access_token):
|
||||||
headers = {"Authorization": "Bearer %s" % access_token}
|
headers = {"Authorization": "Bearer %s" % access_token}
|
||||||
|
user_info_url = os.getenv("LOGIN_DOT_GOV_USER_INFO_URL")
|
||||||
user_attributes = requests.get(
|
user_attributes = requests.get(
|
||||||
"https://idp.int.identitysandbox.gov/api/openid_connect/userinfo",
|
user_info_url,
|
||||||
headers=headers,
|
headers=headers,
|
||||||
)
|
)
|
||||||
current_app.logger.info(f"HURRAY GOT USER ATTRIBUTES {user_attributes.json()}")
|
|
||||||
user_email = user_attributes.json()["email"]
|
user_email = user_attributes.json()["email"]
|
||||||
return user_email
|
return user_email
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,34 @@
|
|||||||
from flask import redirect, url_for
|
import os
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from flask import redirect, url_for, current_app
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
from app.main import main
|
from app.main import main
|
||||||
|
|
||||||
|
|
||||||
|
def _sign_out_at_login_dot_gov():
|
||||||
|
|
||||||
|
base_url = "https://idp.int.identitysandbox.gov/openid_connect/logout?"
|
||||||
|
client_id = (
|
||||||
|
f"client_id={os.getenv('LOGIN_DOT_GOV_CLIENT_ID')}"
|
||||||
|
)
|
||||||
|
post_logout_redirect_uri = "post_logout_redirect_api=http://localhost:6012/sign-in"
|
||||||
|
state = f"state={str(uuid.uuid4())}"
|
||||||
|
|
||||||
|
# TODO If I take this url and put it in the browser, login.gov sign out works properly
|
||||||
|
# TODO But with this code it results in a 404 error message and we don't sign out from login.gov
|
||||||
|
url = f"{base_url}&{client_id}&{post_logout_redirect_uri}&{state}"
|
||||||
|
current_app.logger.info(f"URL={url}")
|
||||||
|
response = requests.post(url)
|
||||||
|
current_app.logger.info(f"GOT A RESPONSE {response}")
|
||||||
|
|
||||||
|
|
||||||
@main.route("/sign-out", methods=(["GET"]))
|
@main.route("/sign-out", methods=(["GET"]))
|
||||||
def sign_out():
|
def sign_out():
|
||||||
# An AnonymousUser does not have an id
|
# An AnonymousUser does not have an id
|
||||||
if current_user.is_authenticated:
|
if current_user.is_authenticated:
|
||||||
current_user.sign_out()
|
current_user.sign_out()
|
||||||
|
_sign_out_at_login_dot_gov()
|
||||||
return redirect(url_for("main.index"))
|
return redirect(url_for("main.index"))
|
||||||
|
|||||||
21
docs/login_dot_gov.md
Normal file
21
docs/login_dot_gov.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Integrating with login.gov
|
||||||
|
|
||||||
|
How to integrate with the login.gov sandbox: https://dashboard.int.identitysandbox.gov
|
||||||
|
|
||||||
|
1. Create a team and a user over in the login.gov sandbox.
|
||||||
|
2. Create a test app:
|
||||||
|
a. you will need to create a unique client id that looks like: urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:test_notify_gov
|
||||||
|
b. Select OpenIdConnect and private key JWT
|
||||||
|
c. select authentication only
|
||||||
|
d. select MFA required + remember device 30 days only (AAL1)
|
||||||
|
3. generate a cert: openssl req -nodes -x509 -days 365 -newkey rsa:2048 -keyout private.pem -out public.crt
|
||||||
|
4. Upload the public.crt to your app in the sandbox
|
||||||
|
|
||||||
|
|
||||||
|
## Open Issues
|
||||||
|
|
||||||
|
1. The logout functionality is not working. The URL in sign_out.py does work by itself, but for some reason a
|
||||||
|
requests.post(url) fails.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -41,3 +41,8 @@ NR_TRUST_KEY=562946
|
|||||||
NR_AGENT_ID=1134289521
|
NR_AGENT_ID=1134289521
|
||||||
NR_APP_ID=1013682065
|
NR_APP_ID=1013682065
|
||||||
NR_BROWSER_KEY="don't write secrets to the sample file"
|
NR_BROWSER_KEY="don't write secrets to the sample file"
|
||||||
|
|
||||||
|
# Login.gov
|
||||||
|
LOGIN_DOT_GOV_CLIENT_ID="urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:test_notify_gov"
|
||||||
|
LOGIN_DOT_GOV_USER_INFO_URL="https://idp.int.identitysandbox.gov/api/openid_connect/userinfo"
|
||||||
|
LOGIN_DOT_GOV_ACCESS_TOKEN_URL="https://idp.int.identitysandbox.gov/api/openid_connect/token"
|
||||||
Reference in New Issue
Block a user