PsDos.OktaSDK.psm1
function Add-OktaErrorExceptionMessage { param( $webException, $url, $message ) if($null -ne $webException.Response) { $stream = $webException.Response.GetResponseStream() $stream.Position = 0 $reader = [System.IO.StreamReader]::new($Stream) $responseJson = $reader.ReadToEnd() | ConvertFrom-Json | ConvertTo-Json } $retVal = "$message `n URL: $url `n Web Request Error: $($webException.Message) `n Response Body: $responseJson" return $retVal } <# .SYNOPSIS Returns [{ id = <appId>; name = <appName>; clientId = <client id>; secret = <client secret>; }, ...] OR { id = <appId>; name = <appName>; clientId = <client id>; secret = <client secret>; } Throws exception if failed .DESCRIPTION Reaches out to the specified Okta instance in $baseUrl and collects all applications according to the $appName parameter. Returns a list of Okta Application objects. See https://developer.okta.com/docs/reference/api/apps/#application-object .PARAMETER appName A name of the applications you want to retrieve. Okta will do wildcard matching on this, so partial names are accepted. .PARAMETER baseUrl The base url of the okta instance you're trying to hit .PARAMETER token$token the Okta SSWS token used to authenticate with the Okta API. #> function Get-OktaAppsByName { param( [string]$appName, [string]$baseUrl, [string]$token, [string]$tokenType ) if($tokenType -ne 'SSWS' -and $tokenType -ne 'Bearer') { throw 'tokenType must be either SSWS or Bearer' } $appsUrl = "$baseUrl/api/v1/apps?q=$appName" $headers = @{ 'Authorization' = "$tokenType $token"; 'Content-Type' = 'application/json'; 'Accept' = 'application/json'; } try { $response = Invoke-RestMethod -Uri $appsUrl -Method 'GET' -Headers $headers } catch { $errMsg = "Error getting existing Okta Applications" throw Add-OktaErrorExceptionMessage -webException $_.Exception -url $appsUrl -message $errMsg } $retVal = foreach($app in $response) { $retVal + @{ id = $app.id; name = $app.label; clientId = $app.credentials.oauthClient.client_id; secret = $app.credentials.oauthClient.client_secret; } } return $retVal } <# .SYNOPSIS Returns { id = <appId>; name = <appName>; clientId = <client id>; secret = <client secret>; } Throws exception if failed .DESCRIPTION Reaches out to the specified Okta instance in $baseUrl and retrieves one application according to the $appId parameter. Returns a single application object taking the form { appId = <id>; name = <name>; clientId = <client_id>; secret = <client_secret>; } The appId and client ID should always be the same .PARAMETER appId The Id of the application you want to retrieve. .PARAMETER baseUrl The base url of the okta instance you're trying to hit .PARAMETER token$token the Okta SSWS token used to authenticate with the Okta API. #> function Get-OktaAppById { param( [string]$appId, [string]$baseUrl, [string]$token, [string]$tokenType ) if($tokenType -ne 'SSWS' -and $tokenType -ne 'Bearer') { throw 'tokenType must be either SSWS or Bearer' } if([string]::IsNullOrEmpty($appId)){ throw "appId must not be empty" } $appsUrl = "$baseUrl/api/v1/apps/$appId" $headers = @{ 'Authorization' = "$tokenType $token"; 'Content-Type' = 'application/json'; 'Accept' = 'application/json'; } try { $response = Invoke-RestMethod -Uri $appsUrl -Method 'GET' -Headers $headers } catch { $errMsg = "Error getting existing Okta Applications" throw Add-OktaErrorExceptionMessage -webException $_.Exception -message $errMsg } return @{ id = $response.id; name = $response.label; clientId = $response.credentials.oauthClient.client_id; secret = $response.credentials.oauthClient.client_secret; } } function Add-OktaOIDCApplication { param( $oktaAppRequestBody, [string]$baseUrl, [string]$token, [string]$tokenType ) if($tokenType -ne 'SSWS' -and $tokenType -ne 'Bearer') { throw 'tokenType must be either SSWS or Bearer' } $appsUrl = "$baseUrl/api/v1/apps" $headers = @{ 'Authorization' = "$tokenType $token"; 'Content-Type' = 'application/json'; 'Accept' = 'application/json'; } $jsonBody = ConvertTo-Json -Depth 100 $oktaAppRequestBody try { $response = Invoke-RestMethod -Uri $appsUrl -Method 'POST' -Body $jsonBody -Headers $headers } catch { $errMsg = "Error creating an Okta Application" throw Add-OktaErrorExceptionMessage -webException $_.Exception -url $appsUrl -message $errMsg } $newApp = @{ id = $response.id; name = $response.label; clientId = $response.credentials.oauthClient.client_id; secret = $response.credentials.oauthClient.client_secret; } # Find the ID of the Everyone group in Okta. $groupUrl = "$baseUrl/api/v1/groups?q=everyone" try { $everyoneGroup = Invoke-RestMethod -Uri $groupUrl -Method 'GET' -Headers $headers } catch { $errMsg = "Error getting the Everyone Group from Okta" Add-OktaErrorExceptionMessage -webException $_.Exception -url $groupUrl -message $errMsg } # Associate the new app to the Everyone group $appGroupUrl = "$appsUrl/$($response.id)/groups/$($everyoneGroup.id)" try { Invoke-RestMethod -Uri $appGroupUrl -Method 'PUT' -Headers $headers | Out-Null } catch { $errMsg = "Error adding ${newApp.name} to the Everyone group" Add-OktaErrorExceptionMessage -webException $_.Exception -url $appGroupUrl -message $errMsg } return $newApp } function Update-OktaOIDCApplication { param( [string]$appId, $oktaAppRequestBody, [string]$baseUrl, [string]$token, [string]$tokenType ) if($tokenType -ne 'SSWS' -and $tokenType -ne 'Bearer') { throw 'tokenType must be either SSWS or Bearer' } if([string]::IsNullOrEmpty($appId)){ throw "appId must not be empty" } $appsUrl = "$baseUrl/api/v1/apps/$appId" $headers = @{ 'Authorization' = "$tokenType $token"; 'Content-Type' = 'application/json'; 'Accept' = 'application/json'; } $jsonBody = ConvertTo-Json -Depth 100 $oktaAppRequestBody try { $response = Invoke-RestMethod -Uri $appsUrl -Method 'PUT' -Body $jsonBody -Headers $headers } catch { $errMsg = "Error updating Okta application with id $appId" throw Add-OktaErrorExceptionMessage -webException $_.Exception -url $appsUrl -message $errMsg } $updatedApp = @{ id = $response.id; name = $response.label; clientId = $response.credentials.oauthClient.client_id; secret = $response.credentials.oauthClient.client_secret; } # Find the ID of the Everyone group in Okta. $groupUrl = "$baseUrl/api/v1/groups?q=everyone" try { $everyoneGroup = Invoke-RestMethod -Uri $groupUrl -Method 'GET' -Headers $headers } catch { $errMsg = "Error getting the Everyone Group from Okta" Add-OktaErrorExceptionMessage -webException $_.Exception -url $groupUrl -message $errMsg } # Associate the new app to the Everyone group $appGroupUrl = "$appsUrl/groups/$($everyoneGroup.id)" try { Invoke-RestMethod -Uri $appGroupUrl -Method 'PUT' -Headers $headers | Out-Null } catch { $errMsg = "Error adding ${newApp.name} to the Everyone group" Add-OktaErrorExceptionMessage -webException $_.Exception -url $appGroupUrl -message $errMsg } return $updatedApp } function Get-WebApplicationBody { return @{ name = 'oidc_client'; label = ''; signOnMode = 'OPENID_CONNECT'; credentials = @{ userNameTemplate = @{ template = '${source.login}'; type = 'BUILT_IN'; }; oauthClient = @{ autoKeyRotation = $true; token_endpoint_auth_method = "client_secret_basic"; } }; settings = @{ oauthClient = @{ initiate_login_uri = ''; client_uri = $null; logo_uri = $null; redirect_uris = ''; post_logout_redirect_uris = ''; response_types = @('code', 'token', 'id_token'); grant_types = @('implicit','client_credentials','refresh_token','authorization_code'); application_type = 'web'; consent_method = 'TRUSTED'; issuer_mode = 'ORG_URL'; } } } } <# .SYNOPSIS Creates an Okta OIDC Application with type WEB. Returns { id = <appId>; name = <appName>; clientId = <client id>; secret = <client secret>; } throws exception if failed .DESCRIPTION Creates an OIDC application in okta that can use client_credentials, code, and implicit flows. This is usually reserved for serverside rendered web application .PARAMETER appName name of the application you want to create .PARAMETER redirectUris URIs that you want to redirect back to after authenticating with Okta .PARAMETER logoutUris URIs that you want to navigate to upon logging out of Okta .PARAMETER baseUrl the url of the Okta instance you want to hit .PARAMETER token$token the Okta SSWS token used to authenticate with the Okta API #> function Add-OktaOIDCWebApp { param( [string]$appName, [System.Array]$redirectUris, [System.Array]$logoutUris, [string]$baseUrl, [string]$token, [string]$tokenType ) if($tokenType -ne 'SSWS' -and $tokenType -ne 'Bearer') { throw 'tokenType must be either SSWS or Bearer' } Write-Host "***********Adding web application************" $body = Get-WebApplicationBody $body['label'] = $appName $body['settings']['oauthClient']['redirect_uris'] = $redirectUris $body['settings']['oauthClient']['post_logout_redirect_uris'] = $logoutUris return Add-OktaOIDCApplication ` -oktaAppRequestBody $body ` -baseUrl $baseUrl ` -token $token ` -tokenType $tokenType } <# .SYNOPSIS Updates an Okta OIDC Application with type WEB. Returns { id = <appId>; name = <appName>; clientId = <client id>; secret = <client secret>; } Returns $null if failed .DESCRIPTION Updates an Okta OIDC Application with type WEB .PARAMETER appId id of the application you wish to update .PARAMETER appName new name of the application .PARAMETER redirectUris new redirect URIs for the application .PARAMETER logoutUris new logout redirect URIs for the application .PARAMETER baseUrl the url of the Okta instance you want to hit .PARAMETER token$token the Okta SSWS token used to authenticate with the Okta API #> function Update-OktaOIDCWebApp { param( [string]$appId, [string]$appName, [System.Array]$redirectUris, [System.Array]$logoutUris, [string]$baseUrl, [string]$token, [string]$tokenType ) if($tokenType -ne 'SSWS' -and $tokenType -ne 'Bearer') { throw 'tokenType must be either SSWS or Bearer' } if([string]::IsNullOrEmpty($appId)){ throw "appId must not be empty" } Write-Host "***********Updating web application************" $body = Get-WebApplicationBody $body['label'] = $appName $body['settings']['oauthClient']['redirect_uris'] = $redirectUris $body['settings']['oauthClient']['post_logout_redirect_uris'] = $logoutUris $body['credentials']['oauthClient']['client_id'] = $appId return Update-OktaOIDCApplication ` -appId $appId ` -oktaAppRequestBody $body ` -baseUrl $baseUrl ` -token $token ` -tokenType $tokenType } function Get-SpaApplicationBody { @{ name = 'oidc_client'; label = ''; signOnMode = 'OPENID_CONNECT'; credentials = @{ userNameTemplate = @{ template = '${source.login}'; type = 'BUILT_IN'; }; oauthClient = @{ autoKeyRotation = $true; token_endpoint_auth_method = "none"; } }; settings = @{ oauthClient = @{ client_uri = $null; logo_uri = $null; redirect_uris = ''; post_logout_redirect_uris = ''; response_types = @('code'); grant_types = @('authorization_code'); initiate_login_uri = ''; application_type = 'browser'; consent_method = 'TRUSTED'; issuer_mode = 'ORG_URL'; } } } } <# .SYNOPSIS Returns { id = <appId>; name = <appName>; clientId = <client id>; secret = <client secret>; } Returns $null if failed .DESCRIPTION Creates an OIDC application in okta that can use code+PKCE, and implicit flows. This should be used for Single Page Applications .PARAMETER appName name of the application you want to create .PARAMETER redirectUris URIs that you want to redirect back to after authenticating with Okta .PARAMETER logoutUris URIs that you want to navigate to upon logging out of Okta .PARAMETER baseUrl the url of the Okta instance you want to hit .PARAMETER token$token the Okta SSWS token used to authenticate with the Okta API #> function Add-OktaOIDCSinglePageApp { param( [string]$appName, [System.Array]$redirectUris, [System.Array]$logoutUris, [string]$baseUrl, [string]$token, [string]$tokenType ) if($tokenType -ne 'SSWS' -and $tokenType -ne 'Bearer') { throw 'tokenType must be either SSWS or Bearer' } Write-Host "***********Adding client Single Page application************" $body = Get-SpaApplicationBody $body['label'] = $appName $body['settings']['oauthClient']['redirect_uris'] = $redirectUris $body['settings']['oauthClient']['post_logout_redirect_uris'] = $logoutUris return Add-OktaOIDCApplication ` -oktaAppRequestBody $body ` -baseUrl $baseUrl ` -token $token ` -tokenType $tokenType } <# .SYNOPSIS Updates an Okta OIDC Application with type SPA. Returns { id = <appId>; name = <appName>; clientId = <client id>; secret = <client secret>; } Returns $null if failed .DESCRIPTION Updates an Okta OIDC Application with type SPA .PARAMETER appId id of the SPA application you wish to update .PARAMETER appName new name of the application .PARAMETER redirectUris new redirect URIs for the application .PARAMETER logoutUris new logout redirect URIs for the application .PARAMETER baseUrl the url of the Okta instance you want to hit .PARAMETER token$token the Okta SSWS token used to authenticate with the Okta API #> function Update-OktaOIDCSinglePageApp { param( [string]$appId, [string]$appName, [System.Array]$redirectUris, [System.Array]$logoutUris, [string]$baseUrl, [string]$token, [string]$tokenType ) if($tokenType -ne 'SSWS' -and $tokenType -ne 'Bearer') { throw 'tokenType must be either SSWS or Bearer' } if([string]::IsNullOrEmpty($appId)){ throw "appId must not be empty" } Write-Host "***********Updating client Single Page application************" $body = Get-SpaApplicationBody $body['label'] = $appName $body['settings']['oauthClient']['redirect_uris'] = $redirectUris $body['settings']['oauthClient']['post_logout_redirect_uris'] = $logoutUris $body['credentials']['oauthClient']['client_id'] = $appId return Update-OktaOIDCApplication ` -appId $appId ` -oktaAppRequestBody $body ` -baseUrl $baseUrl ` -token $token ` -tokenType $tokenType } function Get-ClientCredentialsApplicationBody { return @{ name = 'oidc_client'; label = ''; signOnMode = 'OPENID_CONNECT'; credentials = @{ userNameTemplate = @{ template = '${source.login}'; type = 'BUILT_IN'; }; oauthClient = @{ autoKeyRotation = $true; token_endpoint_auth_method = "client_secret_basic"; } }; settings = @{ oauthClient = @{ client_uri = $null; logo_uri = $null; response_types = @('token'); grant_types = @('client_credentials'); application_type = 'service'; issuer_mode = 'ORG_URL'; } } } } <# .SYNOPSIS Creates an Okta OIDC Application with type Service. Returns { id = <appId>; name = <appName>; clientId = <client id>; secret = <client secret>; } Returns $null if failed .DESCRIPTION Creates an OIDC application in okta that can use client credentials flow. This should be used for Machine To Machine applications that don't have a user context .PARAMETER appName name of the application you want to create .PARAMETER baseUrl the url of the Okta instance you want to hit .PARAMETER token$token the Okta SSWS token used to authenticate with the Okta API #> function Add-OktaClientCredentialsApp { param( [string]$appName, [string]$baseUrl, [string]$token, [string]$tokenType ) if($tokenType -ne 'SSWS' -and $tokenType -ne 'Bearer') { throw 'tokenType must be either SSWS or Bearer' } Write-Host "***********Adding client credentials application************" $body = Get-ClientCredentialsApplicationBody $body['label'] = $appName return Add-OktaOIDCApplication ` -oktaAppRequestBody $body ` -baseUrl $baseUrl ` -token $token ` -tokenType $tokenType } <# .SYNOPSIS Updates an Okta OIDC Application with type Service. Returns { id = <appId>; name = <appName>; clientId = <client id>; secret = <client secret>; } Returns $null if failed .DESCRIPTION Updates an Okta OIDC Application with type Service .PARAMETER appId id of the SPA application you wish to update .PARAMETER appName new name of the application .PARAMETER baseUrl the url of the Okta instance you want to hit .PARAMETER token$token the Okta SSWS token used to authenticate with the Okta API #> function Update-OktaClientCredentialsApp { param( [string]$appId, [string]$appName, [string]$baseUrl, [string]$token, [string]$tokenType ) if($tokenType -ne 'SSWS' -and $tokenType -ne 'Bearer') { throw 'tokenType must be either SSWS or Bearer' } if([string]::IsNullOrEmpty($appId)){ throw "appId must not be empty" } Write-Host "***********Updating client credentials application************" $body = Get-ClientCredentialsApplicationBody $body['label'] = $appName $body['credentials']['oauthClient']['client_id'] = $appId return Update-OktaOIDCApplication ` -appId $appId ` -oktaAppRequestBody $body ` -baseUrl $baseUrl ` -token $token ` -tokenType $tokenType } <# .SYNOPSIS Deletes and Okta application by ID. Returns $true if passed Returns $false if failed .DESCRIPTION Deletes and Okta application by ID .PARAMETER appId Id of the application you want to delete. Can be the Raw ID or Client Id .PARAMETER baseUrl The base url of the okta instance you're trying to hit. .PARAMETER token$token the Okta SSWS Token used to authenticate with the API #> function Remove-OktaApp { param( [string]$appId, [string]$baseUrl, [string]$token, [string]$tokenType ) if($tokenType -ne 'SSWS' -and $tokenType -ne 'Bearer') { throw 'tokenType must be either SSWS or Bearer' } if([string]::IsNullOrEmpty($appId)){ throw "appId must not be empty" } $appsUrl = "$baseUrl/api/v1/apps/$appId" $headers = @{ 'Authorization' = "$tokenType $token"; 'Content-Type' = 'application/json'; 'Accept' = 'application/json'; } try { Invoke-RestMethod -Uri $appsUrl -Method 'DELETE' -Headers $headers } catch { $errMsg = "Error deleting Okta Application with Id $appId" throw Add-OktaErrorExceptionMessage -webException $_.Exception -url $appsUrl -message $errMsg } Write-Host "Successfully deleted Okta application" return $true } <# .SYNOPSIS Returns [{ id = <id>; name = <name>; audiences = []; issuer = <issuer>; status = <status>; }, ...] OR { id = <id>; name = <name>; audiences = []; issuer = <issuer>; status = <status>; } Throws exception if failed .DESCRIPTION Retrieves a list of Okta Authorization Servers by their names. This does wildcard matching, so partial names are accepted. .PARAMETER authServerName Name of the auth servers you want to find. .PARAMETER baseUrl base url of the Okta instance you want to hit .PARAMETER token$token Okta SSWS token that you would use to authenticate with the Okta API #> function Get-OktaAuthorizationServersByName { param( [string]$authServerName, [string]$baseUrl, [string]$token, [string]$tokenType ) if($tokenType -ne 'SSWS' -and $tokenType -ne 'Bearer') { throw 'tokenType must be either SSWS or Bearer' } if([string]::IsNullOrEmpty($authServerName)){ throw "authServerName must not be empty" } $baseUrl = "$baseUrl/api/v1/authorizationServers?q=$authServerName" $headers = @{ 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Authorization' = "$tokenType $token" } try { $authServers = Invoke-RestMethod -Uri $baseUrl -Method 'GET' -Headers $headers } catch { $errMsg = "Error finding the authorization server $authServerName" throw Add-OktaErrorExceptionMessage -webException $_.Exception -url $baseUrl -message $errMsg } $retVal = foreach($authServer in $authServers) { $retVal + @{ id = $authServer.id; name = $authServer.name; audiences = $authServer.audiences; issuer = $authServer.issuer; status = $authServer.status; } } return $retVal } <# .SYNOPSIS Returns { id = <id>; name = <name>; audiences = []; issuer = <issuer>; status = <status>; } Throws exception if failed .DESCRIPTION Retrieves a single Okta Authorization Server by it's ID taking the form { id = <id>; name = <name>; audiences = <audiences>; issuer = <issuer>; status = <status>; } .PARAMETER authServerId ID of the auth servers you want to find. .PARAMETER baseUrl base url of the Okta instance you want to hit .PARAMETER token$token Okta SSWS token that you would use to authenticate with the Okta API #> function Get-OktaAuthorizationServerById { param( [string]$authServerId, [string]$baseUrl, [string]$token, [string]$tokenType ) if($tokenType -ne 'SSWS' -and $tokenType -ne 'Bearer') { throw 'tokenType must be either SSWS or Bearer' } if([string]::IsNullOrEmpty($authServerId)){ throw "authServerId must not be empty" } $baseUrl = "$baseUrl/api/v1/authorizationServers/$authServerId" $headers = @{ 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Authorization' = "$tokenType $token" } try { $authServer = Invoke-RestMethod -Uri $baseUrl -Method 'GET' -Headers $headers } catch { $errMsg = "Error getting auth server with id $authServerId" throw Add-OktaErrorExceptionMessage -webException $_.Exception -url $baseUrl -message $errMsg } return @{ id = $authServer.id; name = $authServer.name; audiences = $authServer.audiences; issuer = $authServer.issuer; status = $authServer.status; } } <# .SYNOPSIS Returns [{ id = <scope id>; name = <scope name>; }, ...] OR { id = <scope id>; name = <scope name>; } Throws exception on error .DESCRIPTION Retrieves a list of Okta Authorization Server Scopes by their names. This does wildcard matching, so partial names are accepted. .PARAMETER authServerId Id of the auth server you're trying to hit .PARAMETER scopeName Name of the auth server scopes you want to find. .PARAMETER baseUrl base url of the Okta instance you want to hit .PARAMETER token$token Okta SSWS token that you would use to authenticate with the Okta API #> function Get-OktaAuthorizationServerScopesByName { param( [string]$authServerId, [string]$scopeName, [string]$baseUrl, [string]$token, [string]$tokenType ) if($tokenType -ne 'SSWS' -and $tokenType -ne 'Bearer') { throw 'tokenType must be either SSWS or Bearer' } if([string]::IsNullOrEmpty($authServerId)){ throw "authServerId must not be empty" } if([string]::IsNullOrEmpty($scopeName)){ throw "scopeName must not be empty" } $baseUrl = "$baseUrl/api/v1/authorizationServers/$authServerId/scopes?q=$scopeName" $headers = @{ 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Authorization' = "$tokenType $token" } try { $scopes = Invoke-RestMethod -Uri $baseUrl -Method 'GET' -Headers $headers } catch { $errMsg = "Error getting auth server scopes with name $scopeName" throw Add-OktaErrorExceptionMessage -webException $_.Exception -url $baseUrl -message $errMsg } $retVal = foreach($scope in $scopes) { @{ id = $scope.id; name = $scope.name; } } return $retVal } <# .SYNOPSIS Returns { id = <scope id>; name = <scope name>; } Throws exception on error .DESCRIPTION Retrieves a single Okta Authorization Server Scope by it's ID. .PARAMETER authServerId Id of the auth server you're trying to hit .PARAMETER scopeId Id of the auth server scope you want to find. .PARAMETER baseUrl base url of the Okta instance you want to hit .PARAMETER token$token Okta SSWS token that you would use to authenticate with the Okta API #> function Get-OktaAuthorizationServerScopesById { param( [string]$authServerId, [string]$scopeId, [string]$baseUrl, [string]$token, [string]$tokenType ) if($tokenType -ne 'SSWS' -and $tokenType -ne 'Bearer') { throw 'tokenType must be either SSWS or Bearer' } if([string]::IsNullOrEmpty($authServerId)){ throw "authServerId must not be empty" } if([string]::IsNullOrEmpty($scopeId)){ throw "scopeId must not be empty" } $baseUrl = "$baseUrl/api/v1/authorizationServers/$authServerId/scopes/$scopeId" $headers = @{ 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Authorization' = "$tokenType $token" } try { $scope = Invoke-RestMethod -Uri $baseUrl -Method 'GET' -Headers $headers } catch { $errMsg = "Error getting auth server scopes with id $scopeId" throw Add-OktaErrorExceptionMessage -webException $_.Exception -url $baseUrl -message $errMsg } return @{ id = $scope.id; name = $scope.name; } } <# .SYNOPSIS Returns { id = <scope id>; name = <scope name>; } Throws exception on error .DESCRIPTION Creates a single Okta Authorization Server Scope .PARAMETER authServerId Id of the auth server you want to add the scope to .PARAMETER scopeName Name of the scope .PARAMETER description Description of what the scope is for .PARAMETER baseUrl Base url of the okta instance you're trying to hit .PARAMETER token$token Okta SSWS token used to authenticate with the Okta API #> function Add-OktaAuthorizationServerScope { param( [string]$authServerId, [string]$scopeName, [string]$description, [string]$baseUrl, [string]$token, [string]$tokenType ) if($tokenType -ne 'SSWS' -and $tokenType -ne 'Bearer') { throw 'tokenType must be either SSWS or Bearer' } if([string]::IsNullOrEmpty($authServerId)){ throw "authServerId must not be empty" } $scopeUrl = "$baseUrl/api/v1/authorizationServers/$authServerId/scopes" $headers = @{ 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Authorization' = "$tokenType $token" } $body = @{ name = $scopeName; description = $description; system = $false; default = $false; displayName = $scopeName; consent = 'IMPLICIT'; metadataPublish = 'ALL_CLIENTS'; } $jsonBody = ConvertTo-Json $body try { $response = Invoke-RestMethod -Uri $scopeUrl -Method 'POST' -Body $jsonBody -Headers $headers } catch { $errMsg = "Error creating scope on authorization server with id $authServerId" throw Add-OktaErrorExceptionMessage -webException $_.Exception -url $scopeUrl -message $errMsg } return @{ id = $response.id; name = $response.name; } } <# .SYNOPSIS Returns { id = <scope id>; name = <scope name>; } Throws exception on error .DESCRIPTION Updates a single Okta Authorization Server Scope .PARAMETER authServerId Id of the auth server where the scope resides .PARAMETER scopeId Id of the scope you wish to change .PARAMETER scopeName New name of the scope .PARAMETER description New description of what the scope is for .PARAMETER baseUrl Base url of the okta instance you're trying to hit .PARAMETER token$token Okta SSWS token used to authenticate with the Okta API #> function Update-OktaAuthorizationServerScope { param( [string]$authServerId, [string]$scopeId, [string]$scopeName, [string]$description, [string]$baseUrl, [string]$token, [string]$tokenType ) if($tokenType -ne 'SSWS' -and $tokenType -ne 'Bearer') { throw 'tokenType must be either SSWS or Bearer' } if([string]::IsNullOrEmpty($authServerId)){ throw "authServerId must not be empty" } if([string]::IsNullOrEmpty($scopeId)){ throw "scopeId must not be empty" } $scopeUrl = "$baseUrl/api/v1/authorizationServers/$authServerId/scopes/$scopeId" $headers = @{ 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Authorization' = "$tokenType $token" } $body = @{ name = $scopeName; description = $description; system = $false; default = $false; displayName = $scopeName; consent = 'IMPLICIT'; metadataPublish = 'ALL_CLIENTS'; } $jsonBody = ConvertTo-Json $body try { $response = Invoke-RestMethod -Uri $scopeUrl -Method 'PUT' -Body $jsonBody -Headers $headers } catch { $errMsg = "Error updating scope on authorization server with id $authServerId" throw Add-OktaErrorExceptionMessage -webException $_.Exception -url $scopeUrl -message $errMsg } return @{ id = $response.id; name = $response.name; } } <# .SYNOPSIS Returns $true if passed Returns $false if failed .DESCRIPTION Removes a single scope from an Okta Authorization Server .PARAMETER authServerId Id of the authorization server you wish to remove the scope from .PARAMETER scopeId Id of the scope you wish to remove .PARAMETER baseUrl Base url of the Okta instance you wish to hit .PARAMETER token$token Okta SSWS token used to authenticate with the Okta API #> function Remove-OktaAuthorizationServerScope { param( [string]$authServerId, [string]$scopeId, [string]$baseUrl, [string]$token, [string]$tokenType ) if($tokenType -ne 'SSWS' -and $tokenType -ne 'Bearer') { throw 'tokenType must be either SSWS or Bearer' } if([string]::IsNullOrEmpty($authServerId)){ throw "authServerId must not be empty" } if([string]::IsNullOrEmpty($scopeId)){ throw "scopeId must not be empty" } $scopeUrl = "$baseUrl/api/v1/authorizationServers/$authServerId/scopes/$scopeId" $headers = @{ 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Authorization' = "$tokenType $token" } try { Invoke-RestMethod -Uri $scopeUrl -Method 'DELETE' -Headers $headers } catch { $errMsg = "Error deleting scope on authorization server with id $authServerId" throw Add-OktaErrorExceptionMessage -webException $_.Exception -url $scopeUrl -message $errMsg } Write-Host "Successfully deleted Okta scope on auth server with id $authServerId" } Export-ModuleMember -Function Get-OktaAppsByName Export-ModuleMember -Function Get-OktaAppById Export-ModuleMember -Function Add-OktaClientCredentialsApp Export-ModuleMember -Function Add-OktaOIDCSinglePageApp Export-ModuleMember -Function Add-OktaOIDCWebApp Export-ModuleMember -Function Update-OktaClientCredentialsApp Export-ModuleMember -Function Update-OktaOIDCSinglePageApp Export-ModuleMember -Function Update-OktaOIDCWebApp Export-ModuleMember -Function Update-OktaAuthorizationServerScope Export-ModuleMember -Function Add-OktaAuthorizationServerScope Export-ModuleMember -Function Get-OktaAuthorizationServerById Export-ModuleMember -Function Get-OktaAuthorizationServersByName Export-ModuleMember -Function Get-OktaAuthorizationServerScopesByName Export-ModuleMember -Function Get-OktaAuthorizationServerScopesById Export-ModuleMember -Function Remove-OktaAuthorizationServerScope Export-ModuleMember -Function Get-OktaAccessToken # SIG # Begin signature block # MIIcSQYJKoZIhvcNAQcCoIIcOjCCHDYCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDNikSXy7NIbWRy # LJAn9z5xVF4ia46N69PqOK28+ju5/qCCCqMwggUwMIIEGKADAgECAhAECRgbX9W7 # ZnVTQ7VvlVAIMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV # BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBa # Fw0yODEwMjIxMjAwMDBaMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy # dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lD # ZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3 # DQEBAQUAA4IBDwAwggEKAoIBAQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/l # qJ3bMtdx6nadBS63j/qSQ8Cl+YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fT # eyOU5JEjlpB3gvmhhCNmElQzUHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqH # CN8M9eJNYBi+qsSyrnAxZjNxPqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+ # bMt+dDk2DZDv5LVOpKnqagqrhPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLo # LFH3c7y9hbFig3NBggfkOItqcyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIB # yTASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAK # BggrBgEFBQcDAzB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9v # Y3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGln # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHow # eDA6oDigNoY0aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJl # ZElEUm9vdENBLmNybDA6oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0Rp # Z2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwA # AgQwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAK # BghghkgBhv1sAzAdBgNVHQ4EFgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0j # BBgwFoAUReuir/SSy4IxLVGLp6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7s # DVoks/Mi0RXILHwlKXaoHV0cLToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGS # dQ9RtG6ljlriXiSBThCk7j9xjmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6 # r7VRwo0kriTGxycqoSkoGjpxKAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo # +MUSaJ/PQMtARKUT8OZkDCUIQjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qz # sIzV6Q3d9gEgzpkxYz0IGhizgZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHq # aGxEMrJmoecYpJpkUe8wggVrMIIEU6ADAgECAhAMMCpTLsjxo9FR9hag8ePUMA0G # CSqGSIb3DQEBCwUAMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ # bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0 # IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EwHhcNMjAwMzMxMDAwMDAw # WhcNMjMwNTEwMTIwMDAwWjCBpzELMAkGA1UEBhMCVVMxDTALBgNVBAgTBFV0YWgx # FzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVIZWFsdGggQ2F0YWx5 # c3QsIEluYy4xHjAcBgNVBAMTFUhlYWx0aCBDYXRhbHlzdCwgSW5jLjEwMC4GCSqG # SIb3DQEJARYhYWRtaW5uaXN0cmF0b3JAaGVhbHRoY2F0YWx5c3QuY29tMIIBIjAN # BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2fY0HWdxDJezDOsbHp7f9u/lrrD5 # nuZ1mENMgvixlrtC/KXgBRXlcWH7ajIOKljKnWCSAZwlZy4nFGbMagKmMzohXUXg # xo94u5nCdiBa/kgPazNGpL0AyGgX2VARMbcpm8Gdy+/uH3Kc7L91lcoGZVVBnVIt # 1oj5iXURqmhL83TrMyYqyj3XOH0So8Y10FVLPSukocMzMqBIRgvn/7EP0iWtOjXx # +o1wB5Ql+z9G3NCqF6CKE/Pn355XYbbmjF7BPzKoOjocHO6VU2uEflJWq1ZFb0QY # /tAosyyLYi9kFfO1damtJfRbbsVqavwg2UeQkzhg9CpB6eSsmBXPlFHudQIDAQAB # o4IBxTCCAcEwHwYDVR0jBBgwFoAUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHQYDVR0O # BBYEFFjfHOOIre2C4m9NCk8TFJlDwMxUMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUE # DDAKBggrBgEFBQcDAzB3BgNVHR8EcDBuMDWgM6Axhi9odHRwOi8vY3JsMy5kaWdp # Y2VydC5jb20vc2hhMi1hc3N1cmVkLWNzLWcxLmNybDA1oDOgMYYvaHR0cDovL2Ny # bDQuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwTAYDVR0gBEUw # QzA3BglghkgBhv1sAwEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNl # cnQuY29tL0NQUzAIBgZngQwBBAEwgYQGCCsGAQUFBwEBBHgwdjAkBggrBgEFBQcw # AYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tME4GCCsGAQUFBzAChkJodHRwOi8v # Y2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyQXNzdXJlZElEQ29kZVNp # Z25pbmdDQS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAQEAsBxn # 9yJAQi+9cJPZpJvOEV6iHaOBGv8898wNJCc4eB5g8WPziEY70GZVeqEdx3z0wS8U # QQIr19Hkju2NFZjDtzB9z1jAc/9EgqFGoCZbPijv1EYAa2oOVAp1BPbLjqBSdXqu # 2mzqo14CJ30oNom9ep9F6LGZ5zEoPsMrJejSbJGr4EacrksX8C8qeFklc7FzwiGk # GX7IQxidrrhOm2fOvGGAAxnvNYAR0FqJK0LiWWPSt5R/j63H/6HQtqD2sLevI3+O # bRP74TPchDobFmWlSogX9oB63E7fsbDAqecY0cRPQ6tVWK53Ke2sB514nahFjZDa # mxsa3/acZWL659ly3jGCEPwwghD4AgEBMIGGMHIxCzAJBgNVBAYTAlVTMRUwEwYD # VQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAv # BgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EC # EAwwKlMuyPGj0VH2FqDx49QwDQYJYIZIAWUDBAIBBQCgfDAQBgorBgEEAYI3AgEM # MQIwADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4w # DAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgkLTDOrnVHkrHcgYOgp3WH30N # bWe5Y07xgpySlMemWcQwDQYJKoZIhvcNAQEBBQAEggEATGMQ+69SSc3K7avLGh9h # HpLpjVhW15MqsRMwbcDXa6kk+z0EbJIugGc5gpig0Rr1GT8lGvyQZEn9tb7O43pC # +bYHliMxKcbt6/5CrmJwL921gn5tCKNoRXBnXe0Hu7tTVDL8+QmMnwRWqllNNv96 # WJx0otxfcVlVwbbftA+pg6tZQLWjLkGyDJeq9mQ9ZQB6TpanPCE97DW77Rl1m8Mb # Q3wdD860apywC0UqXqiZxTIuTLOxEa+tehuh5OVg1ZEiMy/rTSz/FmJGclBXwAER # ERSq6iXsd8Qxn+ycF9+LQ9HbrFhUZIkJmidUxVYLCiu8wSsKP6SIoCCjNZf0agKs # PaGCDsgwgg7EBgorBgEEAYI3AwMBMYIOtDCCDrAGCSqGSIb3DQEHAqCCDqEwgg6d # AgEDMQ8wDQYJYIZIAWUDBAIBBQAwdwYLKoZIhvcNAQkQAQSgaARmMGQCAQEGCWCG # SAGG/WwHATAxMA0GCWCGSAFlAwQCAQUABCBwIkpCgXMsdps5Uik/czQBMucTB+3p # ShbbcRBDHM0bdQIQcDAsNY2a+yI7SJHOSpmnBxgPMjAyMDEyMTQxODA4MTJaoIIL # uzCCBoIwggVqoAMCAQICEATNP4VornbGG7D+cWDMp20wDQYJKoZIhvcNAQELBQAw # cjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ # d3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVk # IElEIFRpbWVzdGFtcGluZyBDQTAeFw0xOTEwMDEwMDAwMDBaFw0zMDEwMTcwMDAw # MDBaMEwxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjEkMCIG # A1UEAxMbVElNRVNUQU1QLVNIQTI1Ni0yMDE5LTEwLTE1MIIBIjANBgkqhkiG9w0B # AQEFAAOCAQ8AMIIBCgKCAQEA6WQ1nPqpmGVkG+QX3LgpNsxnCViFTTDgyf/lOzwR # KFCvBzHiXQkYwvaJjGkIBCPgdy2dFeW46KFqjv/UrtJ6Fu/4QbUdOXXBzy+nrEV+ # lG2sAwGZPGI+fnr9RZcxtPq32UI+p1Wb31pPWAKoMmkiE76Lgi3GmKtrm7TJ8mUR # DHQNsvAIlnTE6LJIoqEUpfj64YlwRDuN7/uk9MO5vRQs6wwoJyWAqxBLFhJgC2ki # jE7NxtWyZVkh4HwsEo1wDo+KyuDT17M5d1DQQiwues6cZ3o4d1RA/0+VBCDU68jO # hxQI/h2A3dDnK3jqvx9wxu5CFlM2RZtTGUlinXoCm5UUowIDAQABo4IDODCCAzQw # DgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYB # BQUHAwgwggG/BgNVHSAEggG2MIIBsjCCAaEGCWCGSAGG/WwHATCCAZIwKAYIKwYB # BQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwggFkBggrBgEFBQcC # AjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgAaQBzACAAQwBlAHIA # dABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQAZQBzACAAYQBjAGMA # ZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcAaQBDAGUAcgB0ACAA # QwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwAeQBpAG4AZwAgAFAA # YQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkAYwBoACAAbABpAG0A # aQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEAcgBlACAAaQBuAGMA # bwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIAeQAgAHIAZQBmAGUA # cgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMB8GA1UdIwQYMBaAFPS24SAd/imu0uRh # pbKiJbLIFzVuMB0GA1UdDgQWBBRWUw/BxgenTdfYbldygFBM5OyewTBxBgNVHR8E # ajBoMDKgMKAuhixodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVk # LXRzLmNybDAyoDCgLoYsaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItYXNz # dXJlZC10cy5jcmwwgYUGCCsGAQUFBwEBBHkwdzAkBggrBgEFBQcwAYYYaHR0cDov # L29jc3AuZGlnaWNlcnQuY29tME8GCCsGAQUFBzAChkNodHRwOi8vY2FjZXJ0cy5k # aWdpY2VydC5jb20vRGlnaUNlcnRTSEEyQXNzdXJlZElEVGltZXN0YW1waW5nQ0Eu # Y3J0MA0GCSqGSIb3DQEBCwUAA4IBAQAug6FEBUoE47kyUvrZgfAau/gJjSO5PdiS # oeZGHEovbno8Y243F6Mav1gjskOclINOOQmwLOjH4eLM7ct5a87eIwFH7ZVUgeCA # exKxrwKGqTpzav74n8GN0SGM5CmCw4oLYAACnR9HxJ+0CmhTf1oQpvgi5vhTkjFf # 2IKDLW0TQq6DwRBOpCT0R5zeDyJyd1x/T+k5mCtXkkTX726T2UPHBDNjUTdWnkcE # EcOjWFQh2OKOVtdJP1f8Cp8jXnv0lI3dnRq733oqptJFplUMj/ZMivKWz4lG3DGy # kZCjXzMwYFX1/GswrKHt5EdOM55naii1TcLtW5eC+MupCGxTCbT3MIIFMTCCBBmg # AwIBAgIQCqEl1tYyG35B5AXaNpfCFTANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG # EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl # cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcN # MTYwMTA3MTIwMDAwWhcNMzEwMTA3MTIwMDAwWjByMQswCQYDVQQGEwJVUzEVMBMG # A1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEw # LwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQgSUQgVGltZXN0YW1waW5nIENB # MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvdAy7kvNj3/dqbqCmcU5 # VChXtiNKxA4HRTNREH3Q+X1NaH7ntqD0jbOI5Je/YyGQmL8TvFfTw+F+CNZqFAA4 # 9y4eO+7MpvYyWf5fZT/gm+vjRkcGGlV+Cyd+wKL1oODeIj8O/36V+/OjuiI+GKwR # 5PCZA207hXwJ0+5dyJoLVOOoCXFr4M8iEA91z3FyTgqt30A6XLdR4aF5FMZNJCMw # XbzsPGBqrC8HzP3w6kfZiFBe/WZuVmEnKYmEUeaC50ZQ/ZQqLKfkdT66mA+Ef58x # FNat1fJky3seBdCEGXIX8RcG7z3N1k3vBkL9olMqT4UdxB08r8/arBD13ays6Vb/ # kwIDAQABo4IBzjCCAcowHQYDVR0OBBYEFPS24SAd/imu0uRhpbKiJbLIFzVuMB8G # A1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMBIGA1UdEwEB/wQIMAYBAf8C # AQAwDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHkGCCsGAQUF # BwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMG # CCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRB # c3N1cmVkSURSb290Q0EuY3J0MIGBBgNVHR8EejB4MDqgOKA2hjRodHRwOi8vY3Js # NC5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMDqgOKA2 # hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290 # Q0EuY3JsMFAGA1UdIARJMEcwOAYKYIZIAYb9bAACBDAqMCgGCCsGAQUFBwIBFhxo # dHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAsGCWCGSAGG/WwHATANBgkqhkiG # 9w0BAQsFAAOCAQEAcZUS6VGHVmnN793afKpjerN4zwY3QITvS4S/ys8DAv3Fp8MO # IEIsr3fzKx8MIVoqtwU0HWqumfgnoma/Capg33akOpMP+LLR2HwZYuhegiUexLoc # eywh4tZbLBQ1QwRostt1AuByx5jWPGTlH0gQGF+JOGFNYkYkh2OMkVIsrymJ5Xgf # 1gsUpYDXEkdws3XVk4WTfraSZ/tTYYmo9WuWwPRYaQ18yAGxuSh1t5ljhSKMYcp5 # lH5Z/IwP42+1ASa2bKXuh1Eh5Fhgm7oMLSttosR+u8QlK0cCCHxJrhO24XxCQijG # GFbPQTS2Zl22dHv1VjMiLyI2skuiSpXY9aaOUjGCAk0wggJJAgEBMIGGMHIxCzAJ # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k # aWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBU # aW1lc3RhbXBpbmcgQ0ECEATNP4VornbGG7D+cWDMp20wDQYJYIZIAWUDBAIBBQCg # gZgwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0y # MDEyMTQxODA4MTJaMCsGCyqGSIb3DQEJEAIMMRwwGjAYMBYEFAMlvVBe2pYwLcIv # T6AeTCi+KDTFMC8GCSqGSIb3DQEJBDEiBCCNwVhU8QhRNcBRSEfr6gj0y071Y5yl # cnfa0I0hrzt3hjANBgkqhkiG9w0BAQEFAASCAQBB4L3sC2u7C1uwWaAkaDLD8Y1v # 2QlzmQZNlOOfccZ6KCteQnA5cU71G2bwhMD1NlgmdEFS3EUB+XEGknNr9kQhMWkZ # 2JfotiiAwfKxHjnaOK6hGVwq5i/WIabGgooFf+Jrn9j0iTfuH4G2sQkighn04R21 # gjnD6mcbRqBjFY8QZpAprF9HEwaWYtzPkmkJAqspyNL0lZ2oLzt0UwhYB7HPTdU4 # wSoeA0faqKrT0stUFgUMTypjSHBhH+jTl0mzg4EdE7cGF10q4VvbOgqt0kREFDDo # QqSoGYCVY2jSBk6RhdBU3BzomdlqWMnziHiR+5lxdzLQrso2OP9ID5759jXD # SIG # End signature block |