服务到服务呼叫和图形APi

时间:2016-06-20 00:37:45

标签: office365api azure-ad-graph-api

我注册了一个网络API https://dev.office.com/app-registration。我保留了签名网址 localhost:8000和RedirectURI as localhost:8000。

在此之后,我创建了一个控制台应用程序来访问图API。这是代码。但它不起作用。我收到错误“访问被拒绝”。

我在这里遗漏了什么?

还有一件事,我检查了access_token,我在那里看不到任何用户信息。             string clientId =“<>”;             string clientsecret =“<>”;             string tenant =“my.com”;

        var authUri = "https://login.microsoftonline.com/" + tenant + "/oauth2/token";  
        var RESOURCE_URL = "https://graph.microsoft.com";

        HttpClient client = new HttpClient();
        var authContext = new AuthenticationContext(authUri);
        var credential = new ClientCredential(clientId: clientId, clientSecret: clientsecret);
            var result = authContext.AcquireTokenAsync(RESOURCE_URL, credential).Result;
            Console.WriteLine(result.AccessToken.ToString());

        client.DefaultRequestHeaders.Add("Authorization", "bearer " + result.AccessToken);
        var httpContent = new StringContent(content, Encoding.GetEncoding("utf-8"), "application/json");
        var response = client.GetAsync("https://graph.microsoft.com/v1.0/users/ankushb/calendar/events").Result;
    //    var response = client.PostAsync("https://graph.microsoft.com/v1.0/groups", httpContent).Result;
        Console.WriteLine(response.Content.ReadAsStringAsync().Result);

1 个答案:

答案 0 :(得分:0)

Azure AD使用的OAuth2有两种基本身份验证流程。

首先是authorization code grant flow,用于访问本机客户端和网站的Web API。在此流程中,用户委派对客户端应用程序的访问权限。

第二个是Client Credentials grant flow,它允许Web服务(机密客户端)在调用另一个Web服务时使用自己的凭据进行身份验证,而不是模仿用户。在这种情况下,客户端通常是中间层Web服务,守护程序服务或网站。

上面的代码使用的是客户端凭据授权流程,这就是没有用户信息的原因。

在您的方案中,您应该注册一个原生应用程序(控制台应用程序不是不应该使用该秘密来请求令牌的机密客户端)并使用授权代码授予流程< / strong>允许用户使用其帐户登录。要在控制台应用程序中使用此流程,我们需要提示Web对话框导航到登录页面并获取auth代码以请求访问令牌。

以下是使用授权代码授权流程对应用进行身份验证的示例:

 var oauth = new OauthConfiguration
        {
            Authority = "https://login.microsoftonline.com",
            Tenant = "common",
            ClientId = "{clientId}",
            RedirectURI = "{redirectURL}",
            Secret = ""
        };
        var tokenResponse = new OAuth2.OauthWebAuthHelper(oauth).AcquireTokenWithResource("https://graph.microsoft.com");
        var accessToken = tokenResponse.GetValue("access_token").Value<string>();
        var refreshToken = tokenResponse.GetValue("refresh_token").Value<string>();


namespace OAuth2
{
public class OauthWebAuthHelper
{
    public enum Version
    {
        V1 = 1,
        V2 = 2
    }

    private OauthConfiguration _configuration;

    private const string OAUTH2_AUTHORIZE_V1_SUFFIX = @"oauth2/";

    private const string OAUTH2_AUTHORIZE_V2_SUFFIX = @"oauth2/v2.0";

    private string _authorizeSuffix;

    public OauthWebAuthHelper(OauthConfiguration configuration, Version version = Version.V1)
    {
        _configuration = configuration;

        switch (version)
        {
            case Version.V1: _authorizeSuffix = OAUTH2_AUTHORIZE_V1_SUFFIX; break;

            case Version.V2: _authorizeSuffix = OAUTH2_AUTHORIZE_V2_SUFFIX; break;
        }
    }

    public void LogOut()
    {
        var dialog = new WebBrowserDialog();

        dialog.Open(string.Format("{0}/logout", EndPointUrl));
    }

    protected string EndPointUrl
    {
        get
        {
            return string.Format("{0}/{1}/{2}", _configuration.Authority, _configuration.Tenant, _authorizeSuffix);
        }
    }


    public JObject GetAuthorizationCode()
    {
        JObject response = new JObject();

        var parameters = new Dictionary<string, string>
            {
                { "response_type", "code" },
                { "client_id", _configuration.ClientId },
                { "redirect_uri", _configuration.RedirectURI },
                { "prompt", "login"}
            };

        var requestUrl = string.Format("{0}/authorize?{1}", EndPointUrl, BuildQueryString(parameters));

        var dialog = new WebBrowserDialog();

        dialog.OnNavigated((sender, arg) =>
        {
            if (arg.Url.AbsoluteUri.StartsWith(_configuration.RedirectURI))
            {
                var collection = HttpUtility.ParseQueryString(arg.Url.Query);

                foreach (var key in collection.AllKeys)
                {
                    response.Add(key, collection[key]);
                }

                dialog.Close();
            }
        });

        dialog.Open(requestUrl);

        return response;
    }


