Office 365 Rest API - 守护程序周身份验证

2024-01-02

我正在尝试建立一个Ruby用于访问 Office 365 Rest API 的守护程序服务。最近可以通过 OAuth 'client_credentials' 流程来做到这一点,如本博客文章所述:https://learn.microsoft.com/en-us/archive/blogs/exchangedev/building-daemon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client-凭证流 https://learn.microsoft.com/en-us/archive/blogs/exchangedev/building-daemon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client-credential-flow

我正在努力生成有效的访问令牌。令牌端点返回给我一个 JWT,但是当使用此令牌时,我收到了带有以下消息的 401:

访问令牌是使用身份验证方法获取的,该身份验证方法太弱,无法允许此应用程序访问。提供的身份验证强度为 1,所需的身份验证强度为 2

据我了解,client_credentials 流程要求您提供 X.509 证书,不幸的是,博客文章中的所有示例均适用于 C#。

我在请求令牌时使用生成的自签名证书和私钥来执行客户端断言。我按照博客文章中的步骤生成证书并更新清单以使用此证书。

这是供参考的 ruby​​ 代码:

def request_token
  uri = URI.parse("https://login.windows.net/== TENANT-ID ==/oauth2/token?api-version=1.0")
  https = Net::HTTP.new(uri.host, uri.port)

  req = Net::HTTP::Post.new(uri.request_uri)
  req.set_form_data(
    :grant_type    => 'client_credentials',
    :redirect_uri  => 'http://spready.dev',
    :resource      => 'https://outlook.office365.com/',
    :client_id     => '== Client ID ==',
    :client_secret => '== Client secret =='
  )

  https.use_ssl = true
  https.cert = client_cert
  https.key = client_key
  https.verify_mode = OpenSSL::SSL::VERIFY_PEER

  resp = https.start { |cx| cx.request(req) }

  @access_token = JSON.parse(resp.body)
end

显然,为了安全起见,我删除了某些信息。即使它是 ruby​​,您也可以看到我正在使用我的证书通过 SSL 连接来验证客户端。

以下是有关该错误的更多信息:

"x-ms-diagnostics" => "2000010;
    reason=\"The access token is acquired using an authentication method that is too weak to allow access for this application. Presented auth strength was 1, required is 2.\";
    error_category=\"insufficient_auth_strength\"", 
"x-diaginfo"=>"AM3PR01MB0662", 
"x-beserver"=>"AM3PR01MB0662"

任何帮助将不胜感激。


Edit

对于其他想要在 Ruby 中做类似事情的人来说,这里是我使用的代码要点:https://gist.github.com/NGMarmaduke/a088943edbe4e703129d https://gist.github.com/NGMarmaduke/a088943edbe4e703129d

该示例使用 Rails 环境,但删除 Rails 特定位应该相当容易。

请记住将 YOUR CLIENT ID、TENANT_ID 和 CERT_THUMBPRINT 替换为正确的值,并将证书路径和客户端密钥方法指向正确的文件路径。

然后你可以做这样的事情:

mailbox = OfficeAPI.new("[email protected] /cdn-cgi/l/email-protection")
messages = mailbox.request_messages

代替client_secret在您的请求正文中,您需要一个client_assertion。这有点复杂,但这就是您需要该证书的原因。

基本上,您需要构建一个 JSON Web 令牌,并使用 SHA256 哈希通过您的证书对其进行签名。令牌看起来像这样:

Header:

{ 
  "alg": "RS256",
  "x5t": "..." // THUMBPRINT of Cert
}

Payload:

{
  "aud": "https:\\/\\/login.windows.net\\/<The logged in user's tenant ID>\\/oauth2\\/token",
  "exp": 1423168488,
  "iss": "YOUR CLIENT ID",
  "jti": "SOME GUID YOU ASSIGN",
  "nbf": 1423167888,
  "sub": "YOUR CLIENT ID"
}

如果您仍然同意我的观点,您现在需要对这两部分(分别)进行 Base64 编码,然后用“.”将它们连接起来。所以现在你应该有:

base64_header.base64_payload

现在,您使用 SHA256 哈希获取该字符串并用您的证书对其进行签名。然后对结果进行 base64 编码,对其进行 url 编码,然后附加到字符串,所以现在您拥有:

base64_header.base64_payload.base64_signature

最后,将其包含在令牌端点的 POST 中,作为client_assertion参数,还包括一个client_assertion_type参数设置为“urn:ietf:params:oauth:client-assertion-type:jwt-bearer”:

req.set_form_data(
    :grant_type    => 'client_credentials',
    :redirect_uri  => 'http://spready.dev',
    :resource      => 'https://outlook.office365.com/',
    :client_id     => '== Client ID ==',
    :client_assertion_type => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
    :client_assertion => 'base64_header.base64_payload.base64_signature'
  )

我希望这有帮助!这都是基于我的研究ADAL https://github.com/AzureAD/azure-activedirectory-library-for-dotnet确实如此,而且我还没有在 Ruby 中亲自测试过。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Office 365 Rest API - 守护程序周身份验证 的相关文章

