Public/Get-GraphOauthAuthorizationCode.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<#
    .NOTES
    ===========================================================================
     Created with:     SAPIEN Technologies, Inc., PowerShell Studio 2017 v5.4.135
     Created on:     2/8/2017 8:48 AM
     Edited on: 2/7/2019
     Created by:     Mark Kraus
     Organization:     Mitel
     Modified by: Mark Domansky
     Filename:     Get-GraphOauthAuthorizationCode.ps1
    ===========================================================================
    .DESCRIPTION
        Get-GraphOauthAuthorizationCode Function
#>


<#
    .SYNOPSIS
        Retrieves an OAuth Authorization code form Microsoft

    .DESCRIPTION
        Retrieves an OAuth Authorization code form Microsoft for a given Graph Application. This commandlet requires an interactive session as you will need to provide your credentials and authorize the Graph Application. The OAuth Authorization code will be used to obtain an OAuth Access Token.

    .PARAMETER Application
        MSGraphAPI.Application object (See New-GraphApplication)

    .PARAMETER BaseURL
        The base URL for obtaining an OAuth Authorization Code form Microsoft. This is provided in the event that a different URL is required. The default is

            https://login.microsoftonline.com/common/oauth2/authorize

    .PARAMETER ForcePrompt
        Ignore existing cached authentications and force appropriate authentication prompt. This is not usually needed.
        Accepted Values: none=prefer existing login, login=force login prompt, consent=force user consent, admin_consent=force admin user consent
        For ADFS federated login, see https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/operations/ad-fs-prompt-login
        For additional information on the OAuth flow and values, see https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow

    .EXAMPLE
                PS C:\> $GraphAuthCode = Get-GraphOauthAuthorizationCode -Application $GraphApp

    .OUTPUTS
        MSGraphAPI.Oauth.AuthorizationCode

    .LINK
        http://psmsgraph.readthedocs.io/en/latest/functions/Get-GraphOauthAuthorizationCode
    .LINK
        https://graph.microsoft.io/en-us/docs/authorization/auth_overview
    .LINK
        http://psmsgraph.readthedocs.io/en/latest/functions/New-GraphApplication
#>

function Get-GraphOauthAuthorizationCode {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")]
    [CmdletBinding(ConfirmImpact = 'Low',
                   HelpUri = 'http://psmsgraph.readthedocs.io/en/latest/functions/Get-GraphOauthAuthorizationCode',
                   SupportsShouldProcess = $true)]
    [OutputType('MSGraphAPI.Oauth.AuthorizationCode')]
    param
    (
        [Parameter(Mandatory = $true,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [Alias('App')]
        [PSTypeName('MSGraphAPI.Application')]$Application,

        [Parameter(Mandatory = $false,
                   ValueFromPipelineByPropertyName = $true)]
        [Alias('URL')]
        [string]$BaseURL = 'https://login.microsoftonline.com/common/oauth2/authorize',

        [Parameter(Mandatory = $false,
                   ValueFromPipelineByPropertyName = $true)]
                   [ValidateNotNullOrEmpty()]
                   [ValidateSet('none','login','consent','admin_consent')]
        [string]$ForcePrompt
    )
    Process {
        if (-not $pscmdlet.ShouldProcess($Application.ClientID)) {
            return
        }
        if ($PSBoundParameters.ContainsKey('ForcePrompt')) {$ForcePrompt_Uri = "&prompt=$ForcePrompt"}
        $Client_Id = [System.Web.HttpUtility]::UrlEncode($Application.ClientId)
        $Redirect_Uri = [System.Web.HttpUtility]::UrlEncode($Application.RedirectUri)
        $Url = "{0}?response_type=code&redirect_uri={1}&client_id={2}{3}" -f @(
            $BaseURL
            $Redirect_Uri
            $Client_Id
            $ForcePrompt_Uri
        )
        Write-Verbose "URL: '$URL'"
        $Params = @{
            TypeName = 'System.Windows.Forms.Form'
            Property = @{
                Width = 440
                Height = 640
            }
        }
        $Form = New-Object @Params
        $Params = @{
            TypeName = 'System.Windows.Forms.WebBrowser'
            Property = @{
                Width = 420
                Height = 600
                Url = $Url
            }
        }
        $Web = New-Object @Params
        $DocumentCompleted_Script = {
            if ($web.Url.AbsoluteUri -match "error=[^&]*|code=[^&]*") {
                $form.Close()
            }
        }
        # ScriptErrorsSuppressed must be $false or AD FS tenants will fail on Windows Integrated Authentication pages
        $web.ScriptErrorsSuppressed = $false
        $web.Add_DocumentCompleted($DocumentCompleted_Script)
        $form.Controls.Add($web)
        $form.Add_Shown({ $form.Activate() })
        [void]$form.ShowDialog()

        $QueryOutput = [System.Web.HttpUtility]::ParseQueryString($web.Url.Query)
        $Response = @{ }
        foreach ($key in $queryOutput.Keys) {
            $Response["$key"] = $QueryOutput[$key]
        }
        $SecAuthCode = 'NOAUTHCODE' | ConvertTo-SecureString -AsPlainText -Force
        $AuthCodeCredential = [pscredential]::new('NOAUTHCODE', $SecAuthCode)
        if ($Response.Code) {
            $SecAuthCode = $Response.Code | ConvertTo-SecureString -AsPlainText -Force
            $AuthCodeCredential = [pscredential]::new('AuthCode', $SecAuthCode)
            $Response.Remove('Code')
        }
        [pscustomobject]@{
            PSTypeName = 'MSGraphAPI.Oauth.AuthorizationCode'
            AuthCodeCredential = $AuthCodeCredential
            ResultURL = $web.Url.psobject.copy()
            Application = $Application
            AuthCodeBaseURL = $BaseURL
            Response = $Response
            Issued = Get-date
        }
        [void]$form.Close()
        [void]$Web.Dispose()
        [void]$Form.Dispose()
    }
}