使用本地adfs登录到azure oauth2

问题描述 投票:0回答:1

我正在尝试将oauth2与某些python脚本中的azure租户连接。我创建了一个应用注册,并允许一些API访问。

当我尝试使用用户名和密码进行连接时,我只会得到Error Code 50126(无效的用户名或密码)。

[如果我在应用程序注册中定义了一些机密,并切换为client secret作为grant_type,则可以访问我的应用程序。

但是我想使用用户名和密码。用户名是[email protected],密码也是正确的。

所以我认为我们的ADFS服务器出现问题。

我们正在使用一些本地AD,并将用户数据同步到Azure Connect,但是我们不同步密码。因此,登录到Azure的请求将转发到我们的adfs实例,并在前提下完成。

如何在脚本中实现该逻辑?我需要使用用户名和密码重定向到adfs的东西,并且需要正确的登录响应才能使天青。

我已经为此进行了很多搜索,但没有找到答案。我无法激活密码同步。

我的天蓝色连接参数就像

tokenpost = {
    'client_id':clientid,
    'resource':crmorg,
    'password':password,
    'username':'[email protected]',
    'grant_type':'password'
}
tokenres = requests.post('https://login.microsoftonline.com/<tenantid>/oauth2/token', data=tokenpost)

有些人遇到同样的问题?

最好,罗宾

oauth-2.0 azure-active-directory adfs
1个回答
0
投票

知道了。必须首先从ADFS中获得一个断言。这是对我有很大帮助的文档:https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-saml-bearer-assertion

我现在用Java写的,但是在python中应该非常相等:

package Azure

import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import java.util.Base64;


String getAzureAccessToken(String clientId, String assertion, String azureURL)
{
  HttpClient httpClient = new HttpClient();

  PostMethod methodPost = new PostMethod(azureURL);
  methodPost.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  methodPost.setRequestHeader("Host", "login.microsoftonline.com");
  methodPost.addParameter("grant_type", "urn:ietf:params:oauth:grant-type:saml2-bearer");
  methodPost.addParameter("assertion", Base64.getEncoder().encodeToString(assertion.getBytes()));
  methodPost.addParameter("client_secret", "XXX");
  methodPost.addParameter("client_id", clientId);
  methodPost.addParameter("scope", "XXX");
  methodPost.addParameter("Accept", "application/json");

  int returnCode = httpClient.executeMethod(methodPost)
  if(returnCode != 200)
  {
    throw new Exception("Cannot connect to Azure "+methodPost.getStatusLine().toString())
  }
  BufferedReader br = new BufferedReader(new InputStreamReader(methodPost.getResponseBodyAsStream()));
  String response;
  while ((response = br.readLine()) != null) {
    return response.split("\"access_token\":\"")[1].split("\"")[0];
  }
}

String getAdfsAssertion(String username, String password, String adfsURL)
{
  String adfsSoapXML = """<?xml version="1.0" encoding="utf-8"?>
      <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" 
      xmlns:a="http://www.w3.org/2005/08/addressing" 
      xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
          <s:Header><a:Action s:mustUnderstand="1">http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue</a:Action>
              <a:MessageID>urn:uuid:XXX</a:MessageID>
              <a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo>
              <a:To s:mustUnderstand="1">"""+ adfsURL +"""</a:To>
              <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" >
                  <o:UsernameToken u:Id="XXX">
                      <o:Username>"""+ username +"""</o:Username>
                      <o:Password>"""+ password +"""</o:Password>
                  </o:UsernameToken>
              </o:Security>
          </s:Header>
          <s:Body>
              <trust:RequestSecurityToken xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
                  <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
                      <a:EndpointReference>
                          <a:Address>urn:federation:MicrosoftOnline</a:Address>
                      </a:EndpointReference>
                  </wsp:AppliesTo>
                  <trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType>
                  <trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType>
                  <trust:TokenType>urn:oasis:names:tc:SAML:2.0:assertion</trust:TokenType>
              </trust:RequestSecurityToken>
          </s:Body>
      </s:Envelope>
  """;

  HttpClient httpClient = new HttpClient();
  PostMethod methodPost = new PostMethod(adfsURL);
  methodPost.setRequestBody(adfsSoapXML);
  methodPost.setRequestHeader("SOAPAction", "http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue");
  methodPost.setRequestHeader("Content-type", "application/soap+xml");
  methodPost.setRequestHeader("client-request-id", "XXX");
  methodPost.setRequestHeader("return-client-request-id", "true");
  methodPost.setRequestHeader("Accept", "application/json");

  int returnCode = httpClient.executeMethod(methodPost)
  if(returnCode != 200)
  {
    throw new Exception("Cannot connect to adfs "+methodPost.getStatusLine().toString())
  }
  BufferedReader br = new BufferedReader(new InputStreamReader(methodPost.getResponseBodyAsStream()));
  String response;
  while ((response = br.readLine()) != null) {
    return response.split("<trust:RequestedSecurityToken>")[1].split("</trust:RequestedSecurityToken>")[0];
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.