我正在尝试构建Ruby Daemon服务来访问Office 365 rest API。最近,可以通过OAuth“ client_credentials”流程执行此操作,如本博客文章中所述:http : //blogs.msdn.com/b/exchangedev/archive/2015/01/22/building-demon-or与办公室365邮件日历和联系人API的应用程序服务-apis-oauth2-client-credential-flow.aspx
我正在努力生成有效的访问令牌。令牌端点向我返回了一个JWT,但是使用此令牌时,我收到了一条带有以下消息的401:
使用太弱而无法允许对此应用程序进行访问的身份验证方法来获取访问令牌。显示的身份验证强度为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
显然,为了安全起见,我删除了某些信息。即使它是红宝石,您也可以看到我正在使用我的证书通过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("[email protected]")
messages = mailbox.request_messages
而不是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"
}
如果您仍然和我在一起,则现在需要对这两段进行base64编码(分别),然后将它们连接为“。”。因此,现在您应该具有:
base64_header.base64_payload
现在,您使用SHA256散列获取该字符串并使用证书对其进行签名。然后对结果进行base64编码,对其进行url编码,然后追加到字符串,所以现在您有了:
base64_header.base64_payload.base64_signature
最后,将此client_assertion
参数作为参数包含在您的POST到令牌端点中,还包括一个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'
)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句