Public/Get-GraphOauthAccessToken.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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
<#
    .NOTES
    ===========================================================================
     Created with: SAPIEN Technologies, Inc., PowerShell Studio 2017 v5.4.135
     Created on: 2/8/2017 10:26 AM
     Edited on:: 4/22/2017
     Created by: Mark Kraus
     Organization:
     Filename: Get-GraphOauthAccessToken.ps1
    ===========================================================================
    .DESCRIPTION
        Get-GraphOauthAccessToken Function
#>


<#
    .SYNOPSIS
        Retieves an OAuth Access Token from Microsoft

    .DESCRIPTION
        Takes an OAuth Acces Authorization code returned from Get-GraphOauthAuthorizationCode and
        requests an OAuth Access Token for the provided resource from Microsoft. A
        MSGraphAPI.Oauth.AccessToken object is returned. This object is required for making calls
        to Invoke-GraphRequest and many other functions provided by this module.


    .PARAMETER AuthenticationCode
        The Authentication Code returned from Get-GraphOauthAuthorizationCode

    .PARAMETER BaseURL
        The Base URL used for retrieving OAuth Acces Tokens. This is not required. the default is

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

    .PARAMETER Resource
        The resource for which the OAuth Access token will be requested. The default is

            https://graph.microsoft.com

        You must set the resource to match the endpoints your token will be valid for.

            Microsft Graph: https://graph.microsoft.com
            Azure AD Graph API: https://graph.windows.net
            Office 365 Unified Mail API: https://outlook.office.com

        If you need to access more than one resrouce, you will need to request multiple OAuth Access
        Tokens and use the correct tokens for the correct endpoints.

    .EXAMPLE
        PS C:\> $ClientCredential = Get-Credential
        PS C:\> $Params = @{
        Name = 'MyGraphApp'
        Description = 'My Graph Application!'
        ClientCredential = $ClientCredential
        RedirectUri = 'https://adataum/ouath?'
        UserAgent = 'Windows:PowerShell:GraphApplication'
        }
        PS C:\> $GraphApp = New-GraphApplication @Params
        PS C:\> $GraphAuthCode = Get-GraphOauthAuthorizationCode -Application $GraphApp
        PS C:\> $GraphAccessToken = Get-GraphOauthAccessToken -AuthenticationCode $GraphAuthCode

    .OUTPUTS
        MSGraphAPI.Oauth.AccessToken

    .NOTES
        See Get-GraphOauthAuthorizationCode for obtaining a OAuth Authorization code.
        See Export-GraphOauthAccessToken for exporting Graph Acess Token Objects
        See Import-GraphOauthAccessToken for importing exported Graph AcessToken Objects
        See Update-GraphOauthAccessToken for refreshing the Graph Access Token

    .LINK
        http://psmsgraph.readthedocs.io/en/latest/functions/Get-GraphOauthAccessToken
    .LINK
        http://psmsgraph.readthedocs.io/en/latest/functions/Get-GraphOauthAuthorizationCode
    .LINK
        http://psmsgraph.readthedocs.io/en/latest/functions/Export-GraphOauthAccessToken
    .LINK
        http://psmsgraph.readthedocs.io/en/latest/functions/Import-GraphOauthAccessToken
    .LINK
        http://psmsgraph.readthedocs.io/en/latest/functions/Update-GraphOauthAccessToken
    .LINK
        https://graph.microsoft.io/en-us/docs/authorization/auth_overview
#>

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

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

        [Parameter(Mandatory = $false,
                   ValueFromPipelineByPropertyName = $true)]
        [string]$Resource = 'https://graph.microsoft.com'
    )

    Process {
        $Application = $AuthenticationCode.Application
        if (-not $pscmdlet.ShouldProcess($Application.ClientID)) {
            return
        }
        $Client_Id = [System.Web.HttpUtility]::UrlEncode($Application.ClientID)
        $Redirect_uri = [System.Web.HttpUtility]::UrlEncode($Application.RedirectUri)
        $Resource_encoded = [System.Web.HttpUtility]::UrlEncode($Resource)
        $AuthCode = [System.Web.HttpUtility]::UrlEncode($AuthenticationCode.GetAuthCode())
        $Body = @(
            'grant_type=authorization_code'
            '&redirect_uri={0}' -f $Redirect_uri
            '&client_id={0}' -f $Client_Id
            '&code={0}' -f $AuthCode
            '&resource={0}' -f $Resource_encoded
            '&client_secret={0}' -f [System.Web.HttpUtility]::UrlEncode(
                $Application.GetClientSecret())
        ) -join ''
        Write-Verbose "Body: $Body"
        $RequestedDate = Get-Date
        $Params = @{
            Uri = $BaseURL
            Method = 'POST'
            ContentType = "application/x-www-form-urlencoded"
            Body = $Body
            ErrorAction = 'Stop'
            SessionVariable = 'Session'
        }
        try {
            Write-Verbose "Retrieving OAuth Access Token from $BaseURL..."
            $Result = Invoke-WebRequest @Params
        }
        catch {
            $_.Exception.
                psobject.
                TypeNames.
                Insert(0,'MSGraphAPI.Oauth.Exception')
            Write-Error -Exception $_.Exception
            return
        }
        try {
            $Content = $Result.Content | ConvertFrom-Json -ErrorAction Stop
        }
        Catch {
            $Params = @{
                MemberType = 'NoteProperty'
                Name = 'Respone'
                Value = $Result
            }
            $_.Exception | Add-Member @Params
            Write-Error -Exception $_.Exception
            return
        }
        $SecureAccessToken = $Content.access_token | ConvertTo-SecureString -AsPlainText -Force
        $SecureRefreshToken = $Content.refresh_token | ConvertTo-SecureString -AsPlainText -Force
        $AccessTokenCredential = [pscredential]::new('access_token', $SecureAccessToken )
        $RefreshTokenCredential = [pscredential]::new('refresh_token', $SecureRefreshToken)
        $Params = @{
            Application = $Application
            AccessTokenCredential = $AccessTokenCredential
            RefreshTokenCredential = $RefreshTokenCredential
            RequestedDate = $RequestedDate
            Response = $Content | Select-Object -property * -ExcludeProperty access_token, refresh_token
            ResponseHeaders = $Result.Headers
            LastRequestDate = $RequestedDate
            Session = $Session
            GUID = [guid]::NewGuid()
        }
        New-GraphOauthAccessToken @Params
    }
}