Office 365 Rest API-守护程序周身份验证 [英] Office 365 Rest API - Daemon week authentication

查看:141
本文介绍了Office 365 Rest API-守护程序周身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建 Ruby 守护程序服务以访问Office 365 rest API.最近,可以通过OAuth'client_credentials'流执行此操作,如本博客文章中所述:

很显然,为了安全起见,我删除了某些信息.即使它是红宝石,您也可以看到我正在使用我的证书通过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特定位应该相当容易.

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

然后您可以执行以下操作:

mailbox = OfficeAPI.new("nick@test.com")
messages = mailbox.request_messages

解决方案

您需要一个client_assertion,而不是您的请求正文中的client_secret.这有点复杂,但这就是您需要该证书的原因.

基本上,您需要构建一个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'
  )

我希望能对您有所帮助!这全部基于我对 ADAL 的研究方法,而我自己还没有在Ruby中测试过.

I am trying to build a Ruby Daemon service to access the Office 365 rest API. It was recently made possible to do this via the OAuth 'client_credentials' flow, as detailed in this blog post: 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

I am struggling to generate a valid access token. The token endpoint returns me a JWT however when using this token I received a 401 with this message:

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

I understand that the client_credentials flow requires you to present a X.509 cert, unfortunately all the examples in the blog post are for C#.

I am using a generated self signed cert and private key to do a client assertion when requesting the token. I followed the steps in the blog post to generate the cert and update the manifest to use this cert.

This is the ruby code for reference:

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

Obviously I have removed certain bits of information for security. Even though it is ruby you can see I am using my cert to validate the client using an SSL connection.

Here's some more infomation on the error:

"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"

Any help would be appreciate.


Edit

For others looking to do something similar in Ruby here's a Gist of the code I use: https://gist.github.com/NGMarmaduke/a088943edbe4e703129d

The example uses a Rails environment but it should be fairly easy to strip out the Rails specific bits.

Remember to replace YOUR CLIENT ID, TENANT_ID and CERT_THUMBPRINT with the correct values and point the cert path and client key methods to the right file path.

Then you can do something like this:

mailbox = OfficeAPI.new("nick@test.com")
messages = mailbox.request_messages

解决方案

Instead of a client_secret in your request body, you need a client_assertion. This is a bit more complex, but it's the reason you need that certificate.

Basically you need to build a JSON Web Token and sign it with your certificate using a SHA256 hash. The token is going to look something like this:

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"
}

If you're still with me, you now need to base64-encode both pieces (separately), then concatenate them with a '.'. So now you should have:

base64_header.base64_payload

Now you take that string and sign it with your certificate, using a SHA256 hash. Then base64-encode the result of that, url-encode it, then append to the string, so now you have:

base64_header.base64_payload.base64_signature

Finally, include this in your POST to the token endpoint as the client_assertion parameter, and also include a client_assertion_type parameter set to "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'
  )

I hope that helps! This is all based on my research into how ADAL does it, and I haven't tested it myself in Ruby.

这篇关于Office 365 Rest API-守护程序周身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