[玩转系统] 利用您的 API 到 PowerShell Graph API
作者:精品下载站 日期:2024-12-14 20:50:09 浏览:14 分类:玩电脑
利用您的 API 到 PowerShell Graph API
Microsoft Graph API 是一项服务,允许您在单个 REST API 端点下读取、修改和管理 Azure AD 和 Office 365 的几乎所有方面。在本文中,了解如何将 API 转换为 PowerShell Graph API。
先决条件
如果您想跟我一起阅读本文,请确保您首先满足以下条件:
- 运行 Windows PowerShell 5.1(这是我测试过的版本。其他版本可能可以工作,但不能保证)
- Azure 租户
- 使用具有订阅全局管理员权限或应用程序注册权限的帐户和全局管理员向 Azure 进行身份验证,以接受你的应用程序注册请求。
为 Microsoft Graph API 创建应用程序标识
要访问 Microsoft Graph API,您首先需要一个身份来获取 OAuth 令牌。这主要通过可以在 Azure 门户中创建的应用程序标识来完成。您可以通过 Azure 门户创建应用程序标识。为此:
- 转到 Azure 门户并转到 Azure Active Directory。
- 单击左侧菜单管理下的应用注册,然后单击新注册按钮。
- 输入您的应用程序的名称,然后单击“注册”。
- 复制应用程序 ID 指南以供以后使用。
为 Microsoft Graph API 创建机密
您可以使用两种主要方法对 Graph API 进行身份验证:AppId/Secret 和基于证书的身份验证。使用 PowerShell 连接到图形 API 时,您需要进行身份验证。
让我们介绍一下如何使用这两种方法进行身份验证。
应用程序 ID/秘密
应用程序 ID/秘密就像常规的用户名/密码。应用程序 ID 由 GUID 而不是用户名组成,密码只是一个随机字符串。
要创建密钥 - 单击左侧菜单中的证书和密钥,然后按新客户端密钥。
输入密钥的描述并选择您希望其过期的时间。现在只需请求许可即可访问所需的数据。
证书
可以创建自签名证书并将其公钥上传到 Azure。这是首选且更安全的身份验证方式。
您首先需要生成一个自签名证书。幸运的是,这可以通过 PowerShell 轻松完成。
# Your tenant name (can something more descriptive as well)
$TenantName = "contoso.onmicrosoft.com"
# Where to export the certificate without the private key
$CerOutputPath = "C:\Temp\PowerShellGraphCert.cer"
# What cert store you want it to be in
$StoreLocation = "Cert:\CurrentUser\My"
# Expiration date of the new certificate
$ExpirationDate = (Get-Date).AddYears(2)
# Splat for readability
$CreateCertificateSplat = @{
FriendlyName = "AzureApp"
DnsName = $TenantName
CertStoreLocation = $StoreLocation
NotAfter = $ExpirationDate
KeyExportPolicy = "Exportable"
KeySpec = "Signature"
Provider = "Microsoft Enhanced RSA and AES Cryptographic Provider"
HashAlgorithm = "SHA256"
}
# Create certificate
$Certificate = New-SelfSignedCertificate @CreateCertificateSplat
# Get certificate path
$CertificatePath = Join-Path -Path $StoreLocation -ChildPath $Certificate.Thumbprint
# Export certificate without private key
Export-Certificate -Cert $CertificatePath -FilePath $CerOutputPath | Out-Null
现在,通过单击左侧菜单中的“证书和机密”并按“上传证书”,将导出到 $CerOutputPath
的自签名证书上传到 Azure 应用程序。
向应用程序添加权限
为应用程序提供适当的权限非常重要 - 不仅对于应用程序的功能而言,而且对于安全性而言。有关这方面的知识以及 Microsoft Graph API 中的(几乎)其他所有内容都可以在文档中找到。
一旦完成此设置,我将收集租户的所有安全事件。为了被允许这样做,我需要 SecurityEvents.Read.All 作为最低权限。有了这个,我可以收集并针对 Impossible Travel 事件、通过 VPN/TOR 连接的用户等采取行动。
要将SecurityEvents.Read.All添加到您的应用程序中 - 单击API Permissions,然后添加权限。这不仅会向您展示 Graph API,还会向您展示 Azure 中的大量其他应用程序。一旦您知道如何连接到 Microsoft Graph API,大多数应用程序就可以轻松连接。
单击Microsoft Graph > 应用程序权限 > 安全事件并检查SecurityEvents.Read.All。之后按添加权限按钮。
您是否看到该权限的需要管理员同意列已设置为是?这意味着在将权限添加到应用程序之前需要租户管理员批准。
如果您是全局管理员,请按授予管理员同意或请求全局管理员批准。向用户请求许可而不是仅由管理员设置读/写权限是 OAuth 身份验证的重要组成部分。但这使我们能够绕过 Microsoft Graph 中的大多数权限。
您可能已经在 Facebook 或 Google 上看到过这样的内容:“您允许应用程序 X 访问您的个人资料吗?”
现在一切都准备好了 - 让我们登录并获取一些数据!
获取访问令牌(应用程序 ID 和密钥)
为此,我们需要发布请求以从 Microsoft Graph OAuth 端点获取访问令牌。在该请求的正文中,我们需要提供:
client_id
- 您的应用程序 ID - url 编码client_secret
- 您的应用程序秘密 - url 编码scope
- 一个 url 编码的 url,指定您要访问的内容grant_type
- 您使用的身份验证方法
终结点的 URL 为 https://login.microsoftonline.com//oauth2/v2.0/token。您可以使用下面的代码片段通过 PowerShell 和 Graph API 请求访问令牌。
# Define AppId, secret and scope, your tenant name and endpoint URL
$AppId = '2d10909e-0396-49f2-ba2f-854b77c1e45b'
$AppSecret = 'abcdefghijklmnopqrstuv12345'
$Scope = "https://graph.microsoft.com/.default"
$TenantName = "contoso.onmicrosoft.com"
$Url = "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token"
# Add System.Web for urlencode
Add-Type -AssemblyName System.Web
# Create body
$Body = @{
client_id = $AppId
client_secret = $AppSecret
scope = $Scope
grant_type = 'client_credentials'
}
# Splat the parameters for Invoke-Restmethod for cleaner code
$PostSplat = @{
ContentType = 'application/x-www-form-urlencoded'
Method = 'POST'
# Create string by joining bodylist with '&'
Body = $Body
Uri = $Url
}
# Request the token!
$Request = Invoke-RestMethod @PostSplat
获取访问令牌(使用证书)
使用证书对 Microsoft Graph API 进行身份验证与正常的 AppId/Secret 流程有些不同。要使用证书获取访问令牌,您必须:
- 创建 Java Web 令牌 (JWT) 标头。
- 创建 JWT 有效负载。
- 使用之前创建的自签名证书对 JWT 标头和负载进行签名。这将创建一个自制的访问令牌,用于请求 Microsoft Graph 访问令牌。
- 创建一个请求正文,其中包含:
client_id=<application id>
client_assertion=<the JWT>
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
scope=<URLEncoded scope>
grant_type=client_credentials
- 使用 header 中的
Authorization=
向 oauth 端点发出带有正文的 post 请求。
Microsoft 文档中并未明确说明如何执行此操作,但以下是实现此操作的 PowerShell 脚本:
$TenantName = "<your tenant name>.onmicrosoft.com"
$AppId = "<your application id"
$Certificate = Get-Item Cert:\CurrentUser\My\<self signed and uploaded cert thumbprint>
$Scope = "https://graph.microsoft.com/.default"
# Create base64 hash of certificate
$CertificateBase64Hash = [System.Convert]::ToBase64String($Certificate.GetCertHash())
# Create JWT timestamp for expiration
$StartDate = (Get-Date "1970-01-01T00:00:00Z" ).ToUniversalTime()
$JWTExpirationTimeSpan = (New-TimeSpan -Start $StartDate -End (Get-Date).ToUniversalTime().AddMinutes(2)).TotalSeconds
$JWTExpiration = [math]::Round($JWTExpirationTimeSpan,0)
# Create JWT validity start timestamp
$NotBeforeExpirationTimeSpan = (New-TimeSpan -Start $StartDate -End ((Get-Date).ToUniversalTime())).TotalSeconds
$NotBefore = [math]::Round($NotBeforeExpirationTimeSpan,0)
# Create JWT header
$JWTHeader = @{
alg = "RS256"
typ = "JWT"
# Use the CertificateBase64Hash and replace/strip to match web encoding of base64
x5t = $CertificateBase64Hash -replace '\+','-' -replace '/','_' -replace '='
}
# Create JWT payload
$JWTPayLoad = @{
# What endpoint is allowed to use this JWT
aud = "https://login.microsoftonline.com/$TenantName/oauth2/token"
# Expiration timestamp
exp = $JWTExpiration
# Issuer = your application
iss = $AppId
# JWT ID: random guid
jti = [guid]::NewGuid()
# Not to be used before
nbf = $NotBefore
# JWT Subject
sub = $AppId
}
# Convert header and payload to base64
$JWTHeaderToByte = [System.Text.Encoding]::UTF8.GetBytes(($JWTHeader | ConvertTo-Json))
$EncodedHeader = [System.Convert]::ToBase64String($JWTHeaderToByte)
$JWTPayLoadToByte = [System.Text.Encoding]::UTF8.GetBytes(($JWTPayload | ConvertTo-Json))
$EncodedPayload = [System.Convert]::ToBase64String($JWTPayLoadToByte)
# Join header and Payload with "." to create a valid (unsigned) JWT
$JWT = $EncodedHeader + "." + $EncodedPayload
# Get the private key object of your certificate
$PrivateKey = $Certificate.PrivateKey
# Define RSA signature and hashing algorithm
$RSAPadding = [Security.Cryptography.RSASignaturePadding]::Pkcs1
$HashAlgorithm = [Security.Cryptography.HashAlgorithmName]::SHA256
# Create a signature of the JWT
$Signature = [Convert]::ToBase64String(
$PrivateKey.SignData([System.Text.Encoding]::UTF8.GetBytes($JWT),$HashAlgorithm,$RSAPadding)
) -replace '\+','-' -replace '/','_' -replace '='
# Join the signature to the JWT with "."
$JWT = $JWT + "." + $Signature
# Create a hash with body parameters
$Body = @{
client_id = $AppId
client_assertion = $JWT
client_assertion_type = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
scope = $Scope
grant_type = "client_credentials"
}
$Url = "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token"
# Use the self-generated JWT as Authorization
$Header = @{
Authorization = "Bearer $JWT"
}
# Splat the parameters for Invoke-Restmethod for cleaner code
$PostSplat = @{
ContentType = 'application/x-www-form-urlencoded'
Method = 'POST'
Body = $Body
Uri = $Url
Headers = $Header
}
$Request = Invoke-RestMethod @PostSplat
了解请求访问令牌输出
通过应用程序 ID/秘密或通过证书获得访问令牌后,应该会看到一个具有四个属性的对象。
token_type
- 它是什么类型的令牌expires_in
- 访问令牌有效的时间(以秒为单位)ext_expires_in
- 与expires_in
类似,但为了在令牌服务中断时保持弹性access_token
- 我们来这里的目的
接下来,您将使用 token_type
和 access_token
创建标头,并开始使用 PowerShell 向 Microsoft Graph API 发出请求。
向 Microsoft Graph API 发出请求
现在开始向 API 发出一些请求。
按照我们的示例,您首先需要用于列出安全警报的 URL。请记住使用 Microsoft Graph API 文档来查看需要什么。
在这种情况下,您需要一个带有 Authorization=Bearer
的标头和一个针对 Graph API Alerts 端点的 GET 请求。以下是如何使用 PowerShell 执行此操作。
# Create header
$Header = @{
Authorization = "$($Request.token_type) $($Request.access_token)"
}
$Uri = "https://graph.microsoft.com/v1.0/security/alerts"
# Fetch all security alerts
$SecurityAlertsRequest = Invoke-RestMethod -Uri $Uri -Headers $Header -Method Get -ContentType "application/json"
$SecurityAlerts = $SecurityAlertsRequest.Value
现在,如果 $SecurityAlerts
变量中有任何安全警报,它应该如下所示:
$SecurityAlerts | select eventDateTime,Title
eventDateTime title
------------- -----
2019-08-05T17:59:47.6271981Z Atypical travel
2019-08-05T08:23:01.7325708Z Anonymous IP address
2019-08-05T08:23:55.5000456Z Anonymous IP address
2019-08-04T22:06:51.063797Z Anonymous IP address
2019-08-04T21:56:10.981437Z Anonymous IP address
2019-08-08T09:30:00Z Creation of forwarding/redirect rule
2019-07-19T13:30:00Z eDiscovery search started or exported
2019-07-19T08:00:00Z eDiscovery search started or exported
检查 JSON 格式的单个安全警报将如下所示:
"id": "censored",
"azureTenantId": "censored",
"azureSubscriptionId": "censored",
"riskScore": null,
"tags": [
],
"activityGroupName": null,
"assignedTo": null,
"category": "AnonymousLogin",
"closedDateTime": null,
"comments": [
],
"confidence": null,
"createdDateTime": "2019-08-08T09:46:59.65722253Z",
"description": "Sign-in from an anonymous IP address (e.g. Tor browser, anonymizer VPNs)",
"detectionIds": [
],
"eventDateTime": "2019-08-08T09:46:59.65722253Z",
"feedback": null,
"lastModifiedDateTime": "2019-08-08T09:54:30.7256251Z",
"recommendedActions": [
],
"severity": "medium",
"sourceMaterials": [
],
"status": "newAlert",
"title": "Anonymous IP address",
"vendorInformation": {
"provider": "IPC",
"providerVersion": null,
"subProvider": null,
"vendor": "Microsoft"
},
"cloudAppStates": [
],
"fileStates": [
],
"hostStates": [
],
"historyStates": [
],
"malwareStates": [
],
"networkConnections": [
],
"processes": [
],
"registryKeyStates": [
],
"triggers": [
],
"userStates": [
{
"aadUserId": "censored",
"accountName": "john.doe",
"domainName": "contoso.com",
"emailRole": "unknown",
"isVpn": null,
"logonDateTime": "2019-08-08T09:45:59.6174156Z",
"logonId": null,
"logonIp": "censored",
"logonLocation": "Denver, Colorado, US",
"logonType": null,
"onPremisesSecurityIdentifier": null,
"riskScore": null,
"userAccountType": null,
"userPrincipalName": "[email "
}
],
"vulnerabilityStates": [
]
}
了解和管理 API 输出分页
Microsoft Graph API 对每个函数返回的项目数有限制。此限制针对每个功能,但假设为 1000 个项目。这意味着您最多只能在请求中获取 1000 件商品。
当达到此限制时,它将使用分页来传递其余的项目。它通过将 @odata.nextLink
属性添加到您的请求的答案中来实现此目的。 @odata.nextLink
包含一个 URL,您可以调用该 URL 来获取请求的下一页。
您可以通过检查此属性并使用循环来阅读所有项目:
$Uri = "https://graph.microsoft.com/v1.0/auditLogs/signIns"
# Fetch all security alerts
$AuditLogRequest = Invoke-RestMethod -Uri $Uri -Headers $Header -Method Get -ContentType "application/json"
$AuditLogs = @()
$AuditLogs+=$AuditLogRequest.value
while($AuditLogRequest.'@odata.nextLink' -ne $null) {
$AuditLogRequest += Invoke-RestMethod -Uri $AuditLogRequest.'@odata.nextLink' -Headers $Header -Method Get -ContentType "application/json"
}
结论
了解如何对 Graph API 进行身份验证后,从中收集数据就变得非常容易。这是一项功能强大的服务,但使用率却低于应有的水平。
幸运的是,已经有许多模块可以利用 Microsoft Graph API,但为了满足您自己的需求,您可能需要为其创建自己的模块。使用您在本文中学到的技能,您应该可以顺利上路。
有关控制 Office 365 中的来宾访问的更多信息,我在我的博客上写了一篇深入的文章,我鼓励您查看它。
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[电影] 黄沙漫天(2025) 4K.EDRMAX.杜比全景声 / 4K杜比视界/杜比全景声
[风口福利] 短视频红利新风口!炬焰创作者平台重磅激励来袭
[韩剧] 宝物岛/宝藏岛/金银岛(2025)【全16集】【朴炯植/悬疑】
[电影] 愤怒的牦牛 (2025) 国语中字 4k
[短剧合集] 2025年05月30日 精选+付费短剧推荐56部
[软件合集] 25年5月30日 精选软件26个
[软件合集] 25年5月29日 精选软件18个
[短剧合集] 2025年05月28日 精选+付费短剧推荐38部
[软件合集] 25年5月28日 精选软件37个
[软件合集] 25年5月27日 精选软件26个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[办公模版] office模板合集:包含word、Excel、PowerPoint、Access四类共计2000多个模板
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[音乐] 华语流行伤感情经典歌无损音乐合集(700多首)
[影视] 内地绝版高清录像带 [mpg]
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag