Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
L
login_gov
Manage
Activity
Members
Labels
Plan
Wiki
Custom issue tracker
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Model registry
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
project
login_gov
Commits
8aaffe8f
Commit
8aaffe8f
authored
2 years ago
by
John Franklin
Browse files
Options
Downloads
Patches
Plain Diff
Issue
#3308944
by John Franklin: verify the nonce returned by login.gov.
parent
259271e0
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/Plugin/OpenIDConnectClient/OpenIDConnectLoginGovClient.php
+40
-3
40 additions, 3 deletions
...lugin/OpenIDConnectClient/OpenIDConnectLoginGovClient.php
with
40 additions
and
3 deletions
src/Plugin/OpenIDConnectClient/OpenIDConnectLoginGovClient.php
+
40
−
3
View file @
8aaffe8f
...
@@ -2,12 +2,14 @@
...
@@ -2,12 +2,14 @@
namespace
Drupal\login_gov\Plugin\OpenIDConnectClient
;
namespace
Drupal\login_gov\Plugin\OpenIDConnectClient
;
use
Drupal\Component\Serialization\Json
;
use
Drupal\Component\Utility\Crypt
;
use
Drupal\Component\Utility\Crypt
;
use
Drupal\Core\Form\FormStateInterface
;
use
Drupal\Core\Form\FormStateInterface
;
use
Drupal\Core\GeneratedUrl
;
use
Drupal\Core\GeneratedUrl
;
use
Drupal\Core\Link
;
use
Drupal\Core\Link
;
use
Drupal\Core\Url
;
use
Drupal\Core\Url
;
use
Drupal\openid_connect
\Plugin\OpenIDConnectClientBase
;
use
Drupal\openid_connect
\Plugin\OpenIDConnectClientBase
;
use
Firebase\JWT\JWK
;
use
Firebase\JWT\JWT
;
use
Firebase\JWT\JWT
;
/**
/**
...
@@ -198,12 +200,14 @@ class OpenIDConnectLoginGovClient extends OpenIDConnectClientBase {
...
@@ -198,12 +200,14 @@ class OpenIDConnectLoginGovClient extends OpenIDConnectClientBase {
'token'
=>
'https://idp.int.identitysandbox.gov/api/openid_connect/token'
,
'token'
=>
'https://idp.int.identitysandbox.gov/api/openid_connect/token'
,
'userinfo'
=>
'https://idp.int.identitysandbox.gov/api/openid_connect/userinfo'
,
'userinfo'
=>
'https://idp.int.identitysandbox.gov/api/openid_connect/userinfo'
,
'end_session'
=>
'https://idp.int.identitysandbox.gov/openid_connect/logout'
,
'end_session'
=>
'https://idp.int.identitysandbox.gov/openid_connect/logout'
,
'certs'
=>
'https://idp.int.identitysandbox.gov/api/openid_connect/certs'
,
]
:
]
:
[
[
'authorization'
=>
'https://secure.login.gov/openid_connect/authorize'
,
'authorization'
=>
'https://secure.login.gov/openid_connect/authorize'
,
'token'
=>
'https://secure.login.gov/api/openid_connect/token'
,
'token'
=>
'https://secure.login.gov/api/openid_connect/token'
,
'userinfo'
=>
'https://secure.login.gov/api/openid_connect/userinfo'
,
'userinfo'
=>
'https://secure.login.gov/api/openid_connect/userinfo'
,
'end_session'
=>
'https://secure.login.gov/openid_connect/logout'
,
'end_session'
=>
'https://secure.login.gov/openid_connect/logout'
,
'certs'
=>
'https://secure.login.gov/api/openid_connect/certs'
,
];
];
}
}
...
@@ -260,6 +264,19 @@ class OpenIDConnectLoginGovClient extends OpenIDConnectClientBase {
...
@@ -260,6 +264,19 @@ class OpenIDConnectLoginGovClient extends OpenIDConnectClientBase {
return
$this
->
configuration
[
'private_key'
];
return
$this
->
configuration
[
'private_key'
];
}
}
/**
* Get login.gov's public signing key.
*
* @return array|null
* A list of public keys.
*/
protected
function
getPeerPublicKeys
():
?array
{
$endpoints
=
$this
->
getEndpoints
();
$keys_json
=
$this
->
httpClient
->
get
(
$endpoints
[
'certs'
])
->
getBody
()
->
getContents
();
$keys
=
Json
::
decode
(
$keys_json
);
return
JWK
::
parseKeySet
(
$keys
);
}
/**
/**
* Generate a one-time use code word, a nonce.
* Generate a one-time use code word, a nonce.
*
*
...
@@ -268,8 +285,6 @@ class OpenIDConnectLoginGovClient extends OpenIDConnectClientBase {
...
@@ -268,8 +285,6 @@ class OpenIDConnectLoginGovClient extends OpenIDConnectClientBase {
*
*
* @return string
* @return string
* The nonce.
* The nonce.
*
* @todo Save the nonce to verify later.
*/
*/
protected
function
generateNonce
(
int
$length
=
26
):
string
{
protected
function
generateNonce
(
int
$length
=
26
):
string
{
return
substr
(
Crypt
::
randomBytesBase64
(
$length
),
0
,
$length
);
return
substr
(
Crypt
::
randomBytesBase64
(
$length
),
0
,
$length
);
...
@@ -297,10 +312,13 @@ class OpenIDConnectLoginGovClient extends OpenIDConnectClientBase {
...
@@ -297,10 +312,13 @@ class OpenIDConnectLoginGovClient extends OpenIDConnectClientBase {
*/
*/
protected
function
getUrlOptions
(
string
$scope
,
GeneratedUrl
$redirect_uri
):
array
{
protected
function
getUrlOptions
(
string
$scope
,
GeneratedUrl
$redirect_uri
):
array
{
$options
=
parent
::
getUrlOptions
(
$scope
,
$redirect_uri
);
$options
=
parent
::
getUrlOptions
(
$scope
,
$redirect_uri
);
$nonce
=
$this
->
generateNonce
();
$options
[
'query'
]
+=
[
$options
[
'query'
]
+=
[
'acr_values'
=>
$this
->
generateAcrValue
(),
'acr_values'
=>
$this
->
generateAcrValue
(),
'nonce'
=>
$
this
->
generateN
once
()
,
'nonce'
=>
$
n
once
,
];
];
$this
->
requestStack
->
getCurrentRequest
()
->
getSession
()
->
set
(
'login_gov.nonce'
,
$nonce
);
if
(
$this
->
configuration
[
'acr_level'
]
==
'2'
&&
$this
->
configuration
[
'verified_within'
][
'count'
])
{
if
(
$this
->
configuration
[
'acr_level'
]
==
'2'
&&
$this
->
configuration
[
'verified_within'
][
'count'
])
{
$options
[
'query'
][
'verified_within'
]
=
$this
->
configuration
[
'verified_within'
][
'count'
]
.
$this
->
configuration
[
'verified_within'
][
'units'
];
$options
[
'query'
][
'verified_within'
]
=
$this
->
configuration
[
'verified_within'
][
'count'
]
.
$this
->
configuration
[
'verified_within'
][
'units'
];
...
@@ -310,6 +328,25 @@ class OpenIDConnectLoginGovClient extends OpenIDConnectClientBase {
...
@@ -310,6 +328,25 @@ class OpenIDConnectLoginGovClient extends OpenIDConnectClientBase {
return
$options
;
return
$options
;
}
}
/**
* {@inheritdoc}
*/
public
function
retrieveTokens
(
string
$authorization_code
):
?array
{
$tokens
=
parent
::
retrieveTokens
(
$authorization_code
);
// Verify the nonce is the one we sent earlier.
if
(
!
empty
(
$tokens
[
'id_token'
]))
{
$keys
=
$this
->
getPeerPublicKeys
();
$decoded_tokens
=
JWT
::
decode
(
$tokens
[
'id_token'
],
$keys
);
$session_nonce
=
$this
->
requestStack
->
getCurrentRequest
()
->
getSession
()
->
get
(
'login_gov.nonce'
);
if
(
!
empty
(
$session_nonce
)
&&
(
$decoded_tokens
->
nonce
!==
$session_nonce
))
{
return
NULL
;
}
}
return
$tokens
;
}
/**
/**
* {@inheritdoc}
* {@inheritdoc}
*/
*/
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment