Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用OAuth授予对Office365的应用程序访问权限?_C#_Winforms_Rest_Oauth_Office365 - Fatal编程技术网

C# 如何使用OAuth授予对Office365的应用程序访问权限?

C# 如何使用OAuth授予对Office365的应用程序访问权限?,c#,winforms,rest,oauth,office365,C#,Winforms,Rest,Oauth,Office365,我试图让用户浏览到一个网页,在那里他必须决定我的应用程序是否可以访问OneDrive for Business上的文件 我使用以下代码并使用: private string\u authorizationEndpoint=”https://login.windows.net/[code]/oauth2/authorize?api版本=1.0/”; 私有字符串\u令牌端点=”https://login.windows.net/"; 私有字符串_clientId=“[Client Id]”; 私有字

我试图让用户浏览到一个网页,在那里他必须决定我的应用程序是否可以访问OneDrive for Business上的文件

我使用以下代码并使用:

private string\u authorizationEndpoint=”https://login.windows.net/[code]/oauth2/authorize?api版本=1.0/”;
私有字符串\u令牌端点=”https://login.windows.net/";
私有字符串_clientId=“[Client Id]”;
私有字符串\u resource=“https%3A%2F%2F[公司]-my.sharepoint.com%2F”;
私有字符串_redirectURI=“http%3A%2F%2Fwww.nu.nl%2F”;
专用字符串_state=“5gdfd60b-8447-4536-b23f-fcb658e19458”;
私有字符串_authorizationCode=“”;
私有令牌信息_TokenInformation=新令牌信息();
私有授权信息_AuthorizationInformation=新授权信息();
私有void btnAuthenticate_单击(对象发送者,事件参数e)
{
webBrowser1.Navigate(GetAuthorizationUrl());
}
私有字符串GetAuthorizationUrl()
{
//创建授权代码请求。
string url=string.Format(“{0}common/oauth2/authorize?response_type=code&client_id={1}&redirect_uri={2}&resource={3}&state={4}”,
_授权端点,
_clientId,
_乌里,
_资源,,
_国家);
返回url;//“https://login.windows.net/[code]/oauth2/authorize?api version=1.0/common/oauth2/authorize?response_type=code&client_id=[client id]&redirect_uri=http%3A%2F%2Fwww.nu.nl%2F&resource=https:%2F%2fooutlook.office365.com%2F&state=5gdfd60b-8447-4536-b23f-fcb658e19458”
}
私有无效webBrowser1_已导航(对象发送方,WebBrowserNavigatedEventArgs e)
{
txtUrl.Text=e.Url.AbsoluteUri.ToString();
if(e.Url.AbsoluteUri.Contains(“code=”)&&e.Url.AbsoluteUri.Contains(“state”))
{
var splited=e.Url.AbsoluteUri.Split(新字符[]{'=','&});
_authorizationInformation.Code=拆分的[1];
_authorizationInformation.SessionState=已拆分[3];
if(_authorizationInformation.SessionState.Equals(_state))//需要更改每个请求以避免CSRF
{
获取相关信息(授权信息);
}
其他的
{
MessageBox.Show(“跨站点请求伪造”,“错误”,MessageBoxButtons.OK,MessageBoxIcon.Error);
}
}
}
私有字符串GetAdminPermissionUrl()
{
返回string.Format(“{0}common/oauth2/authorize?&response_type=code&client_id={1}&redirect_-uri={2}&resource={3}&state={4}&prompt=admin_-consent”,
_授权端点,
_clientId,
_乌里,
_资源,,
_陈述
);
}
私有令牌信息GetTokenInformation(授权信息authInformation)
{
尝试
{
var response=Post(HttpUtility.UrlEncode(_-tokenEndpoint+“common/oauth2/token/”),新的NameValueCollection(){
{“授权类型”、“授权代码”},
{“code”,authInformation.code},
{“重定向uri”,{U重定向uri},
{“client_id”,“clientId},
//{“client_secret”,根据我提到的网站,我需要一个clientsecret,但这是一个nativa应用程序,所以我没有
});
Stream responseStream=新的内存流(响应);
使用(变量读取器=新的流读取器(responseStream))
{
var json=reader.ReadToEnd();
_tokenInformation=JsonConvert.DeserializeObject(json);
}
}
捕获(异常)
{
Show(exception.Message,“Error”+exception.HResult.ToString(),MessageBoxButtons.OK,MessageBoxIcon.Error);
}
返回null;
}
公共字节[]Post(字符串uri、NameValueCollection对)
{
字节[]响应=null;
使用(WebClient=newWebClient())
{
response=client.UploadValues(uri,对);
}
返回响应;
}
-您可以假设我使用了正确的凭据。

当用户登录并授予访问权限时
根据我前面提到的网站,我得到一个返回的代码,用于交换accesstoken和refreshtoken

现在有一个问题,我没有客户机机密(在Azure Active Directory中),因为我想我开发了一个本地应用程序

GetTokenInformation方法现在不起作用。 如何正确获取accesstoken和刷新token


提前谢谢

如果您在Azure管理门户中将应用程序配置为本机应用程序,则无需提供“client\u secret”参数

但是,您确实需要在发送到令牌授权端点的帖子中提供一个“resource”参数。这是一个字符串,它引用您希望获取其访问/刷新令牌的Office 365资源。这与您在初始身份验证请求url中使用的资源字符串相同。(编辑:我认为甚至没有必要将资源参数添加到初始身份验证请求中-在我的测试中没有资源参数也可以工作。但是在发布到授权端点以获取令牌时,这是肯定必要的)


最后,您还应该确保您的本机应用程序在Azure管理门户中具有正确的权限设置。更具体地说,如果尚未启用,则需要将“Office 365 Sharepoint Online”应用程序添加到“其他应用程序的权限”部分,并将该应用程序的必要详细权限标记为选中状态。

v2.0协议-OAuth 2.0授权代码流 `

private static string redirectDomain=System.Configuration.ConfigurationManager.AppSettings[“DomainName”];
私有字符串状态=Guid.NewGuid().ToString();
私有静态字符串client_id=System.Configuration.ConfigurationManager.AppSettings[“O365ClientId”];
私有静态字符串client_secret=System.Config
private string _authorizationEndpoint = "https://login.windows.net/[code]/oauth2/authorize?api-version=1.0/";
private string _tokenEndpoint = "https://login.windows.net/";
private string _clientId = "[Client Id]";
private string _resource = "https%3A%2F%2F[company]-my.sharepoint.com%2F"; 
private string _redirectURI = "http%3A%2F%2Fwww.nu.nl%2F";
private string _state = "5gdfd60b-8447-4536-b23f-fcb658e19458"; 
private string _authorizationCode = "";

private TokenInformation _tokenInformation = new TokenInformation();
private AuthorizationInformation _authorizationInformation = new AuthorizationInformation();

private void btnAuthenticate_Click(object sender, EventArgs e)
{
    webBrowser1.Navigate(GetAuthorizationUrl());
}

private string GetAuthorizationUrl()
{
    // Create a request for an authorization code.
    string url = string.Format("{0}common/oauth2/authorize?response_type=code&client_id={1}&redirect_uri={2}&resource={3}&state={4}",
            _authorizationEndpoint,
            _clientId,
            _redirectURI,
            _resource,
            _state);
    return url; //"https://login.windows.net/[code]/oauth2/authorize?api-version=1.0/common/oauth2/authorize?response_type=code&client_id=[Client Id]&redirect_uri=http%3A%2F%2Fwww.nu.nl%2F&resource=https:%2f%2foutlook.office365.com%2f&state=5gdfd60b-8447-4536-b23f-fcb658e19458"
}

private void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
    txtUrl.Text = e.Url.AbsoluteUri.ToString();
    if (e.Url.AbsoluteUri.Contains("code=") && e.Url.AbsoluteUri.Contains("state"))
    {
        var splited = e.Url.AbsoluteUri.Split(new char[] { '=', '&' });
        _authorizationInformation.Code = splited[1];
        _authorizationInformation.SessionState = splited[3];

        if (_authorizationInformation.SessionState.Equals(_state)) // Needs to change every request in order to avoid CSRF
        {
            GetTokenInformation(_authorizationInformation);
        }
        else
        {
            MessageBox.Show("Cross-site request forgery", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
}

private string GetAdminPermissionUrl()
{
    return string.Format("{0}common/oauth2/authorize?&response_type=code&client_id={1}&redirect_uri={2}&resource={3}&state={4}&prompt=admin_consent",
            _authorizationEndpoint,
            _clientId,
            _redirectURI,
            _resource,
            _state
        );
}

private TokenInformation GetTokenInformation(AuthorizationInformation authInformation)
{
    try
    {
        var response = Post(HttpUtility.UrlEncode(_tokenEndpoint + "common/oauth2/token/"), new NameValueCollection(){ 
            { "grant_type", "authorization_code" },
            { "code", authInformation.Code },
            { "redirect_uri", _redirectURI },
            { "client_id", _clientId },
            //{ "client_secret", "" }, According to the website I mentioned I need to have a clientsecret, but this is a nativa application so I dont have one
        });

        Stream responseStream = new MemoryStream(response);
        using (var reader = new StreamReader(responseStream))
        {
            var json = reader.ReadToEnd();
            _tokenInformation = JsonConvert.DeserializeObject<TokenInformation>(json);
        }
    }
    catch (Exception exception)
    {
        MessageBox.Show(exception.Message, "Error" + exception.HResult.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    return null;
}


public byte[] Post(string uri, NameValueCollection pairs)
{
    byte[] response = null;
    using (WebClient client = new WebClient())
    {
        response = client.UploadValues(uri, pairs);
    }
    return response;
}
private static string redirectDomain = System.Configuration.ConfigurationManager.AppSettings["DomainName"];
        private string state = Guid.NewGuid().ToString();
        private static string client_id = System.Configuration.ConfigurationManager.AppSettings["O365ClientId"];
        private static string client_secret = System.Configuration.ConfigurationManager.AppSettings["O365ClientSecret"];
 public ActionResult IndexAsync(CancellationToken cancellationToken)
        {
            string url = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id="+client_id+"&response_type=code&redirect_uri=http://localhost/Controllers/o365login/callback&response_mode=query&scope=openid%20offline_access%20https%3A%2F%2Fgraph.microsoft.com%2Fmail.read&state=" + state;
            return  Redirect(url);
        }
    public async void Callback(string code,string state)
        {
            var o365UserInfo = await getO365UserInfo(code);
            if(o365UserInfo != null)
            {
                O365user o365User =   GetEmailFromIdToken(o365UserInfo.access_token);
                if (o365User != null)
                {

                }
            }
        }
    private async Task<O365UserInfo> getO365UserInfo(string code)
        {
            try
            {
                string url = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
                List<KeyValuePair<string, string>> postData = new List<KeyValuePair<string, string>>();
                postData.Add(new KeyValuePair<string, string>("grant_type", "authorization_code"));
                postData.Add(new KeyValuePair<string, string>("code", code));
                postData.Add(new KeyValuePair<string, string>("redirect_uri", "http://localhost/Controllers/o365login/callback"));
                postData.Add(new KeyValuePair<string, string>("client_id", client_id));
                postData.Add(new KeyValuePair<string, string>("client_secret", client_secret));
                using (var httpClient = new HttpClient())
                {
                    using (var content = new FormUrlEncodedContent(postData))
                    {
                        content.Headers.Clear();
                        content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
                        var req = new HttpRequestMessage(HttpMethod.Post, url) { Content = content };
                        HttpResponseMessage response = await httpClient.SendAsync(req);
                        O365UserInfo o365UserInfo= await response.Content.ReadAsAsync<O365UserInfo>();
                        return o365UserInfo;
                    }
                }
            }catch(Exception ex)
            {
                return null;
            }
        }
class O365UserInfo
        {
            public string access_token { get; set; }
            public string token_type { get; set; }
            public int expires_in { get; set; }
            public string expires_on { get; set; }
            public string resource { get; set; }
            public string refresh_token { get; set; }
            public string scope { get; set; }
            public string id_token { get; set; }
        }
        class O365user
        {
            public string name { get; set; }
            public string upn { get; set; }
        }