Skip to content

Commit

Permalink
Adfs activity cmdlets (#24)
Browse files Browse the repository at this point in the history
* import adfs samples

* access control policy fix

* help messages

* cmdlets examples update

* fix access policy assignment

* fix example for import-msidadfssampleapp
  • Loading branch information
marcusca10 authored Oct 4, 2022
1 parent 0c95c8c commit 8d604fb
Show file tree
Hide file tree
Showing 28 changed files with 676 additions and 2 deletions.
94 changes: 94 additions & 0 deletions src/Get-MsIdAdfsSamlToken.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<#
.SYNOPSIS
Initiates a SAML logon request to and AD FS server to generate log activity and returns the user token.
.DESCRIPTION
This command will generate log activity on the ADFS server, by requesting a SAML token using Windows or forms authentication.
.EXAMPLE
PS > Get-MsIdAdfsSamlToken urn:microsoft:adfs:claimsxray -HostName adfs.contoso.com
Sign in to an application on an AD FS server using logged user credentials using the SAML protocol.
.EXAMPLE
PS > $credential = Get-Credential
PS > Get-MsIdAdfsSamlToken urn:microsoft:adfs:claimsxray -HostName adfs.contoso.com
Sign in to an application on an AD FS server using credentials provided by the user using the SAML endpoint and forms based authentication.
.EXAMPLE
PS > $SamlIdentifiers = Get-AdfsRelyingPartyTrust | where { $_.WSFedEndpoint -eq $null } | foreach { $_.Identifier.Item(0) }
PS > $SamlIdentifiers | foreach { Get-MsIdAdfsSamlToken $_ -HostName adfs.contoso.com }
Get all SAML relying party trusts from the AD FS server and sign in using the logged user credentials.
#>
function Get-MsIdAdfsSamlToken
{
[CmdletBinding()]
[OutputType([string])]
param(
# Application identifier
[Parameter(Mandatory=$true,
Position=0,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[string]$Issuer,
# Enter host name for the AD FS server
[Parameter(Mandatory=$true)]
[string]$HostName,
# Provide the credential for the user to be signed in
[Parameter(Mandatory=$false)]
[pscredential]$Credential
)

if ($null -ne $Credential)
{
Write-Warning "Using credentials sends password in clear text over the network!"
}


$login = $null
$loginFail = ""

$EncodedSamlRequest = New-MsIdSamlRequest -Issuer $Issuer -DeflateAndEncode

[System.UriBuilder] $uriAdfs = 'https://{0}/adfs/ls' -f $HostName
$uriAdfs.Query = ConvertTo-QueryString @{
SAMLRequest = $EncodedSamlRequest
}

if ($null -ne $Credential) {
$user = $Credential.UserName
$form = New-AdfsLoginFormFields -Credential $Credential
try{
$login = Invoke-WebRequest -Uri $uriAdfs.Uri -Method POST -Body $form -UseBasicParsing -ErrorAction SilentlyContinue
}
catch [System.Net.WebException]{
$loginFail = $_
}
}
else {
$userAgent = 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT; Windows NT 10.0; en-US)'
$user = "$($env:USERDOMAIN)\$($env:UserName)"
try{
$login = Invoke-WebRequest -Uri $uriAdfs.Uri -UserAgent $userAgent -UseDefaultCredentials -UseBasicParsing -ErrorAction SilentlyContinue
}
catch [System.Net.WebException]{
$loginFail = $_
}
}



if ($null -eq $login) { Write-Error "HTTP request failed for issuer ""$($Issuer)"" and user: $($user). ERROR: $($loginFail)" }
elseif ($login.StatusCode -ne 200) { Write-Error "HTTP request failed for issuer ""$($Issuer)"" and user: $($user). ERROR: HTTP status $($login.StatusCode)" }
elseif ($login.InputFields.Count -le 0) {
Write-Warning "Login failed for issuer ""$($Issuer)"" and user: $($user)"
}
elseif ($login.InputFields[0].outerHTML.Contains("SAMLResponse")) {
Write-Host "Login sucessful for issuer ""$($Issuer)"" and user: $($user)"
return $login.Content | Get-ParsedTokenFromResponse -Protocol SAML
}
else { Write-Warning "Login failed for issuer ""$($Issuer)"" and user: $($user)" }

return
}
48 changes: 48 additions & 0 deletions src/Get-MsIdAdfsSampleApp.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<#
.SYNOPSIS
Returns the list of availabe sample AD FS relyng party trust applications available in this module. These applications do NOT use real endpoints and are meant to be used as test applications.
.EXAMPLE
PS > Get-MsIdAdfsSampleApps
Get the full list of sample AD FS apps.
.EXAMPLE
PS > Get-MsIdAdfsSampleApps SampleAppName
Get only SampleAppName sample AD FS app (replace SampleAppName by one of the available apps).
#>
function Get-MsIdAdfsSampleApp {
[CmdletBinding()]
[OutputType([object[]])]
param (
# Sample applications name
[Parameter(Mandatory = $false)]
[string] $Name
)

$result = [System.Collections.ArrayList]@()

if (Import-AdfsModule) {
$apps = Get-ChildItem -Path "$($PSScriptRoot)\internal\AdfsSamples\"

if ($Name -ne '') {
$apps = $apps | Where-Object { $_.Name -eq $Name + '.json' }
}

ForEach ($app in $apps) {
Try {
Write-Verbose "Loading app: $($app.Name)"
if ($app.Name -notlike '*.xml') {
$rp = Get-Content $app.FullName | ConvertFrom-json
$null = $result.Add($rp)
}
}
catch {
Write-Warning "Error while loading app '$($app.Name)': ($_)"
}
}

return ,$result
}
}
91 changes: 91 additions & 0 deletions src/Get-MsIdAdfsWsFedToken.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<#
.SYNOPSIS
Initiates a Ws-Fed logon request to and AD FS server to generate log activity and returns the user token.
.DESCRIPTION
This command will generate log activity on the ADFS server, by requesting a Ws-Fed token using the windows or forms authentication.
.EXAMPLE
PS > Get-MsIdAdfsWsFedToken urn:federation:MicrosoftOnline -HostName adfs.contoso.com
Sign in to an application on an AD FS server using logged user credentials using the Ws-Fed protocol.
.EXAMPLE
PS > $credential = Get-Credential
PS > Get-MsIdAdfsWsFedToken urn:federation:MicrosoftOnline -HostName adfs.contoso.com
Sign in to an application on an AD FS server using credentials provided by the user using the Ws-Fed endpoint and forms based authentication.
.EXAMPLE
PS > $WsFedIdentifiers = Get-AdfsRelyingPartyTrust | where { $_.WSFedEndpoint -ne $null -and $_.Identifier -notcontains "urn:federation:MicrosoftOnline" } | foreach { $_.Identifier.Item(0) }
PS > $WsFedIdentifiers | foreach { Get-MsIdAdfsWsFedToken $_ -HostName adfs.contoso.com }
Get all Ws-Fed relying party trusts from the AD FS server excluding Azure AD and sign in using the logged user credentials.
#>
function Get-MsIdAdfsWsFedToken
{
[CmdletBinding()]
[OutputType([string])]
param(
# Enter the application identifier
[Parameter(Mandatory=$true,
Position=0,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[string]$WtRealm,
# Enter host name for the AD FS server
[Parameter(Mandatory=$true)]
[string]$HostName,
# Provide the credential for the user to be signed in
[Parameter(Mandatory=$false)]
[pscredential]$Credential
)

$login = $null
$loginFail = ""

# Defaults to Ws-Fed request
[System.UriBuilder] $uriAdfs = 'https://{0}/adfs/ls' -f $HostName
$uriAdfs.Query = ConvertTo-QueryString @{
'client-request-id' = New-Guid
wa = 'wsignin1.0'
wtrealm = $WtRealm
}


if ($null -ne $Credential) {
Write-Warning "Using credentials sends password in clear text over the network!"

$user = $Credential.UserName
$form = New-AdfsLoginFormFields -Credential $Credential
try{
$login = Invoke-WebRequest -Uri $uriAdfs.Uri -Method POST -Body $form -UseBasicParsing -ErrorAction SilentlyContinue
}
catch [System.Net.WebException]{
$loginFail = $_
}
}
else {
$userAgent = 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT; Windows NT 10.0; en-US)'
$user = "$($env:USERDOMAIN)\$($env:UserName)"
try{
$login = Invoke-WebRequest -Uri $uriAdfs.Uri -UserAgent $userAgent -UseDefaultCredentials -UseBasicParsing -ErrorAction SilentlyContinue
}
catch [System.Net.WebException]{
$loginFail = $_
}
}


if ($null -eq $login) { Write-Error "HTTP request failed for WtRealm ""$($WtRealm)"" and user: $($user). ERROR: $($loginFail)" }
elseif ($login.StatusCode -ne 200) { Write-Error "HTTP request failed for WtRealm ""$($WtRealm)"" and user: $($user). ERROR: HTTP status $($login.StatusCode)" }
elseif ($login.InputFields.Count -le 0) {
Write-Warning "Login failed for WtRealm ""$($WtRealm)"" and user: $($user)"
}
elseif ($login.InputFields[0].outerHTML.Contains("wsignin1.0")) {
Write-Host "Login sucessful for WtRealm ""$($WtRealm)"" and user: $($user)"
return $login.Content | Get-ParsedTokenFromResponse -Protocol WsFed
}
else { Write-Warning "Login failed for WtRealm ""$($WtRealm)"" and user: $($user)" }

return
}
84 changes: 84 additions & 0 deletions src/Get-MsIdAdfsWsTrustToken.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<#
.SYNOPSIS
Initiates a Ws-Trust logon request to and AD FS server to generate log activity and returns the user token.
.DESCRIPTION
This command will generate log activity on the ADFS server, by requesting a Ws-Trust token using the windows transport or user name mixed endpoint.
.EXAMPLE
PS > Get-MsIdAdfsWsTrustToken urn:federation:MicrosoftOnline -HostName adfs.contoso.com
Sign in to an application on an AD FS server using logged user credentials using the WindowsTransport endpoint.
.EXAMPLE
PS > $credential = Get-Credential
PS > Get-MsIdAdfsWsTrustToken urn:federation:MicrosoftOnline -HostName adfs.contoso.com -Credential $credential
Sign in to an application on an AD FS server using credentials provided by the user using the UserNameMixed endpoint.
.EXAMPLE
PS > $identifiers = Get-AdfsRelyingPartyTrust | foreach { $_.Identifier.Item(0) }
PS > $identifiers | foreach { Get-MsIdAdfsWsTrustToken $_ -HostName adfs.contoso.com }
Get all relying party trusts from the AD FS server and sign in using the logged user credentials.
#>
function Get-MsIdAdfsWsTrustToken
{
[CmdletBinding()]
[OutputType([string])]
param(
# Enter the application identifier
[Parameter(Mandatory=$true,
Position=0,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[string]$Identifier,
# Enter host name for the AD FS server
[Parameter(Mandatory=$true)]
[string]$HostName,
# Provide the credential for the user to be signed in
[Parameter(Mandatory=$false)]
[pscredential]$Credential
)

$login = $null
$loginFail = ""

if ($null -ne $Credential) {
$user = $Credential.UserName

[System.UriBuilder] $uriAdfs = 'https://{0}/adfs/services/trust/2005/usernamemixed' -f $HostName

$wstrustRequest = New-MsIdWsTrustRequest $Identifier -Endpoint $uriAdfs.Uri -Credential $Credential
try{
$login = Invoke-WebRequest $uriAdfs.Uri -Method Post -Body $wstrustRequest -ContentType "application/soap+xml" -UseBasicParsing -ErrorAction SilentlyContinue
}
catch [System.Net.WebException]{
$loginFail = $_
}
}
else {
$user = "$($env:USERDOMAIN)\$($env:UserName)"

[System.UriBuilder] $uriAdfs = 'https://{0}/adfs/services/trust/2005/windowstransport' -f $HostName

$wstrustRequest = New-MsIdWsTrustRequest $Identifier -Endpoint $uriAdfs.Uri
try{
$login = Invoke-WebRequest $uriAdfs.Uri -Method Post -Body $wstrustRequest -ContentType "application/soap+xml" -UseDefaultCredentials -UseBasicParsing -ErrorAction SilentlyContinue
}
catch [System.Net.WebException]{
$loginFail = $_
}
}



if ($null -eq $login) { Write-Error "HTTP request failed for identifier ""$($identifier)"" and user: $($user). ERROR: $($loginFail)" }
elseif ($login.StatusCode -ne 200) { Write-Error "HTTP request failed for identifier ""$($identifier)"" and user: $($user). ERROR: HTTP status $($login.StatusCode)" }
elseif ($login.Headers["Content-Type"].Contains("application/soap+xml")) {
Write-Host "Login sucessful for identifier ""$($Identifier)"" and user: $($user)"
return $login.Content | ConvertFrom-SamlMessage
}
else { Write-Warning "Login failed for identifier ""$($Identifier)"" and user: $($user)" }

return
}
Loading

0 comments on commit 8d604fb

Please sign in to comment.