Skip to content

Commit 1389fa7

Browse files
committed
access token refresh
1 parent baaad16 commit 1389fa7

File tree

5 files changed

+39
-3
lines changed

5 files changed

+39
-3
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
*.Pester.Defaults.json
22
*.zip
3+
.DS_Store

RELEASE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
- Fix invalid Id error, [#262](https://github.com/Snow-Shell/servicenow-powershell/issues/262)
1+
- Add support for access token refresh, [#277](https://github.com/Snow-Shell/servicenow-powershell/issues/277)

Readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ $params = @{
4343
New-ServiceNowSession @params
4444
```
4545

46-
Oauth authentication with user credential as well as application/client credential. The application/client credential can be found in the System OAuth->Application Registry section of ServiceNow.
46+
Oauth authentication with user credential as well as application/client credential. The application/client credential can be found in the System OAuth->Application Registry section of ServiceNow. The access token will be refreshed automatically when it expires.
4747
```PowerShell
4848
$params = @{
4949
Url = 'instance.service-now.com'

ServiceNow/Private/Get-ServiceNowAuth.ps1

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,35 @@ function Get-ServiceNowAuth {
3131

3232
if ( $ServiceNowSession.Count -gt 0 ) {
3333
$hashOut.Uri = $ServiceNowSession.BaseUri
34+
35+
# check if we need a new access token
36+
if ( $ServiceNowSession.ExpiresOn -lt (Get-Date) -and $ServiceNowSession.RefreshToken -and $ServiceNowSession.ClientCredential ) {
37+
# we've expired and have a refresh token
38+
$refreshParams = @{
39+
Uri = 'https://{0}/oauth_token.do' -f $ServiceNowSession.Domain
40+
Method = 'POST'
41+
ContentType = 'application/x-www-form-urlencoded'
42+
Body = @{
43+
grant_type = 'refresh_token'
44+
client_id = $ServiceNowSession.ClientCredential.UserName
45+
client_secret = $ServiceNowSession.ClientCredential.GetNetworkCredential().password
46+
refresh_token = $ServiceNowSession.RefreshToken.GetNetworkCredential().password
47+
}
48+
}
49+
50+
$response = Invoke-RestMethod @refreshParams
51+
52+
$ServiceNowSession.AccessToken = New-Object System.Management.Automation.PSCredential('AccessToken', ($response.access_token | ConvertTo-SecureString -AsPlainText -Force))
53+
$ServiceNowSession.RefreshToken = New-Object System.Management.Automation.PSCredential('RefreshToken', ($response.refresh_token | ConvertTo-SecureString -AsPlainText -Force))
54+
if ($response.expires_in) {
55+
$ServiceNowSession.ExpiresOn = (Get-Date).AddSeconds($response.expires_in)
56+
Write-Verbose ('Access token has been refreshed and will expire at {0}' -f $ServiceNowSession.ExpiresOn)
57+
}
58+
59+
# ensure script/module scoped variable is updated
60+
$script:ServiceNowSession = $ServiceNowSession
61+
}
62+
3463
if ( $ServiceNowSession.AccessToken ) {
3564
$hashOut.Headers = @{
3665
'Authorization' = 'Bearer {0}' -f $ServiceNowSession.AccessToken.GetNetworkCredential().password

ServiceNow/Public/New-ServiceNowSession.ps1

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ Create a new ServiceNow session
66
Create a new ServiceNow session via credentials, OAuth, or access token.
77
This session will be used by default for all future calls.
88
Optionally, you can specify the api version you'd like to use; the default is the latest.
9+
910
To use OAuth, ensure you've set it up, https://docs.servicenow.com/bundle/quebec-platform-administration/page/administer/security/task/t_SettingUpOAuth.html.
1011
12+
If using OAuth, the client credential will be stored in the script scoped variable ServiceNowSession and the access token will be automatically refreshed.
13+
1114
.PARAMETER Url
1215
Base domain for your ServiceNow instance, eg. tenant.domain.com
1316
@@ -200,8 +203,11 @@ function New-ServiceNowSession {
200203
if ($token.expires_in) {
201204
$expiryTime = (Get-Date).AddSeconds($token.expires_in)
202205
$newSession.Add('ExpiresOn', $expiryTime)
203-
Write-Verbose "Token will expire at $expiryTime"
206+
Write-Verbose "Access token will expire at $expiryTime"
204207
}
208+
# store client credential as it will be needed to refresh the access token
209+
$newSession.Add('ClientCredential', $ClientCredential)
210+
205211
}
206212
else {
207213
# invoke-webrequest didn't throw an error, but we didn't get a token back either

0 commit comments

Comments
 (0)