我正在尝试构建 Ruby 守护程序服务来访问Office 365 rest API。最近通过OAuth' client_credentials'来实现这一目标。流程,详见本博文:http://blogs.msdn.com/b/exchangedev/archive/2015/01/22/building-demon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client-credential-flow.aspx
我正在努力生成有效的访问令牌。令牌端点返回给我一个JWT但是当使用这个令牌时,我收到了一条带有此消息的消息:
使用身份验证方法获取访问令牌,该身份验证方法太弱而无法访问此应用程序。提出的auth强度为1,要求为2
我知道client_credentials流程要求您提供X.509证书,不幸的是,博客文章中的所有示例都是针对C#的。
我在请求令牌时使用生成的自签名证书和私钥来执行客户端断言。我按照博客文章中的步骤生成证书并更新清单以使用此证书。
这是红宝石代码供参考:
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"
任何帮助都会受到赞赏。
修改的
对于其他想在Ruby中做类似事情的人来说,这是我使用的代码的要点:https://gist.github.com/NGMarmaduke/a088943edbe4e703129d
该示例使用Rails环境,但删除Rails特定位应该相当容易。
请记住使用正确的值替换您的CLIENT ID,TENANT_ID和CERT_THUMBPRINT,并将证书路径和客户端密钥方法指向正确的文件路径。
然后你可以这样做:
mailbox = OfficeAPI.new("nick@test.com")
messages = mailbox.request_messages
答案 0 :(得分:10)
您需要client_secret
,而不是请求正文中的client_assertion
。这有点复杂,但这是您需要该证书的原因。
基本上,您需要构建一个JSON Web令牌,并使用SHA256哈希对您的证书进行签名。令牌看起来像这样:
部首:
{
"alg": "RS256",
"x5t": "..." // THUMBPRINT of Cert
}
有效载荷:
{
"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"
}
如果你仍然和我在一起,你现在需要对这两个部分进行64位编码(单独编写),然后将它们连接起来。&#39;。所以现在你应该:
base64_header.base64_payload
现在您使用SHA256哈希获取该字符串并使用您的证书对其进行签名。然后对其结果进行base64编码,对其进行url-encode,然后追加到字符串中,所以现在你有:
base64_header.base64_payload.base64_signature
最后,将此作为client_assertion
参数包含在您对POST标记端点的POST中,并将client_assertion_type
参数设置为&#34; urn:ietf:params:oauth:client-assertion型:JWT承载&#34;:
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如何做到这一点的研究,而我还没有在Ruby中对它进行过测试。
答案 1 :(得分:4)
我只是设法让这个工作,所以我想我会再加上一条建议。那里的所有说明文章都说你应该将你的证书添加到清单文件中。我遇到了麻烦,但这就是我所做的,最终使它发挥作用:
.cer
文件(如果您不知道如何转换,请使用google)。这应该是文本编辑器barfs的二进制文件。现在它已经上传,微软将为您提供指纹。它位于“Thumbprint”列中。 但,它是十六进制,而不是base64。所以,像这样转换它:
# Hint: use your actual thumbprint, not this fake one
echo '5292850026FADB09700E7D6C1BCB1CD1F3270BCC' | xxd -r -p | base64
最后,使用此base64编码的指纹作为JSON标题中x5t
的值。
答案 2 :(得分:1)
我在git上的HomeController中添加了一个函数来演示如何使用没有ADAL的客户端断言手动请求访问令牌。使用它可能更容易移植:https://github.com/mattleib/o365api-as-apponly-webapp/commit/12d5b6dc66055625683020576139f5771e6059e1
答案 3 :(得分:0)
只是一些补充:断言中的受众声明与您使用令牌请求解决的端点相同。正如Jason正确识别的那样,这是AAD的令牌端点:https://login.windows.net/ {您想要用于} / oauth2 / token的app令牌的租户。 nbf和exp也是你在unix epoche时间创建断言的时间,例如:在.net中你会做类似&#34; WebConvert.EpocTime(DateTime.UtcNow)&#34;。对于&#34;而不是之前&#34; (nbf)可以减去用于时钟偏移的缓冲器,例如, 5分钟;并且对于(exp)中的到期,增加一些时间,例如15分钟(因此断言在那段时间仍然有效)。
这是令牌请求(原始)的提琴手痕迹: POST https://login.windows.net/0e49ef1f-ca07-45f1-b4c0-ac9409d3e576/oauth2/token HTTP / 1.1 内容类型:application / x-www-form-urlencoded client-request-id:a8108f88-275b-424d-ac28-f675aabe548e return-client-request-id:true x-client-SKU:.NET x-client-Ver:2.12.0.0 x-client-CPU:x64 x-client-OS:Microsoft Windows NT 6.2.9200.0 主持人:login.windows.net 内容长度:983 期待:100-继续 连接:Keep-Alive
资源= HTTPS%3A%2F%2Fgraph.windows.net%2F&安培; CLIENT_ID = f17bb8a5-2bef-4ad5-a83f-cd7113449fc2&安培; client_assertion_type =瓮%3Aietf%3Aparams%3Aoauth%3Aclient断言型%3Ajwt承载&安培; client_assertion = eyJhbGciOiJSUzI1NiIsIng1dCI6ImY4S2JVY0xtMnItS2s4b1Z3ZVZYTFU0NzhJcyJ9.eyJhdWQiOiJodHRwczpcL1wvbG9naW4ud2luZG93cy5uZXRcLzBlNDllZjFmLWNhMDctNDVmMS1iNGMwLWFjOTQwOWQzZTU3Nlwvb2F1dGgyXC90b2tlbiIsImV4cCI6MTQyMjk4NDMzNSwiaXNzIjoiZjE3YmI4YTUtMmJlZi00YWQ1LWE4M2YtY2Q3MTEzNDQ5ZmMyIiwianRpIjoiZTI3OTA5YTctZGYwMC00NjBhLTlmZjctOGZkNDExOWVmNTYzIiwibmJmIjoxNDIyOTgzNzM1LCJzdWIiOiJmMTdiYjhhNS0yYmVmLTRhZDUtYTgzZi1jZDcxMTM0NDlmYzIifQ.g9bo4-lxpNJ4kEOMuQxODU-5iakwSVIzyRQEPLdbpuNn_XD4lcvt2yBIWT12EQaUVKkMyqFrDiIh4Oav565-Po7HfhmSPF3URXVj8Kx5lx17Zh0nWiaNkRXEi1vhwswsfjm1o-8B8LGUJTtT6JXTognrueuSL1aEE_-4qSG1y74aoc949Un1pQCjwuBtao4vs4CPJLu9Y9mVbirVRRtiIfxkUMmzf6yfMtuhugoGmrvUYntUo4x6N2fu4LxGjuIs7czyrMMAmDRo-XK4sAhDo5uof10HKb8ETEU8mhObwNZcz86MYHWbZm3Z_HDOwzC9kA_tp6hWqmlJ3c-gLg5VXA&安培; grant_type = client_credentia LS
希望这有帮助! 祝你好运!
的Matthias