    public JObject GetAuthorizationCode(string scope)
    {
        JObject response = new JObject();

        var parameters = new Dictionary<string, string>
            {
                { "response_type", "code" },
                { "client_id", _configuration.ClientId },
                { "redirect_uri", _configuration.RedirectURI },
                { "prompt", "login"},
                { "scope", scope}
            };

        var requestUrl = string.Format("{0}/authorize?{1}", EndPointUrl, BuildQueryString(parameters));

        var dialog = new WebBrowserDialog();

        dialog.OnNavigated((sender, arg) =>
        {
            if (arg.Url.AbsoluteUri.StartsWith(_configuration.RedirectURI))
            {
                var collection = HttpUtility.ParseQueryString(arg.Url.Query);

                foreach (var key in collection.AllKeys)
                {
                    response.Add(key, collection[key]);
                }

                dialog.Close();
            }
        });

        dialog.Open(requestUrl);

        return response;
    }

    public JObject AcquireTokenWithResource(string resource)
    {
        var codeResponse = GetAuthorizationCode();

        var code = codeResponse.GetValue("code").Value<string>();

        var parameters = new Dictionary<string, string>
            {
                { "resource", resource},
                { "client_id", _configuration.ClientId },
                { "code",  code},
                { "grant_type", "authorization_code" },
                { "redirect_uri", _configuration.RedirectURI},
                { "client_secret",_configuration.Secret}
            };

        var client = new HttpClient();

        var content = new StringContent(BuildQueryString(parameters), Encoding.GetEncoding("utf-8"), "application/x-www-form-urlencoded");

        var url = string.Format("{0}/token", EndPointUrl);

        var response = client.PostAsync(url, content).Result;

        var text = response.Content.ReadAsStringAsync().Result;

        return JsonConvert.DeserializeObject(text) as JObject;
    }


    public JObject RefreshTokenWithResource(string refreshToken)
    {
        var parameters = new Dictionary<string, string>
            {
                { "client_id", _configuration.ClientId },
                { "refresh_token",  refreshToken},
                { "grant_type", "refresh_token" }
            };

        var client = new HttpClient();

        var content = new StringContent(BuildQueryString(parameters), Encoding.GetEncoding("utf-8"), "application/x-www-form-urlencoded");

        var url = string.Format("{0}/token", EndPointUrl);

        var response = client.PostAsync(url, content).Result;

        var text = response.Content.ReadAsStringAsync().Result;

        return JsonConvert.DeserializeObject(text) as JObject;
    }

    public JObject AcquireTokenWithScope(string scope)
    {
        var codeResponse = GetAuthorizationCode(scope);

        var code = codeResponse.GetValue("code").Value<string>();

        var parameters = new Dictionary<string, string>
            {
                { "client_id", _configuration.ClientId },
                { "code",  code},
                { "grant_type", "authorization_code" },
                { "redirect_uri", _configuration.RedirectURI},
            };

        var client = new HttpClient();

        var content = new StringContent(BuildQueryString(parameters), Encoding.GetEncoding("utf-8"), "application/x-www-form-urlencoded");

        var url = string.Format("{0}/token", EndPointUrl);

        var response = client.PostAsync(url, content).Result;

        var text = response.Content.ReadAsStringAsync().Result;

        return JsonConvert.DeserializeObject(text) as JObject;
    }

    private string BuildQueryString(IDictionary<string, string> parameters)
    {
        var list = new List<string>();

        foreach (var parameter in parameters)
        {
            if (!string.IsNullOrEmpty(parameter.Value))
                list.Add(string.Format("{0}={1}", parameter.Key, HttpUtility.UrlEncode(parameter.Value)));
        }

        return string.Join("&", list);
    }
}

 public class OauthConfiguration
{
    public string Authority { get; set; }

    public string Tenant { get; set; }

    public string ClientId { get; set; }

    public string RedirectURI { get; set; }

    public string Secret { get; set; }
}

 public class WebBrowserDialog
{
    private const int DEFAULT_WIDTH = 400;

    private const int DEFAULT_HEIGHT = 500;

    private Form _displayLoginForm;

    private string _title;

    private WebBrowser _browser;

    private WebBrowserNavigatedEventHandler _webBrowserNavigatedEventHandler;

    public WebBrowserDialog()
    {
        _title = "OAuth Basic";

        _browser = new WebBrowser();

        _browser.Width = DEFAULT_WIDTH;

        _browser.Height = DEFAULT_HEIGHT;

        _browser.Navigated += WebBrowserNavigatedEventHandler;

        _displayLoginForm = new Form();

        _displayLoginForm.SuspendLayout();

        _displayLoginForm.Width = DEFAULT_WIDTH;

        _displayLoginForm.Height = DEFAULT_HEIGHT;

        _displayLoginForm.Text = _title;

        _displayLoginForm.Controls.Add(_browser);

        _displayLoginForm.ResumeLayout(false);
    }


    public void OnNavigated(WebBrowserNavigatedEventHandler handler)
    {
        _webBrowserNavigatedEventHandler = handler;
    }

    protected void WebBrowserNavigatedEventHandler(object sender, WebBrowserNavigatedEventArgs e)
    {
        if(_webBrowserNavigatedEventHandler != null)
        {
            _webBrowserNavigatedEventHandler.Invoke(sender, e);
        }
    }

    public void Open(string url)
    {
        _browser.Navigate(url);

        _displayLoginForm.ShowDialog();
    }

    public void Close()
    {
        _displayLoginForm.Close();
    }
}
}

您可以从here获取更多有关Microsoft Graph的示例。