{"id":4235,"date":"2013-09-14T12:51:39","date_gmt":"2013-09-14T10:51:39","guid":{"rendered":"http:\/\/www.limilabs.com\/blog\/?p=4235"},"modified":"2022-03-29T15:32:27","modified_gmt":"2022-03-29T13:32:27","slug":"oauth2-outlook-com-imap-web-applications","status":"publish","type":"post","link":"https:\/\/www.limilabs.com\/blog\/oauth2-outlook-com-imap-web-applications","title":{"rendered":"OAuth 2.0 with Outlook.com over IMAP for web applications"},"content":{"rendered":"\n<div class=\"well\">\nYou can also read how to use:\n<p>&nbsp;<\/p>\n<ul>\n<li><a href=\"\/blog\/oauth2-outlook-com-imap-installed-applications\">OAuth 2.0 with Outlook.com over IMAP for installed applications<\/a><\/li>\n<li>OAuth 2.0 with Outlook.com over IMAP for web applications<\/li>\n<\/ul>\n<ul>\n<li><a href=\"https:\/\/www.limilabs.com\/blog\/oauth2-office365-exchange-imap-pop3-smtp\">OAuth 2.0 with Office365\/Exchange IMAP\/POP3\/SMTP<\/a><\/li>\n<li><a href=\"https:\/\/www.limilabs.com\/blog\/oauth2-password-grant-office365-exchange-imap-pop3-smtp\">OAuth 2.0 password grant with Office365\/Exchange IMAP\/POP3\/SMTP<\/a><\/li>\n<li><a href=\"https:\/\/www.limilabs.com\/blog\/oauth2-device-flow-office365-exchange-imap-pop3-smtp\">OAuth 2.0 device flow with Office365\/Exchange IMAP\/POP3\/SMTP<\/a><\/li>\n<\/ul>\n<\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft\"><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/2013\/09\/Outlook.png\" alt=\"Outlook\"\/><\/figure><\/div>\n\n\n\n<p><strong>OAuth&nbsp;<\/strong>is an open protocol to allow secure API authorization in a simple and standard method from desktop and web applications.<\/p>\n\n\n\n<p>\n\nThis article describes using OAuth 2.0 to access Outlook.com IMAP and SMTP servers using&nbsp;<a href=\"https:\/\/www.limilabs.com\/mail\">.NET IMAP component<\/a>&nbsp;in web application scenario (ASP.NET\/ASP.NET MVC). You can also use&nbsp;<a href=\"https:\/\/www.limilabs.com\/blog\/oauth2-outlook-com-imap-installed-applications\">OAuth 2.0 with Outlook.com for installed\/native applications<\/a>.\n\n<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"> DotNetOpenAuth <\/h2>\n\n\n\n<p>First download the latest version of DotNetOpenAuth \u2013 it\u2019s free, open source library that implements OAuth 2.0:&nbsp;<\/p>\n\n\n\n<p><a href=\"http:\/\/www.dotnetopenauth.net\/\">http:\/\/www.dotnetopenauth.net<\/a>  <\/p>\n\n\n\n<p>Add it as a reference and import namespaces:  <\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ c#\n \nusing DotNetOpenAuth.OAuth2;\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: vb; title: ; notranslate\" title=\"\">\n' VB.NET\n \nImports DotNetOpenAuth.OAuth2\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\"> Register Application <\/h2>\n\n\n\n<p>Before you can use OAuth 2.0, you must register your application using the Azure Portal.<\/p>\n\n\n\n<p>This process is described in detail here: <\/p>\n\n\n\n<p><a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/auth-register-app-v2\">https:\/\/docs.microsoft.com\/en-us\/graph\/auth-register-app-v2<\/a><\/p>\n\n\n\n<p>On Azure Portal go to&nbsp;<strong>&#8220;Azure Active Directory \/ App Registrations \/ New Registration&#8221;<\/strong><\/p>\n\n\n\n<p>After registering, you need to add a new&nbsp;<strong>Client Secret<\/strong>&nbsp;for your application. You can do that using the&nbsp;<strong>&#8220;Certificates &amp; secrets&#8221;<\/strong>&nbsp;menu within the&nbsp;<strong>&#8220;Azure Active Directory \/ App Registrations settings&#8221;<\/strong>. <\/p>\n\n\n\n<p>Deprecated url for registering applications: https:\/\/account.live.com\/developers\/applications\/<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">ClientID, ClientSecret, Scope<\/h2>\n\n\n\n<p> Now we can define clientID, clientSecret, redirect url and scope variables, as well as Outlook.com OAuth 2.0 server addresses. Scope basically specifies what services we want to have access to. In our case it is user\u2019s email address and IMAP\/SMTP access: <\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nstring clientID = &quot;000000014810009D&quot;;\nstring clientSecret = &quot;wiRCccXnq1uyKcXnq1uyK&quot;;\nstring redirectUri = &quot;http:\/\/fake-domain-9650932456.com\/OAuth2.aspx&quot;;\n \nAuthorizationServerDescription server = new AuthorizationServerDescription\n{\n    AuthorizationEndpoint = new Uri(&quot;https:\/\/login.live.com\/oauth20_authorize.srf&quot;),\n    TokenEndpoint = new Uri(&quot;https:\/\/login.live.com\/oauth20_token.srf&quot;),\n    ProtocolVersion = ProtocolVersion.V20,\n};\n \nList&lt;string&gt; scope = new List&lt;string&gt;\n{\n    OutlookScope.ImapAndSmtp.Name,\n    OutlookScope.EmailAddress.Name\n};\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\"> Obtain an OAuth 2.0 access token <\/h2>\n\n\n\n<p>\n\nAs we are using&nbsp;<strong>ASP.NET<\/strong>&nbsp;we\u2019ll use&nbsp;<em>WebServerClient<\/em>&nbsp;class:\n\n<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nWebServerClient consumer = new WebServerClient(server, clientID, clientSecret);\n \n\/\/ Here redirect to authorization site occurs\nconsumer.RequestUserAuthorization(scope, new Uri(redirectUri));\n<\/pre><\/div>\n\n\n<p>If you use&nbsp;<strong>ASP.NET MVC<\/strong>&nbsp;the last line is different:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Here redirect to authorization site occurs\nOutgoingWebResponse response = consumer.PrepareRequestUserAuthorization(\nscope, new Uri(redirectUri));\nreturn response.AsActionResult();\n<\/pre><\/div>\n\n\n<p>\n\nAt this point user is redirected to Microsoft to authorize the access:\n\n<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/2013\/09\/Outlook_2Confirm.png\" alt=\"Outlook_2Confirm\"\/><\/figure>\n\n\n\n<p>\n\nAfter this step user is redirected back to your website (http:\/\/fake-domain-9650932456.com\/OAuth2.aspx). Following is this callback code. Its purpose is to get a refresh-token and an access-token:\n\n<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nWebServerClient consumer = new WebServerClient(server, clientID, clientSecret);\nIAuthorizationState grantedAccess = consumer.ProcessUserAuthorization(null);\n \nstring accessToken = grantedAccess.AccessToken;\n<\/pre><\/div>\n\n\n<p>\n\nAn access token is usually short lived, and allows you to access the user\u2019s data. You also received a refresh token. A refresh token can be used to request a new access token once the previous expired.\n\n<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"> Access IMAP\/SMTP server <\/h2>\n\n\n\n<p>\n\nFinally we\u2019ll ask Microsoft for user\u2019s email and use&nbsp;<em>LoginOAUTH2<\/em>&nbsp;method to access Outlook.com IMAP server:\n\n<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nOutlookApi api = new OutlookApi(accessToken);\nstring user = api.GetEmail();\n \nusing (Imap imap = new Imap())\n{\n    imap.ConnectSSL(&quot;imap-mail.outlook.com&quot;);\n    imap.LoginOAUTH2(user, accessToken);\n \n    imap.SelectInbox();\n    List&lt;long&gt; uids = imap.Search(Flag.Unseen);\n \n    foreach (long uid in uids)\n    {\n        var eml = imap.GetMessageByUID(uid);\n        IMail email = new MailBuilder().CreateFromEml(eml);\n        Console.WriteLine(email.Subject);\n    }\n    imap.Close();\n}\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\"> Refreshing access token <\/h2>\n\n\n\n<p>An access token is usually&nbsp;<strong>short lived<\/strong>. The main reason behind this is security and prevention of replay attacks. This means that for long-lived applications you need to refresh the access token.<\/p>\n\n\n\n<p>In most cases web applications don\u2019t need to refresh access token (they request new one every time), thus when using&nbsp;<em>WebServerClient<\/em>&nbsp;refresh token is not sent. To force sending refresh token you need to add \u201cwl.offline_access\u201d to requested scopes:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nList&lt;string&gt; scope = new List&lt;string&gt; \n{\n    OutlookScope.ImapAndSmtp.Name,\n    OutlookScope.EmailAddress.Name,\n    OutlookScope.OfflineAccess.Name\n};\n<\/pre><\/div>\n\n\n<p><strong>Your refresh token will be sent only once \u2013 don\u2019t loose it!<\/strong><\/p>\n\n\n\n<p>We recommend storing entire&nbsp;<em>IAuthorizationState<\/em>&nbsp;object received from&nbsp;<em>WebServerClient.ProcessUserAuthorization<\/em>&nbsp;method call. This object contains both: refresh token and access token, along with its expiration time.<\/p>\n\n\n\n<p>The process of refreshing access token is simple:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nIAuthorizationState grantedAccess = ...\nconsumer.RefreshAuthorization(grantedAccess, TimeSpan.FromMinutes(20));\n<\/pre><\/div>\n\n\n<p>\n\nIn the example above the access token will not be refreshed if its remaining lifetime exceeds 20 minutes.\n\n<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"> Apps and services you\u2019ve given access <\/h2>\n\n\n\n<p>\n\nUsers can manage consent for applications and services that can access some of their data on&nbsp;<a href=\"https:\/\/account.live.com\/consent\/Manage\">consent panel<\/a><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>You can also read how to use: &nbsp; OAuth 2.0 with Outlook.com over IMAP for installed applications OAuth 2.0 with Outlook.com over IMAP for web applications OAuth 2.0 with Office365\/Exchange IMAP\/POP3\/SMTP OAuth 2.0 password grant with Office365\/Exchange IMAP\/POP3\/SMTP OAuth 2.0 device flow with Office365\/Exchange IMAP\/POP3\/SMTP OAuth&nbsp;is an open protocol to allow secure API authorization in [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[10,15,28,77,84,50,85],"class_list":["post-4235","post","type-post","status-publish","format-standard","hentry","category-mail-dll","tag-asp-net","tag-c","tag-imap","tag-imap-component","tag-oauth-2-0","tag-smtp","tag-xoauth2"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts\/4235"}],"collection":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/comments?post=4235"}],"version-history":[{"count":48,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts\/4235\/revisions"}],"predecessor-version":[{"id":6041,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts\/4235\/revisions\/6041"}],"wp:attachment":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/media?parent=4235"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/categories?post=4235"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/tags?post=4235"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}