随机推荐

  • 获取包含 10 种以上语言的所有维基数据项目?

    我正在尝试使用 SPARQL 从 Wikidata 获取世界上最著名的电影 我有以下查询 SELECT item WHERE item wdt P31 wd Q11424 SERVICE wikibase label bd serviceP
  • 在 scikit-learn 中使用相似矩阵代替 MDS 的相异矩阵

    我想可视化文本文档的相似性 我使用 scikit learn 的 TfidfVectorizer 作为tfidf TfidfVectorizer decode error ignore max df 3 fit transform data
  • 如何将委托作为参数传递以作为事件处理程序进行订阅?

    我有一个提供事件的外部应用程序StkQuit 我在一个静态类中订阅此事件 该类处理我的应用程序和外部应用程序之间的所有通信 我想订阅StkQuit使用位于我的表单类上的另一个处理程序的事件 该处理程序将通知用户外部应用程序已关闭 我想在静态
  • golang 生成的 WebAssembly 上的 Websocket?

    是否可以在 wasm 中而不是 go 中编写 Websocket 客户端 我尝试过使用gorilla websocket 但没有成功 func main ws func this js Value inputs js Value inter
  • SQOOP增量导入:当从数据库中删除一行时,它如何处理数据?

    假设我有一个包含列 emp id emp name emp age emp update ts 的员工表 如果表上有更新 则 updat ts 字段每次都会自动更新为当前时间戳 现在我的问题是 当我更新 插入表中的行并使用lastmodif
  • NSSplitViewController 导致包含的视图绘制在窗口角上

    I m trying to create a little Finder clone using Cocoa I m placing a source list table view to act as a sidebar and a st
  • 如何使用 Tensorboard 在同一图上绘制不同的汇总指标?

    我希望能够绘制每批次训练损失和average验证损失用于 Tensorboard 中同一图上的验证集 当我的验证集太大而无法放入内存时 我遇到了这个问题 因此需要批处理并使用tf metrics更新操作 这个问题可能适用于您想要显示在 Te
  • UIPageViewController 内的 UISlider

    我有一个 PageViewController 其初始化如下 self pageViewController UIPageViewController alloc initWithTransitionStyle UIPageViewCont
  • 设置独立的 cygwin 应用程序

    我想设置一组最小的 cygwin 应用程序 ls diff path find grep 以便它们在没有完整 cygwin 安装的计算机上运行 我假设我需要的只是相关的 exe 文件和 dll 到目前为止 这就是我所拥有的 到目前为止它有效
  • 井字游戏评价棋盘算法

    我已经用人工智能实现了井字棋 但现在面临一个问题 如何评价井字棋游戏的棋盘 也许一开始我会描述它应该如何工作 我们有 n 个井字棋游戏板 有不同的变体 我们的人工智能应该评估哪个棋盘最适合继续前进 最适合对手 Ai 通过极小极大算法计算移动
  • data.table 通过带空格的列名进行操作失败

    可重现的例子 Use the Iris data set library data table iris colnames iris 3 lt Petal Length iris lt as data table iris 访问没有空格的列
  • 如何调整/更改滚动条宽度

    有没有办法暂时改变滚动条宽度当我测试一些布局代码时 在 FF 或 IE 中 我记得不久前读过一些关于这与分辨率有关的内容 但不太记得了 我尝试更改计算机本身的分辨率 尝试增加浏览器字体大小 但都不起作用 Update我遇到过描述了如何在 F
  • 有没有办法在 PHP 中将 json 转换为 xml?

    有什么办法可以转换吗json to xml in PHP 我知道xml到json是很有可能的 如果您愿意使用XML序列化器 http pear php net package XML Serializer从 PEAR 中 您可以通过两个简单
  • 有没有办法包含来自不同目录的子 Rmd 文件

    我有一个主降价文件 例如 Parent Rmd 以及许多子文档 其中包含 r child introduction Rmd echo FALSE r child chapter2 Rmd echo FALSE 看来我应该能够做到 r chi
  • 样式表单错误消息 - bootstrap/rails

    我的 Rails 表单的错误消息在引导程序中看起来很糟糕 有谁知道更好 好看 错误消息的解决方案 我使用 Rails 和 Bootstrap 我的表格 它是一个助手 是这样的 div h2 prohibited this user from
  • 按钮.Visible = true;在功能内激活时无法将按钮设置为可见

    我找不到其他人遇到同样的问题 所以希望有人能有一些想法或能够向我指出另一个答案 当通过按下表单上的按钮来运行函数时 另一个按钮应该变得可见 然而 即使按钮是函数中的第一个按钮 它也永远不会显示 该函数中的所有其他代码都可以完美运行 这是代码
  • 什么是元数据?它在android中有什么用

    我是 Android 新手 之前没有见过或听说过元数据 然而我用谷歌搜索并在 YouTube 上搜索它 它基本上是你的对象的信息 如果我错了请纠正我 任何人都可以帮助我以更好的方式理解它 1 什么是元数据 2 为什么在Android中使用它
  • jQuery 中是否有 $.each 函数的条件循环

    我有一个关于 jQuery 的疑问 each方法 下面是我的ajax 它运行得很好 ajax url js people json js type post dataType json success function data each
  • 如何使用文本样式创建像 stackoverflow 这样的标签

    我想知道如何在输入字段 例如 stackoverflow 的标记系统 内创建 css 样式 当您单击标签时 文本将被设置样式 而且 当您单击样式标签时 它会再次正常 我想我主要关心的是如何在输入字段内设置文本样式 Thanks 标签不是输入
  • Office 365 Rest API - 守护程序周身份验证

    我正在尝试建立一个Ruby用于访问 Office 365 Rest API 的守护程序服务 最近可以通过 OAuth client credentials 流程来做到这一点 如本博客文章所述 https learn microsoft co