Срок действия токена доступа Microsoft Graph в веб-формах asp.net истекает — как обновить токены в приложении веб-форм, а не в MVC

У меня есть приложение веб-форм asp.net 4.6 (без MVC). Я обновляю безопасность в своем приложении. Я использую OpenIdConnectAuthentication для аутентификации в нашей Azure AD. Затем я передаю токен доступа в Microsoft graph, чтобы отправить электронное письмо с помощью Office 365. Срок действия моего токена истекает через 60 минут. Мне нужно либо увеличить срок действия до 8 часов, либо обновить токен. Без MVC я не уверен, как с этим справиться. Я ищу помощь с направлением и, возможно, примерами кода.

(Первоначально я пытался использовать образец MVC и поместить его в свой проект, используя класс Session Token. После того, как мы протестировали несколько пользователей, я полагаю, что у меня произошла утечка памяти, и он выйдет из строя примерно через 5 минут.)

Код запуска:

public class Startup
    {
        private readonly string _clientId = ConfigurationManager.AppSettings["ClientId"];
        private readonly string _redirectUri = ConfigurationManager.AppSettings["RedirectUri"];
        private readonly string _authority = ConfigurationManager.AppSettings["Authority"];
        private readonly string _clientSecret = ConfigurationManager.AppSettings["ClientSecret"];

        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
        }

        public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                CookieManager = new SystemWebCookieManager(),
            });


            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                ClientId = _clientId,
                ClientSecret = _clientSecret,
                //Authority = _authority,
                Authority = String.Format(_authority, domain, "/v2.0"),
                RedirectUri = _redirectUri,
                ResponseType = OpenIdConnectResponseType.CodeIdToken,
                Scope = OpenIdConnectScope.OpenIdProfile,
                UseTokenLifetime = false,
                TokenValidationParameters = new TokenValidationParameters { NameClaimType = "name", RequireExpirationTime = false},
                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    AuthorizationCodeReceived = async n =>
                    {
                        // Exchange code for access and ID tokens
                        var auth = String.Format(_authority, "common/oauth2/v2.0", "/token");
                        var tokenClient = new TokenClient($"{auth}", _clientId, _clientSecret);

                        var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(n.Code, _redirectUri);
                        if (tokenResponse.IsError)
                        {
                            throw new Exception(tokenResponse.Error);
                        }
                        var claims = new List<Claim>()
                      {
                        new Claim("id_token", tokenResponse.IdentityToken),
                        new Claim("access_token", tokenResponse.AccessToken)
                      };

                        n.AuthenticationTicket.Identity.AddClaims(claims);
                    },

                },


            });
        }
    }

Помощник SDK:

public class SDKHelper
    {

        // Get an authenticated Microsoft Graph Service client.
        public static GraphServiceClient GetAuthenticatedClient()
        {
            GraphServiceClient graphClient = new GraphServiceClient(
                new DelegateAuthenticationProvider(
                    async (requestMessage) =>
                    {
                         string accessToken = System.Security.Claims.ClaimsPrincipal.Current.FindFirst("access_token").Value;

                        // Append the access token to the request.
                        requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);

                        // Get event times in the current time zone.
                        requestMessage.Headers.Add("Prefer", "outlook.timezone=\"" + TimeZoneInfo.Local.Id + "\"");

                        // This header has been added to identify our sample in the Microsoft Graph service. If extracting this code for your project please remove.
                        requestMessage.Headers.Add("SampleID", "aspnet-snippets-sample");
                    }));
            return graphClient;
        }

    }

Отправка электронной почты:

 GraphServiceClient graphClient = SDKHelper.GetAuthenticatedClient();

            string address = emailaddress;
            string guid = Guid.NewGuid().ToString();

            List<Recipient> recipients = new List<Recipient>();
            recipients.Add(new Recipient
            {
                EmailAddress = new Microsoft.Graph.EmailAddress
                {
                    Address = address
                }
            });

            // Create the message.
            Message email = new Message
            {
                Body = new ItemBody
                {
                    ContentType = Microsoft.Graph.BodyType.Text,
                },
                Subject = "TEST",
                ToRecipients = recipients,
                From = new Recipient
                {
                    EmailAddress = new Microsoft.Graph.EmailAddress
                    {
                        Address = address
                    }
                }

                };

            // Send the message.
            try
            {
                graphClient.Me.SendMail(email, true).Request().PostAsync().Wait();
            }

            catch (ServiceException exMsg)
            {


            }

person virginia    schedule 23.01.2019    source источник


Ответы (1)


Вам необходимо запросить область действия offline_access. Как только вы запросите это, конечная точка /token вернет как access_token, так и refresh_token. По истечении срока действия вашего токена вы можете сделать еще один вызов конечной точки /token, чтобы запросить новый набор токенов доступа и обновления.

Эта статья может оказаться полезной: Microsoft v2 Endpoint Primer. В частности, раздел о токенах обновления.

person Marc LaFleur    schedule 23.01.2019
comment
Большой! Теперь у меня есть токен обновления, и я протестировал его использование. Мне просто нужно найти лучший способ проверить, когда он истекает. - person virginia; 25.01.2019