#c# #azure #azure-active-directory #microsoft-graph-api #azure-ad-graph-api
#c# #azure #azure-active-directory #microsoft-graph-api #azure-ad-graph-api
Вопрос:
Цель — использовать Graph API для отправки электронной почты. Я могу получить токен авторизации, используя приведенный ниже код — https://login.microsoftonline.com/Some_Tenant_ID/oauth2/v2.0/authorize?client_id=SOME_Client_IDamp;response_type=codeamp;redirect_uri=https://localhostamp;response_mode=queryamp;scope=offline_access user.read mail.readamp;state=12345
Область действия user.read и mail.send с автономным доступом. Теперь, используя этот код авторизации, я хочу получить токен обновления. Насколько я понимаю, это должно работать без каких-либо проблем, но по какой-то причине код прерывается в этой строке var httpResponse = (HttpWebResponse)request.GetResponse();
, и я не уверен, почему.
Ошибка кода исключения 400 неверный запрос. мой вывод на консоль.
Может ли кто-нибудь помочь мне здесь и есть ли другой способ получить токен доступа и / или токен обновления из токена авторизации. конечная цель — отправить электронное письмо из graph API.
string tokenUrl = "https://login.microsoftonline.com/myAppTenantID/oauth2/token";
//string tokenUrl = "https://login.microsoftonline.com/myAppTenantID/oauth2/v2.0/token"; I have tried this URL too
string grant_type= "authorization_code";
string ClientID = "MyAppClientID";
string Auth_Code = "My Auth Code";
string RedirectURI = "https://localhost";
string ClientSecret = "my App secret";
Dictionary<string, string> res_dic = null;
string TargetURL = String.Format(tokenUrl);
var request = (System.Net.HttpWebRequest)WebRequest.Create(TargetURL);
request.ContentType = "application/x-www-form-urlencoded";
string RefreshToken = null;
string requestBody = String.Format(@"client_id={0}amp;scope=user.read mail.readamp;code={1}amp;redirect_uri={2}amp;grant_type=authorization_codeamp;client_secret={3}", ClientID, Auth_Code,RedirectURI, ClientSecret);
request.Method = "POST";
using (var streamwriter = new StreamWriter(request.GetRequestStream()))
{
Console.WriteLine("stage 0....");
streamwriter.Write(requestBody);
streamwriter.Flush();
streamwriter.Close();
}
try
{
Console.WriteLine("stage 1....");
//Console.WriteLine("prting response" (HttpWebResponse)request.GetResponse());
var httpResponse = (HttpWebResponse)request.GetResponse();
Console.WriteLine("Stage 2....");
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
Console.WriteLine("Stage 3");
string Result = streamReader.ReadToEnd();
string StatusCode = httpResponse.StatusCode.ToString();
res_dic = JsonConvert.DeserializeObject<Dictionary<string, string>>(Result);
}
}
catch (WebException ex)
{
Console.WriteLine("stage 4");
string ErrorMessage = ex.Message.ToString();
Console.WriteLine(ErrorMessage);
}
RefreshToken = res_dic["refresh_token"].ToString();
}
Ответ №1:
Это лучше для отладки для получения полного сообщения об ошибке, есть много ситуаций, когда возникает эта ошибка.
Область действия в вашем коде необходимо добавить offline_access
, поскольку refresh_token
она будет предоставлена только в том случае, если offline_access
запрошена область действия.
Вы могли бы использовать SDK. Пример кода здесь:
string[] scopes = new string[] { "", "" };
IConfidentialClientApplication app = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithRedirectUri(redirectUri)
.WithClientSecret(clientSecret)
.WithAuthority(authority)
.Build();
AuthorizationCodeProvider auth = new AuthorizationCodeProvider(app, scopes);
GraphServiceClient graphServiceClient = new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) => {
// Retrieve an access token for Microsoft Graph (gets a fresh token if needed).
var authResult = await app.AcquireTokenByAuthorizationCode(scopes, auth_code).ExecuteAsync();
// Add the access token in the Authorization header of the API request.
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
})
);
И этот API используется для отправки почты, вам нужно сначала добавить Mail.Send
разрешение.
var message = new Message
{
Subject = "Meet for lunch?",
Body = new ItemBody
{
ContentType = BodyType.Text,
Content = "The new cafeteria is open."
},
ToRecipients = new List<Recipient>()
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = "fannyd@contoso.onmicrosoft.com"
}
}
},
CcRecipients = new List<Recipient>()
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = "danas@contoso.onmicrosoft.com"
}
}
}
};
var saveToSentItems = false;
await graphClient.Me
.SendMail(message,saveToSentItems)
.Request()
.PostAsync();
Комментарии:
1. Привет, @Pamela, код SDK, которым вы поделились, предназначен для Java, для C # AuthorizationCodeProvider не принимает «Auth code» в качестве параметра. здесь — docs.microsoft.com/en-us/graph/sdks /. … А также я уже использую тег «Offline_access» при запросе кода аутентификации.
2. Извините, @rajan.sngh. Я редактирую код SDK для C #, здесь используется «auth_code»
app.AcquireTokenByAuthorizationCode(scopes, auth_code)
.