mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-09-09 17:45:32 -04:00
Merge pull request #1966 from GSA/USN-COMPLY-49_Verify_Nonce_on_Login
Verify NONCE on login.
This commit is contained in:
2
.github/workflows/deploy-demo.yml
vendored
2
.github/workflows/deploy-demo.yml
vendored
@@ -63,6 +63,7 @@ jobs:
|
|||||||
LOGIN_DOT_GOV_BASE_LOGOUT_URL: "https://secure.login.gov/openid_connect/logout?"
|
LOGIN_DOT_GOV_BASE_LOGOUT_URL: "https://secure.login.gov/openid_connect/logout?"
|
||||||
LOGIN_DOT_GOV_SIGNOUT_REDIRECT: "https://notify-demo.app.cloud.gov/sign-out"
|
LOGIN_DOT_GOV_SIGNOUT_REDIRECT: "https://notify-demo.app.cloud.gov/sign-out"
|
||||||
LOGIN_DOT_GOV_INITIAL_SIGNIN_URL: "https://secure.login.gov/openid_connect/authorize?acr_values=http%3A%2F%2Fidmanagement.gov%2Fns%2Fassurance%2Fial%2F1&client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov&nonce=NONCE&prompt=select_account&redirect_uri=https://notify-demo.app.cloud.gov/sign-in&response_type=code&scope=openid+email&state=STATE"
|
LOGIN_DOT_GOV_INITIAL_SIGNIN_URL: "https://secure.login.gov/openid_connect/authorize?acr_values=http%3A%2F%2Fidmanagement.gov%2Fns%2Fassurance%2Fial%2F1&client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov&nonce=NONCE&prompt=select_account&redirect_uri=https://notify-demo.app.cloud.gov/sign-in&response_type=code&scope=openid+email&state=STATE"
|
||||||
|
LOGIN_DOT_GOV_CERTS_URL: "https://secure.login.gov/api/openid_connect/certs"
|
||||||
with:
|
with:
|
||||||
cf_username: ${{ secrets.CLOUDGOV_USERNAME }}
|
cf_username: ${{ secrets.CLOUDGOV_USERNAME }}
|
||||||
cf_password: ${{ secrets.CLOUDGOV_PASSWORD }}
|
cf_password: ${{ secrets.CLOUDGOV_PASSWORD }}
|
||||||
@@ -85,6 +86,7 @@ jobs:
|
|||||||
--var LOGIN_DOT_GOV_BASE_LOGOUT_URL="$LOGIN_DOT_GOV_BASE_LOGOUT_URL"
|
--var LOGIN_DOT_GOV_BASE_LOGOUT_URL="$LOGIN_DOT_GOV_BASE_LOGOUT_URL"
|
||||||
--var LOGIN_DOT_GOV_SIGNOUT_REDIRECT="$LOGIN_DOT_GOV_SIGNOUT_REDIRECT"
|
--var LOGIN_DOT_GOV_SIGNOUT_REDIRECT="$LOGIN_DOT_GOV_SIGNOUT_REDIRECT"
|
||||||
--var LOGIN_DOT_GOV_INITIAL_SIGNIN_URL="$LOGIN_DOT_GOV_INITIAL_SIGNIN_URL"
|
--var LOGIN_DOT_GOV_INITIAL_SIGNIN_URL="$LOGIN_DOT_GOV_INITIAL_SIGNIN_URL"
|
||||||
|
--var LOGIN_DOT_GOV_CERTS_URL="$LOGIN_DOT_GOV_CERTS_URL"
|
||||||
|
|
||||||
- name: Check for changes to egress config
|
- name: Check for changes to egress config
|
||||||
id: changed-egress-config
|
id: changed-egress-config
|
||||||
|
|||||||
2
.github/workflows/deploy-prod.yml
vendored
2
.github/workflows/deploy-prod.yml
vendored
@@ -63,6 +63,7 @@ jobs:
|
|||||||
LOGIN_DOT_GOV_BASE_LOGOUT_URL: "https://secure.login.gov/openid_connect/logout?"
|
LOGIN_DOT_GOV_BASE_LOGOUT_URL: "https://secure.login.gov/openid_connect/logout?"
|
||||||
LOGIN_DOT_GOV_SIGNOUT_REDIRECT: "https://beta.notify.gov/sign-out"
|
LOGIN_DOT_GOV_SIGNOUT_REDIRECT: "https://beta.notify.gov/sign-out"
|
||||||
LOGIN_DOT_GOV_INITIAL_SIGNIN_URL: "https://secure.login.gov/openid_connect/authorize?acr_values=http%3A%2F%2Fidmanagement.gov%2Fns%2Fassurance%2Fial%2F1&client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov&nonce=NONCE&prompt=select_account&redirect_uri=https://beta.notify.gov/sign-in&response_type=code&scope=openid+email&state=STATE"
|
LOGIN_DOT_GOV_INITIAL_SIGNIN_URL: "https://secure.login.gov/openid_connect/authorize?acr_values=http%3A%2F%2Fidmanagement.gov%2Fns%2Fassurance%2Fial%2F1&client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov&nonce=NONCE&prompt=select_account&redirect_uri=https://beta.notify.gov/sign-in&response_type=code&scope=openid+email&state=STATE"
|
||||||
|
LOGIN_DOT_GOV_CERTS_URL: "https://secure.login.gov/api/openid_connect/certs"
|
||||||
with:
|
with:
|
||||||
cf_username: ${{ secrets.CLOUDGOV_USERNAME }}
|
cf_username: ${{ secrets.CLOUDGOV_USERNAME }}
|
||||||
cf_password: ${{ secrets.CLOUDGOV_PASSWORD }}
|
cf_password: ${{ secrets.CLOUDGOV_PASSWORD }}
|
||||||
@@ -85,6 +86,7 @@ jobs:
|
|||||||
--var LOGIN_DOT_GOV_BASE_LOGOUT_URL="$LOGIN_DOT_GOV_BASE_LOGOUT_URL"
|
--var LOGIN_DOT_GOV_BASE_LOGOUT_URL="$LOGIN_DOT_GOV_BASE_LOGOUT_URL"
|
||||||
--var LOGIN_DOT_GOV_SIGNOUT_REDIRECT="$LOGIN_DOT_GOV_SIGNOUT_REDIRECT"
|
--var LOGIN_DOT_GOV_SIGNOUT_REDIRECT="$LOGIN_DOT_GOV_SIGNOUT_REDIRECT"
|
||||||
--var LOGIN_DOT_GOV_INITIAL_SIGNIN_URL="$LOGIN_DOT_GOV_INITIAL_SIGNIN_URL"
|
--var LOGIN_DOT_GOV_INITIAL_SIGNIN_URL="$LOGIN_DOT_GOV_INITIAL_SIGNIN_URL"
|
||||||
|
--var LOGIN_DOT_GOV_CERTS_URL="$LOGIN_DOT_GOV_CERTS_URL"
|
||||||
|
|
||||||
- name: Check for changes to egress config
|
- name: Check for changes to egress config
|
||||||
id: changed-egress-config
|
id: changed-egress-config
|
||||||
|
|||||||
2
.github/workflows/deploy.yml
vendored
2
.github/workflows/deploy.yml
vendored
@@ -69,6 +69,7 @@ jobs:
|
|||||||
LOGIN_DOT_GOV_BASE_LOGOUT_URL: "https://secure.login.gov/openid_connect/logout?"
|
LOGIN_DOT_GOV_BASE_LOGOUT_URL: "https://secure.login.gov/openid_connect/logout?"
|
||||||
LOGIN_DOT_GOV_SIGNOUT_REDIRECT: "https://notify-staging.app.cloud.gov/sign-out"
|
LOGIN_DOT_GOV_SIGNOUT_REDIRECT: "https://notify-staging.app.cloud.gov/sign-out"
|
||||||
LOGIN_DOT_GOV_INITIAL_SIGNIN_URL: "https://secure.login.gov/openid_connect/authorize?acr_values=http%3A%2F%2Fidmanagement.gov%2Fns%2Fassurance%2Fial%2F1&client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov&nonce=NONCE&prompt=select_account&redirect_uri=https://notify-staging.app.cloud.gov/sign-in&response_type=code&scope=openid+email&state=STATEE"
|
LOGIN_DOT_GOV_INITIAL_SIGNIN_URL: "https://secure.login.gov/openid_connect/authorize?acr_values=http%3A%2F%2Fidmanagement.gov%2Fns%2Fassurance%2Fial%2F1&client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov&nonce=NONCE&prompt=select_account&redirect_uri=https://notify-staging.app.cloud.gov/sign-in&response_type=code&scope=openid+email&state=STATEE"
|
||||||
|
LOGIN_DOT_GOV_CERTS_URL: "https://secure.login.gov/api/openid_connect/certs"
|
||||||
with:
|
with:
|
||||||
cf_username: ${{ secrets.CLOUDGOV_USERNAME }}
|
cf_username: ${{ secrets.CLOUDGOV_USERNAME }}
|
||||||
cf_password: ${{ secrets.CLOUDGOV_PASSWORD }}
|
cf_password: ${{ secrets.CLOUDGOV_PASSWORD }}
|
||||||
@@ -91,6 +92,7 @@ jobs:
|
|||||||
--var LOGIN_DOT_GOV_BASE_LOGOUT_URL="$LOGIN_DOT_GOV_BASE_LOGOUT_URL"
|
--var LOGIN_DOT_GOV_BASE_LOGOUT_URL="$LOGIN_DOT_GOV_BASE_LOGOUT_URL"
|
||||||
--var LOGIN_DOT_GOV_SIGNOUT_REDIRECT="$LOGIN_DOT_GOV_SIGNOUT_REDIRECT"
|
--var LOGIN_DOT_GOV_SIGNOUT_REDIRECT="$LOGIN_DOT_GOV_SIGNOUT_REDIRECT"
|
||||||
--var LOGIN_DOT_GOV_INITIAL_SIGNIN_URL="$LOGIN_DOT_GOV_INITIAL_SIGNIN_URL"
|
--var LOGIN_DOT_GOV_INITIAL_SIGNIN_URL="$LOGIN_DOT_GOV_INITIAL_SIGNIN_URL"
|
||||||
|
--var LOGIN_DOT_GOV_CERTS_URL="$LOGIN_DOT_GOV_CERTS_URL"
|
||||||
|
|
||||||
|
|
||||||
- name: Check for changes to egress config
|
- name: Check for changes to egress config
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
import os
|
import os
|
||||||
|
import secrets
|
||||||
|
|
||||||
from flask import abort, current_app, redirect, render_template, request, url_for
|
from flask import (
|
||||||
|
abort,
|
||||||
|
current_app,
|
||||||
|
redirect,
|
||||||
|
render_template,
|
||||||
|
request,
|
||||||
|
session,
|
||||||
|
url_for,
|
||||||
|
)
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
from app import status_api_client
|
from app import status_api_client
|
||||||
@@ -23,8 +32,12 @@ def index():
|
|||||||
)
|
)
|
||||||
url = os.getenv("LOGIN_DOT_GOV_INITIAL_SIGNIN_URL")
|
url = os.getenv("LOGIN_DOT_GOV_INITIAL_SIGNIN_URL")
|
||||||
# handle unit tests
|
# handle unit tests
|
||||||
|
|
||||||
|
nonce = secrets.token_urlsafe()
|
||||||
|
session["nonce"] = nonce
|
||||||
|
|
||||||
if url is not None:
|
if url is not None:
|
||||||
url = url.replace("NONCE", token)
|
url = url.replace("NONCE", nonce)
|
||||||
url = url.replace("STATE", token)
|
url = url.replace("STATE", token)
|
||||||
return render_template(
|
return render_template(
|
||||||
"views/signedout.html",
|
"views/signedout.html",
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
import json
|
||||||
import os
|
import os
|
||||||
|
import secrets
|
||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
@@ -12,6 +14,7 @@ from flask import (
|
|||||||
redirect,
|
redirect,
|
||||||
render_template,
|
render_template,
|
||||||
request,
|
request,
|
||||||
|
session,
|
||||||
url_for,
|
url_for,
|
||||||
)
|
)
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
@@ -28,7 +31,7 @@ from app.utils.user import is_gov_user
|
|||||||
from notifications_utils.url_safe_token import generate_token
|
from notifications_utils.url_safe_token import generate_token
|
||||||
|
|
||||||
|
|
||||||
def _reformat_keystring(orig):
|
def _reformat_keystring(orig): # pragma: no cover
|
||||||
arr = orig.split("-----")
|
arr = orig.split("-----")
|
||||||
begin = arr[1]
|
begin = arr[1]
|
||||||
end = arr[3]
|
end = arr[3]
|
||||||
@@ -37,9 +40,10 @@ def _reformat_keystring(orig):
|
|||||||
return new_keystring
|
return new_keystring
|
||||||
|
|
||||||
|
|
||||||
def _get_access_token(code, state):
|
def _get_access_token(code, state): # pragma: no cover
|
||||||
client_id = os.getenv("LOGIN_DOT_GOV_CLIENT_ID")
|
client_id = os.getenv("LOGIN_DOT_GOV_CLIENT_ID")
|
||||||
access_token_url = os.getenv("LOGIN_DOT_GOV_ACCESS_TOKEN_URL")
|
access_token_url = os.getenv("LOGIN_DOT_GOV_ACCESS_TOKEN_URL")
|
||||||
|
certs_url = os.getenv("LOGIN_DOT_GOV_CERTS_URL")
|
||||||
keystring = os.getenv("LOGIN_PEM")
|
keystring = os.getenv("LOGIN_PEM")
|
||||||
if " " in keystring:
|
if " " in keystring:
|
||||||
keystring = _reformat_keystring(keystring)
|
keystring = _reformat_keystring(keystring)
|
||||||
@@ -60,17 +64,48 @@ def _get_access_token(code, state):
|
|||||||
url = f"{base_url}{cli_assert}&{cli_assert_type}&{code_param}&grant_type=authorization_code"
|
url = f"{base_url}{cli_assert}&{cli_assert_type}&{code_param}&grant_type=authorization_code"
|
||||||
headers = {"Authorization": "Bearer %s" % token}
|
headers = {"Authorization": "Bearer %s" % token}
|
||||||
response = requests.post(url, headers=headers)
|
response = requests.post(url, headers=headers)
|
||||||
if response.json().get("access_token") is None:
|
response_json = response.json()
|
||||||
|
try:
|
||||||
|
encoded_id_token = response_json["id_token"]
|
||||||
|
except KeyError as e:
|
||||||
# Capture the response json here so it hopefully shows up in error reports
|
# Capture the response json here so it hopefully shows up in error reports
|
||||||
current_app.logger.error(
|
current_app.logger.exception(f"Error when getting id token {response_json}")
|
||||||
|
raise KeyError(f"'access_token' {response.json()}") from e
|
||||||
|
|
||||||
|
# Getting Login.gov signing keys for unpacking the id_token correctly.
|
||||||
|
jwks = requests.get(certs_url).json()
|
||||||
|
public_keys = {
|
||||||
|
jwk["kid"]: {
|
||||||
|
"key": jwt.algorithms.RSAAlgorithm.from_jwk(json.dumps(jwk)),
|
||||||
|
"algo": jwk["alg"],
|
||||||
|
}
|
||||||
|
for jwk in jwks["keys"]
|
||||||
|
}
|
||||||
|
kid = jwt.get_unverified_header(encoded_id_token)["kid"]
|
||||||
|
pub_key = public_keys[kid]["key"]
|
||||||
|
algo = public_keys[kid]["algo"]
|
||||||
|
id_token = jwt.decode(
|
||||||
|
encoded_id_token, pub_key, audience=client_id, algorithms=[algo]
|
||||||
|
)
|
||||||
|
|
||||||
|
nonce = id_token["nonce"]
|
||||||
|
saved_nonce = session.pop("nonce")
|
||||||
|
if nonce != saved_nonce:
|
||||||
|
current_app.logger.error(f"Nonce Error: {nonce} != {saved_nonce}")
|
||||||
|
abort(403)
|
||||||
|
|
||||||
|
try:
|
||||||
|
access_token = response_json["access_token"]
|
||||||
|
except KeyError as e:
|
||||||
|
# Capture the response json here so it hopefully shows up in error reports
|
||||||
|
current_app.logger.exception(
|
||||||
f"Error when getting access token {response.json()} #notify-admin-1505"
|
f"Error when getting access token {response.json()} #notify-admin-1505"
|
||||||
)
|
)
|
||||||
raise KeyError(f"'access_token' {response.json()}")
|
raise KeyError(f"'access_token' {response.json()}") from e
|
||||||
access_token = response.json()["access_token"]
|
|
||||||
return access_token
|
return access_token
|
||||||
|
|
||||||
|
|
||||||
def _get_user_email_and_uuid(access_token):
|
def _get_user_email_and_uuid(access_token): # pragma: no cover
|
||||||
headers = {"Authorization": "Bearer %s" % access_token}
|
headers = {"Authorization": "Bearer %s" % access_token}
|
||||||
user_info_url = os.getenv("LOGIN_DOT_GOV_USER_INFO_URL")
|
user_info_url = os.getenv("LOGIN_DOT_GOV_USER_INFO_URL")
|
||||||
user_attributes = requests.get(
|
user_attributes = requests.get(
|
||||||
@@ -82,7 +117,7 @@ def _get_user_email_and_uuid(access_token):
|
|||||||
return user_email, user_uuid
|
return user_email, user_uuid
|
||||||
|
|
||||||
|
|
||||||
def _do_login_dot_gov():
|
def _do_login_dot_gov(): # $ pragma: no cover
|
||||||
# start login.gov
|
# start login.gov
|
||||||
code = request.args.get("code")
|
code = request.args.get("code")
|
||||||
state = request.args.get("state")
|
state = request.args.get("state")
|
||||||
@@ -122,14 +157,14 @@ def _do_login_dot_gov():
|
|||||||
current_app.logger.info(f"activating user {usr.id} #notify-admin-1505")
|
current_app.logger.info(f"activating user {usr.id} #notify-admin-1505")
|
||||||
activate_user(usr.id)
|
activate_user(usr.id)
|
||||||
except BaseException as be: # noqa B036
|
except BaseException as be: # noqa B036
|
||||||
current_app.logger.error(f"Error signing in: {be} #notify-admin-1505 ")
|
current_app.logger.exception(f"Error signing in: {be} #notify-admin-1505 ")
|
||||||
error(401)
|
error(401)
|
||||||
return redirect(url_for("main.show_accounts_or_dashboard", next=redirect_url))
|
return redirect(url_for("main.show_accounts_or_dashboard", next=redirect_url))
|
||||||
|
|
||||||
# end login.gov
|
# end login.gov
|
||||||
|
|
||||||
|
|
||||||
def verify_email(user, redirect_url):
|
def verify_email(user, redirect_url): # pragma: no cover
|
||||||
user_api_client.send_verify_code(user["id"], "email", None, redirect_url)
|
user_api_client.send_verify_code(user["id"], "email", None, redirect_url)
|
||||||
title = "Email resent" if request.args.get("email_resent") else "Check your email"
|
title = "Email resent" if request.args.get("email_resent") else "Check your email"
|
||||||
redirect_url = request.args.get("next")
|
redirect_url = request.args.get("next")
|
||||||
@@ -138,7 +173,7 @@ def verify_email(user, redirect_url):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _handle_e2e_tests(redirect_url):
|
def _handle_e2e_tests(redirect_url): # pragma: no cover
|
||||||
try:
|
try:
|
||||||
current_app.logger.warning("E2E TESTS ARE ENABLED.")
|
current_app.logger.warning("E2E TESTS ARE ENABLED.")
|
||||||
current_app.logger.warning(
|
current_app.logger.warning(
|
||||||
@@ -161,7 +196,7 @@ def _handle_e2e_tests(redirect_url):
|
|||||||
|
|
||||||
@main.route("/sign-in", methods=(["GET", "POST"]))
|
@main.route("/sign-in", methods=(["GET", "POST"]))
|
||||||
@hide_from_search_engines
|
@hide_from_search_engines
|
||||||
def sign_in():
|
def sign_in(): # pragma: no cover
|
||||||
redirect_url = request.args.get("next")
|
redirect_url = request.args.get("next")
|
||||||
|
|
||||||
if os.getenv("NOTIFY_E2E_TEST_EMAIL"):
|
if os.getenv("NOTIFY_E2E_TEST_EMAIL"):
|
||||||
@@ -189,10 +224,15 @@ def sign_in():
|
|||||||
current_app.config["DANGEROUS_SALT"],
|
current_app.config["DANGEROUS_SALT"],
|
||||||
)
|
)
|
||||||
url = os.getenv("LOGIN_DOT_GOV_INITIAL_SIGNIN_URL")
|
url = os.getenv("LOGIN_DOT_GOV_INITIAL_SIGNIN_URL")
|
||||||
|
|
||||||
|
nonce = secrets.token_urlsafe()
|
||||||
|
session["nonce"] = nonce
|
||||||
|
|
||||||
# handle unit tests
|
# handle unit tests
|
||||||
if url is not None:
|
if url is not None:
|
||||||
url = url.replace("NONCE", token)
|
url = url.replace("NONCE", nonce)
|
||||||
url = url.replace("STATE", token)
|
url = url.replace("STATE", token)
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"views/signin.html",
|
"views/signin.html",
|
||||||
again=bool(redirect_url),
|
again=bool(redirect_url),
|
||||||
@@ -201,5 +241,5 @@ def sign_in():
|
|||||||
|
|
||||||
|
|
||||||
@login_manager.unauthorized_handler
|
@login_manager.unauthorized_handler
|
||||||
def sign_in_again():
|
def sign_in_again(): # pragma: no cover
|
||||||
return redirect(url_for("main.sign_in", next=request.path))
|
return redirect(url_for("main.sign_in", next=request.path))
|
||||||
|
|||||||
@@ -59,3 +59,4 @@ applications:
|
|||||||
LOGIN_DOT_GOV_BASE_LOGOUT_URL: ((LOGIN_DOT_GOV_BASE_LOGOUT_URL))
|
LOGIN_DOT_GOV_BASE_LOGOUT_URL: ((LOGIN_DOT_GOV_BASE_LOGOUT_URL))
|
||||||
LOGIN_DOT_GOV_SIGNOUT_REDIRECT: ((LOGIN_DOT_GOV_SIGNOUT_REDIRECT))
|
LOGIN_DOT_GOV_SIGNOUT_REDIRECT: ((LOGIN_DOT_GOV_SIGNOUT_REDIRECT))
|
||||||
LOGIN_DOT_GOV_INITIAL_SIGNIN_URL: ((LOGIN_DOT_GOV_INITIAL_SIGNIN_URL))
|
LOGIN_DOT_GOV_INITIAL_SIGNIN_URL: ((LOGIN_DOT_GOV_INITIAL_SIGNIN_URL))
|
||||||
|
LOGIN_DOT_GOV_CERTS_URL: ((LOGIN_DOT_GOV_CERTS_URL))
|
||||||
|
|||||||
@@ -43,3 +43,4 @@ LOGIN_DOT_GOV_LOGOUT_URL="https://idp.int.identitysandbox.gov/openid_connect/log
|
|||||||
LOGIN_DOT_GOV_BASE_LOGOUT_URL="https://idp.int.identitysandbox.gov/openid_connect/logout?"
|
LOGIN_DOT_GOV_BASE_LOGOUT_URL="https://idp.int.identitysandbox.gov/openid_connect/logout?"
|
||||||
LOGIN_DOT_GOV_SIGNOUT_REDIRECT="http://localhost:6012/sign-out"
|
LOGIN_DOT_GOV_SIGNOUT_REDIRECT="http://localhost:6012/sign-out"
|
||||||
LOGIN_DOT_GOV_INITIAL_SIGNIN_URL="https://idp.int.identitysandbox.gov/openid_connect/authorize?acr_values=http%3A%2F%2Fidmanagement.gov%2Fns%2Fassurance%2Fial%2F1&client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:test_notify_gov&nonce=NONCE&prompt=select_account&redirect_uri=http://localhost:6012/sign-in&response_type=code&scope=openid+email&state=STATE"
|
LOGIN_DOT_GOV_INITIAL_SIGNIN_URL="https://idp.int.identitysandbox.gov/openid_connect/authorize?acr_values=http%3A%2F%2Fidmanagement.gov%2Fns%2Fassurance%2Fial%2F1&client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:test_notify_gov&nonce=NONCE&prompt=select_account&redirect_uri=http://localhost:6012/sign-in&response_type=code&scope=openid+email&state=STATE"
|
||||||
|
LOGIN_DOT_GOV_CERTS_URL = "https://idp.int.identitysandbox.gov/api/openid_connect/certs"
|
||||||
|
|||||||
Reference in New Issue
Block a user