<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mark Foppen</title>
    <description>The latest articles on DEV Community by Mark Foppen (@foppenma).</description>
    <link>https://dev.to/foppenma</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F143771%2Fcc53a00c-4c2c-475f-a763-b31ff08f2e78.jpeg</url>
      <title>DEV Community: Mark Foppen</title>
      <link>https://dev.to/foppenma</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/foppenma"/>
    <language>en</language>
    <item>
      <title>Blazor WebAssembly with Azure Active Directory and Azure Functions</title>
      <dc:creator>Mark Foppen</dc:creator>
      <pubDate>Thu, 02 Apr 2020 09:19:34 +0000</pubDate>
      <link>https://dev.to/foppenma/blazor-webassembly-with-azure-active-directory-and-azure-functions-4i9</link>
      <guid>https://dev.to/foppenma/blazor-webassembly-with-azure-active-directory-and-azure-functions-4i9</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m-NvrcKe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2020/04/florian-olivo-4hbJ-eymZ1o-unsplash.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m-NvrcKe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2020/04/florian-olivo-4hbJ-eymZ1o-unsplash.jpg" alt="Blazor WebAssembly with Azure Active Directory and Azure Functions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since the newest Blazor WebAssembly version we have to possibility to use MSAL to authenticate with Azure AD and other OpenID Connect providers. In this post I will focus on authentication with Azure AD. For this I created a &lt;a href="https://github.com/foppenm/multi-tenant-blazor-web-and-backend"&gt;repository&lt;/a&gt; on github.&lt;br&gt;&lt;br&gt;
This solution will allow you to authenticate and make calls to an Azure function with Blazor WebAssembly.The Azure function and Blazor app will be Azure Active Directory protected.&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use the latest Blazor preview installed 3.2.0-preview3.20168.3. See &lt;a href="https://devblogs.microsoft.com/aspnet/blazor-webassembly-3-2-0-preview-3-release-now-available/"&gt;here&lt;/a&gt; for more info.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;First, we need to create an app registration in your Azure Active Directory. You can do this by going to &lt;a href="https://portal.azure.com"&gt;https://portal.azure.com&lt;/a&gt; for the Tenant you want to deploy your app in. Create an application like below. Set the redirect URL to localhost so that you can use it on your local machine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0k6YGkDj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/foppenm/multi-tenant-blazor-web-and-backend/master/docs/images/RegisterApp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0k6YGkDj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/foppenm/multi-tenant-blazor-web-and-backend/master/docs/images/RegisterApp.png" alt="Blazor WebAssembly with Azure Active Directory and Azure Functions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After your registration is completed it should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3MO7XnqT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/foppenm/multi-tenant-blazor-web-and-backend/master/docs/images/RegisterAppCompleted.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3MO7XnqT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/foppenm/multi-tenant-blazor-web-and-backend/master/docs/images/RegisterAppCompleted.png" alt="Blazor WebAssembly with Azure Active Directory and Azure Functions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to the "Expose Api" page and set the Application ID URI to API://clientid. My client id in this case is ddc79846-0ed0-4347-a997-dc10bcf58e48. After this, you also need to set the scope. Set this to API://clientid/user_impersonation and Save.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uK4ThXO9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/foppenm/multi-tenant-blazor-web-and-backend/master/docs/images/ExposeApi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uK4ThXO9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/foppenm/multi-tenant-blazor-web-and-backend/master/docs/images/ExposeApi.png" alt="Blazor WebAssembly with Azure Active Directory and Azure Functions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's go to the Authentication page and change the URLs to match the ones below. Als make sure to check the &lt;strong&gt;Access Tokens&lt;/strong&gt; and &lt;strong&gt;ID tokens&lt;/strong&gt; checkbox. If you haven't already done so make the app multi-tenant at the bottom.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RmoD_xiE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/foppenm/multi-tenant-blazor-web-and-backend/master/docs/images/Authenticationpage.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RmoD_xiE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/foppenm/multi-tenant-blazor-web-and-backend/master/docs/images/Authenticationpage.png" alt="Blazor WebAssembly with Azure Active Directory and Azure Functions"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Azure function config
&lt;/h2&gt;

&lt;p&gt;I am not going in-depth on how to deploy an Azure function and will go straight to the configuration. Before we do that we need to take 2 things from the application registration we just configured&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Client ID&lt;/li&gt;
&lt;li&gt;Client Secret (Generate one in the Certificates &amp;amp; Secrets page)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After you have copied these go to your azure function and go to the new still in preview portal of Azure functions. Go to the Authentication/Authorization page.&lt;/p&gt;

&lt;p&gt;Do 3 things here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Switch App Service Authentication to &lt;strong&gt;On&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Set Action to take when a request is not authenticated to &lt;strong&gt;Log in with Azure Active Directory&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click the Azure Active Directory row&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ggsUinqQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/foppenm/multi-tenant-blazor-web-and-backend/master/docs/images/EnableAdOnlyAuth.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ggsUinqQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/foppenm/multi-tenant-blazor-web-and-backend/master/docs/images/EnableAdOnlyAuth.png" alt="Blazor WebAssembly with Azure Active Directory and Azure Functions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second to last step is to set the Active Directory Authentication to advanced and paste you two values we copied earlier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fgwXsJNd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/foppenm/multi-tenant-blazor-web-and-backend/master/docs/images/SetTheAdAuthenticatioOptions.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fgwXsJNd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/foppenm/multi-tenant-blazor-web-and-backend/master/docs/images/SetTheAdAuthenticatioOptions.png" alt="Blazor WebAssembly with Azure Active Directory and Azure Functions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This should be enough to get it working. Still, if you want to make sure it works on your local machine we have one more setting to go.&lt;/p&gt;

&lt;p&gt;Go to the cors page of azure functions and set an extra cors rule to your localhost environment as I did:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QssaiQHy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/foppenm/multi-tenant-blazor-web-and-backend/master/docs/images/Cors.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QssaiQHy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/foppenm/multi-tenant-blazor-web-and-backend/master/docs/images/Cors.png" alt="Blazor WebAssembly with Azure Active Directory and Azure Functions"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Configure the Solution
&lt;/h2&gt;

&lt;p&gt;For you to be able to run this solution there are a few settings that need to be done. Open the solution (or folder if you are in vs code) and edit the appsettings.json file in the &lt;strong&gt;Web&lt;/strong&gt; project. Set your own clientId and API backend. This can be the Azure function we just configured or a localhost function. Do note that on your local machine you can not test the AD authentication.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "clientId": "ddc79846-0ed0-4347-a997-dc10bcf58e48",
  "postLogoutUrl": "https://localhost:5001",
  "apiBackend": "https://&amp;lt;your azure functionn&amp;gt;.azurewebsites.net/api/" // or "https://localhost:7071/api"
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That is it. If something is not working for you, feel free to create an issue on the github repository.&lt;/p&gt;

</description>
      <category>blazor</category>
      <category>webassembly</category>
      <category>dotnet</category>
      <category>azurefunctions</category>
    </item>
    <item>
      <title>Azure AD Application Registration Security with Graph API</title>
      <dc:creator>Mark Foppen</dc:creator>
      <pubDate>Fri, 04 Oct 2019 15:53:45 +0000</pubDate>
      <link>https://dev.to/foppenma/azure-ad-application-registration-security-with-graph-api-1p48</link>
      <guid>https://dev.to/foppenma/azure-ad-application-registration-security-with-graph-api-1p48</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2Fstockvault-digital-padlock-on-data-screen-web-and-data-security180399.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2Fstockvault-digital-padlock-on-data-screen-web-and-data-security180399.jpg" alt="Azure AD Application Registration Security with Graph API"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In many Azure Active Directories, there are registered applications. These applications all have security permissions. Do you know which one has which permissions and can access what data and resources? Do you know who has the secrets that give access to this data? Let's take a look at how we can achieve this.&lt;/p&gt;

&lt;p&gt;In this blog, I will show you how to generate a list of applications and the permissions they have by using the beta version of the Microsoft Graph API. This will allow you to act on them. It is fine if some applications have a high permission level. At least after reading this blog you have the change retrieve them and to make sure the owners of the applications guard the secrets the best they can. Let's dive right into retrieving the applications.&lt;/p&gt;

&lt;p&gt;Don't know what Azure Active Directory Application registrations are? Check out &lt;a href="https://dev.to/foppenma/understanding-azure-active-directory-application-registrations-5f57-temp-slug-8306065"&gt;this&lt;/a&gt; earlier blog post. If you wanna know more about the Microsoft Graph API beta you can see &lt;a href="https://dev.to/foppenma/how-to-access-data-from-the-beta-channel-of-graph-api-od5"&gt;this&lt;/a&gt; blog on how to connect to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup app registration with permissions
&lt;/h2&gt;

&lt;p&gt;Before we can retrieve the applications from the Graph API, we need to authenticate it to the Azure Active Directory. This is done by adding an application registration. Yes, this is the same type of application we are trying to retrieve. In this case we are need to create a application registration with Directory.Read.All permission.&lt;/p&gt;

&lt;p&gt;To create an application you can go to my GitHub &lt;a href="https://github.com/foppenm/Microsoft-Graph-Applications" rel="noopener noreferrer"&gt;here&lt;/a&gt;. There is a detailed guide in the readme on how to set this up.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;After you are done retrieving the applications, make sure to disable or delete this application.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now that you have created the application, you can get an access token. We do this in C# by using the MSAL library (Microsoft.Identity.Client). This allows you to generate the token we use later in this blog.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ccab = ConfidentialClientApplicationBuilder
    .Create(clientId)
    .WithClientSecret(clientSecret)
    .WithTenantId(tenantId)
    .Build();

var tokenResult = ccab.AcquireTokenForClient(new List&amp;lt;string&amp;gt; { "https://graph.microsoft.com/.default" });
var token = await tokenResult.ExecuteAsync();
return token.AccessToken;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The token we just retrieved is a JWT token that permits us to access the Graph API. Specifically in this case to retrieve the applications from an Azure tenant.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you ever wonder what permissions are associated with the current token. Go to &lt;a href="https://jwt.io/" rel="noopener noreferrer"&gt;https://jwt.io/&lt;/a&gt; and paste in your token.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Retrieve Applications
&lt;/h2&gt;

&lt;p&gt;To retrieve the applications we use the previous access token and make a GET call to &lt;a href="https://graph.microsoft.com/beta/applications" rel="noopener noreferrer"&gt;https://graph.microsoft.com/beta/applications&lt;/a&gt;. Notice that we make use of the &lt;strong&gt;beta&lt;/strong&gt; version of the Graph API.&lt;/p&gt;

&lt;p&gt;Below is the C# code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using (var request = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/beta/applications"))
{
    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "&amp;lt;Your Access Token Here&amp;gt;");

    using (var client = new HttpClient())
    using (var response = await client.SendAsync(request))
    {
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadAsStringAsync();
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Executing this code will return all the applications from the tenant.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Each call to the Graph API will result in a maximum of 100 results. If there are more results, there will be a nextlink property with a URL to retrieve the next 100 results.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Below is an example of the JSON returned. I removed a lot of empty properties in this case. As you can see we have retrieved an application but the only readable data is the display name. What API's is this app giving permissions to? What permissions are assigned? Are these delegated or application permissions?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "id": "1deb4abb-fea2-401b-8881-0bf7f86dda12",
    "appId": "092424f2-09ba-49fb-bfd1-f4fd9c352e82",
    "createdDateTime": "2019-08-10T21:08:51Z",
    "displayName": "Data Engine",
    "appRoles": [],
    "keyCredentials": [],
    "passwordCredentials": [],
    "requiredResourceAccess": [
        {
            "resourceAppId": "00000003-0000-0000-c000-000000000000",
            "resourceAccess": [
                {
                    "id": "465a38f9-76ea-45b9-9f34-9e8b0d4b0b42",
                    "type": "Scope"
                },
                {
                    "id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
                    "type": "Scope"
                },
                {
                    "id": "df021288-bdef-4463-88db-98f22de89214",
                    "type": "Role"
                }
            ]
        }
    ]
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make sense of al these guids we need to retrieve some extra data. By retrieving the service principle of each API we can link the guids to some actual text.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retrieve service principles
&lt;/h2&gt;

&lt;p&gt;First, let's retrieve the service principles in the Azure tenant. We are doing the same call as before with a slight difference in the URL. Instead of calling the &lt;strong&gt;/application&lt;/strong&gt; we now call &lt;strong&gt;/servicePrincipals?filter=appId eq '00000003-0000-0000-c000-000000000000'&lt;/strong&gt;. This will retrieve the associated API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using (var request = new HttpRequestMessage(HttpMethod.Get, "/servicePrincipals?filter=appId eq '00000003-0000-0000-c000-000000000000'"))
{
    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken);

    using (var client = new HttpClient())
    using (var response = await client.SendAsync(request))
    {
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadAsStringAsync();
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see below it will return the information about the Microsoft Graph. Also for this response, I deleted a lot of properties to make it a little more readable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "id": "9a1be802-1792-48de-92e4-ea67cb2ec6e9",
    "appDisplayName": "Microsoft Graph",
    "appId": "00000003-0000-0000-c000-000000000000",
    "displayName": "Microsoft Graph",
    "publishedPermissionScopes": [
        {
            "adminConsentDescription": "Allows the app to read events in user calendars . ",
            "adminConsentDisplayName": "Read user calendars ",
            "id": "465a38f9-76ea-45b9-9f34-9e8b0d4b0b42",
            "isEnabled": true,
            "type": "User",
            "userConsentDescription": "Allows the app to read events in your calendars. ",
            "userConsentDisplayName": "Read your calendars ",
            "value": "Calendars.Read"
        },
        {
            "adminConsentDescription": "Allows users to sign-in to the app, and allows the app to read the profile of signed-in users. It also allows the app to read basic company information of signed-in users.",
            "adminConsentDisplayName": "Sign in and read user profile",
            "id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
            "isEnabled": true,
            "type": "User",
            "userConsentDescription": "Allows you to sign in to the app with your organizational account and let the app read your profile. It also allows the app to read basic company information.",
            "userConsentDisplayName": "Sign you in and read your profile",
            "value": "User.Read"
        }
    ],
    "publisherName": "Microsoft Services",
    "appRoles": [
        {
            "allowedMemberTypes": [
                "Application"
            ],
            "description": "Allows the app to read user profiles without a signed in user.",
            "displayName": "Read all users' full profiles",
            "id": "df021288-bdef-4463-88db-98f22de89214",
            "isEnabled": true,
            "origin": "Application",
            "value": "User.Read.All"
        }
    ]
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the JSON result above you can also see that there are &lt;strong&gt;published permission scopes&lt;/strong&gt; and &lt;strong&gt;approles&lt;/strong&gt;. published permissions scopes are your delegated permissions and the approles are your application permissions. As you can see there is a lot of human-readable text instead of guids. Below is a simple overview of how each property links to another.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F10%2FAnnotation-2019-10-02-111549.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F10%2FAnnotation-2019-10-02-111549.png" alt="Azure AD Application Registration Security with Graph API"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we have retrieved the application we also want to know who the owner is. In case we have questions or for governance purposes, you want to know who owns the applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retrieve the owners
&lt;/h2&gt;

&lt;p&gt;Retrieving the owners is again the same principle as the other calls. By supplying your app id in the URL you can retrieve the owners of that specific app. It can return multiple results.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using (var request = new HttpRequestMessage(HttpMethod.Get, $"/applications/{AppId}/owners"))
{
    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken);

    using (var client = new HttpClient())
    using (var response = await client.SendAsync(request))
    {
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadAsStringAsync();
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the call is executed you will receive a JSON response similar to this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "@odata.type": "#microsoft.graph.user",
    "displayName": "Mark Foppen",
    "jobTitle": "Developer",
    "userPrincipalName": "test@re-mark-able.net"
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Output wrapped in web application
&lt;/h2&gt;

&lt;p&gt;Now you know how to retrieve the applications from you Azure tenant, link all the properties together and retrieve the owners, it is time to make it a little more visible then JSON output. To do this I created a simple web app that shows the output of the call for your specific tenant. The source code can be downloaded from my GitHub &lt;a href="https://github.com/foppenm/Microsoft-Graph-Applications" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F09%2FUi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F09%2FUi.png" alt="Azure AD Application Registration Security with Graph API"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Making it more secure
&lt;/h2&gt;

&lt;p&gt;Now we know what applications we have and what permissions are assigned. We also retrieved who the owner is. Now it's up to you to at least retrieve all the applications from your tenant and put some sort of governance on them. Of course, it is okay to keep applications that have permission to access data but now you can at least compare en react on it. Contact the owners to check if the app is still used and discuss why those permissions are needed.&lt;/p&gt;

&lt;p&gt;Thanks for reading and keep pushing to make things more secure!&lt;/p&gt;

</description>
      <category>security</category>
      <category>azure</category>
      <category>azureactivedirectory</category>
    </item>
    <item>
      <title>Sending your Threat Indicators to Azure Sentinel</title>
      <dc:creator>Mark Foppen</dc:creator>
      <pubDate>Sun, 18 Aug 2019 22:14:00 +0000</pubDate>
      <link>https://dev.to/foppenma/sending-your-threat-indicators-to-azure-sentinel-4oma</link>
      <guid>https://dev.to/foppenma/sending-your-threat-indicators-to-azure-sentinel-4oma</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rTnNdqwG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/08/ZnQSkLZ-_400x400-1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rTnNdqwG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/08/ZnQSkLZ-_400x400-1.jpg" alt="Sending your Threat Indicators to Azure Sentinel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How and why should you send your threat indicators to Azure Sentinel or add them manually to the Microsoft Defender Advanced Threat Protection (MDATP) solution? What is an indicator, also known as an Indicator of Compromise (IoC)? Why should you care? How can you do this? Let's go through this and add indicators manually and by using a Logic App and the Microsoft Graph Security API.&lt;/p&gt;

&lt;p&gt;First, we will take a look into what an Indicator is and how it works in MDATP to get a better understanding of what we are dealing with. Then send the indicator to Azure Sentinel through the Microsoft Graph Security API.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an indicator?
&lt;/h2&gt;

&lt;p&gt;An IoC is a piece of evidence that could indicate you have malicious activity in your environment. This can have many forms i.e.:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File hashes&lt;/li&gt;
&lt;li&gt;Network activities&lt;/li&gt;
&lt;li&gt;Ip address or URL's&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The IoC on its own doesn't necessarily mean you have been compromised. Often the combination of file hashes, network activity, and origin (IP or Url) are the providers of context which in turn determines if it is a threat. For more info, you can have a look at the Mitre ATT&amp;amp;CK framework &lt;a href="https://digitalguardian.com/blog/what-mitre-attck-framework"&gt;here&lt;/a&gt;. This is a framework to describe what tactics and techniques are used to identify and defend against attacks on your organization.&lt;/p&gt;

&lt;p&gt;This is all good and fine but what if you encounter an application on one of your managed devices and want to block it for the entire organization? Take for example an Android application (.apk) that is not detected by MDATP at the moment. As we all know these applications can also have malware in them or download other applications. One of your users sends it to another and another and so forth. How can you stop this? By adding the file hash of the APK to the indicators in MDATP. This will stop the spreading of the file and allow you to further investigate it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add an indicator manually
&lt;/h2&gt;

&lt;p&gt;Let's go to the MDATP &lt;a href="https://securitycenter.windows.com"&gt;portal&lt;/a&gt; and sign in. To get to the &lt;strong&gt;Indicators&lt;/strong&gt; page we first have to go to &lt;strong&gt;Settings&lt;/strong&gt; in the left menu and then to the indicators page. Here you have an overview of all your indicators. This should look like the portal below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Lni_nhuD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/Overview.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Lni_nhuD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/Overview.png" alt="Sending your Threat Indicators to Azure Sentinel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By clicking on &lt;strong&gt;+Add Indicator&lt;/strong&gt; we can add a new indicator manually. Here you must give the file hash which can be a SHA1, SHA256 or MD5. For now, there is a limit of 5000 indicators at the time of writing this post. By setting the expiration date you automatically clean them up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6rYOd7yn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/AddIndicator.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6rYOd7yn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/AddIndicator.png" alt="Sending your Threat Indicators to Azure Sentinel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you go to the next step in adding an indicator you must determine the actions MDATP should take when there is a file with the same hash. We have 3 possible actions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allow&lt;/li&gt;
&lt;li&gt;Alert Only&lt;/li&gt;
&lt;li&gt;Alert and Block&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Allow&lt;/strong&gt; is used when MDATP is already blocking a file or executable that you do not want to be blocked. Take for example Mimikatz, if you put the file hash of that in here you can use the program without MDATP putting it in quarantine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alert Only&lt;/strong&gt; is used when you only want to receive an alert that the file is detected but not want to block it. If you can post the Alert yourself you should not be using this. Instead use the MDATP API (docs &lt;a href="https://docs.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-atp/create-alert-by-reference"&gt;here&lt;/a&gt;) to create the alert. This way you won't be using another spot on that 5000 entries limit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alert &amp;amp; Block&lt;/strong&gt; is used when you immediately want to block the file on all or scope of machines. Be very careful with this option. If a critical windows file ends up here it will have an impact on your organization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MIu81Q4X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/ActionIndicator.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MIu81Q4X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/ActionIndicator.png" alt="Sending your Threat Indicators to Azure Sentinel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The 3rd and last page is to set the scope of the indicator. In the screenshot below you don't see any scope since I don't have any. The scope can be set to a determined list of machines or all machines in the organization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VFO0-etO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/ScopeIndicators.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VFO0-etO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/ScopeIndicators.png" alt="Sending your Threat Indicators to Azure Sentinel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The last step is the summary to make sure you didn't make a mistake and double-check your input.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FHY_Kvyt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/Summary.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FHY_Kvyt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/Summary.png" alt="Sending your Threat Indicators to Azure Sentinel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After we completed these simple steps you will see the indicator added to the list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gRWqWmxa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/Added.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gRWqWmxa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/Added.png" alt="Sending your Threat Indicators to Azure Sentinel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Add Indicators through the Microsoft Graph Security API
&lt;/h2&gt;

&lt;p&gt;Now that we have a good understanding of what threat indicators are and how they are working, we can start adding them to Azure Sentinel. Why would we want to add them to Azure Sentinel? Azure Sentinel is a very good product to correlate security events across different log sources and different Microsoft security products.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Make sure that the &lt;strong&gt;Threat Intelligence&lt;/strong&gt; data connector in Azure Sentinel is enabled.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To add the indicators to Azure we are using the Microsoft Graph Security API (beta). Before we post a new indicator we need to set some properties first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Action: Alert, only give an alert, do not block the file.&lt;/li&gt;
&lt;li&gt;FileHashType: SHA256, in this example we only process SHA256 hashes to keep it simple&lt;/li&gt;
&lt;li&gt;FileHashValue: The actual file hash&lt;/li&gt;
&lt;li&gt;ExpirationDate: When will the indicator expire&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A basic post message would look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "action": "alert",
  "activityGroupNames": [],
  "confidence": 0,
  "description": "This is a canary indicator for demo purpose. Take no action on any observables set in this indicator.",
  "expirationDateTime": "2019-03-01T21:44:03.1668987+00:00",
  "externalId": "Test--8586509942423126760MS164-0",
  "fileHashType": "sha256",
  "fileHashValue": "b555c45c5b1b01304217e72118d6ca1b14b7013644a078273cea27bbdc1cf9d5",
  "killChain": [],
  "malwareFamilyNames": [],
  "severity": 3,
  "tags": [],
  "targetProduct": "Azure Sentinel",
  "threatType": "WatchList",
  "tlpLevel": "green",
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To keep it simple you can either post this to the Graph Security API with &lt;a href="https://www.getpostman.com/"&gt;postman&lt;/a&gt; or by using an Azure Logic App as I did. Your Logic App Http step will look similar to below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sfPIQenZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/logicapp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sfPIQenZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/logicapp.png" alt="Sending your Threat Indicators to Azure Sentinel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the logic app, you see a client id and client secret. These are from the application registration and you can have a look &lt;a href="https://dev.to/foppenma/how-to-access-data-from-the-beta-channel-of-graph-api-od5"&gt;here&lt;/a&gt; how you can set that up. Keep in mind that your application needs the permission &lt;strong&gt;ThreatIndicators.ReadWrite.OwnedBy&lt;/strong&gt; for the request to work. This permission needs to be granted by a global administrator in your tenant.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Did you notice the &lt;strong&gt;targetProduct&lt;/strong&gt; property set to &lt;strong&gt;Azure Sentinel&lt;/strong&gt;? This is what specifies where the indicator is redirected to.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After a successful post, you can view the indicator in the Azure Sentinel dashboard. This can be done by going to the ThreatIntelligenceIndicator log source&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sHuaW-Y9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/08/SentinelLogSource.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sHuaW-Y9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/08/SentinelLogSource.png" alt="Sending your Threat Indicators to Azure Sentinel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you query this you will get something similar like below, depending on how many indicators you posted.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kIzRdtfe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/08/Sentinel.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kIzRdtfe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/08/Sentinel.png" alt="Sending your Threat Indicators to Azure Sentinel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is re[mark]able how easy it is to add indicators to MDATP and Azure Sentinel, but yet so powerful. Now you can leverage the data of indicators in Azure Sentinel alerting, correlation and hunting.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>mdatp</category>
      <category>security</category>
      <category>threatintelligence</category>
      <category>graphapi</category>
    </item>
    <item>
      <title>Using Microsoft Defender ATP Streaming API with Misp</title>
      <dc:creator>Mark Foppen</dc:creator>
      <pubDate>Tue, 23 Jul 2019 15:07:21 +0000</pubDate>
      <link>https://dev.to/foppenma/using-mdatp-streaming-api-with-misp-2g0g</link>
      <guid>https://dev.to/foppenma/using-mdatp-streaming-api-with-misp-2g0g</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2Fvanveenjf-6D1WRBQUdh0-unsplash.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2Fvanveenjf-6D1WRBQUdh0-unsplash.jpg" alt="Using MDATP Streaming API with Misp"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Would it not be great if you can access all the data from the new Microsoft Defender Advanced Threat Protection (MDATP)? It would be great if you can just access all that data through an API. But I really do not want to develop another polling mechanism to pull in all the data. That is where the new MDATP Streaming API comes in which just got enabled for public preview.&lt;/p&gt;

&lt;p&gt;In this post, you will see how easy it is to configure the new Streaming API and how you can get access to the data. You will see how the new API can be attached to Azure Storage and Azure Event Hub.&lt;/p&gt;

&lt;p&gt;Once we receive all the data we can check file hashes in a 3rd party threat intelligence provider like MISP. First, let's configure the MDATP streaming API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure MDATP Streaming
&lt;/h2&gt;

&lt;p&gt;We start by going to the MDATP portal &lt;a href="https://securitycenter.windows.com" rel="noopener noreferrer"&gt;here&lt;/a&gt; where you will see the default dashboard. To start configuring you need to go to the Data Export Settings page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2FDataExportSettings.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2FDataExportSettings.gif" alt="Using MDATP Streaming API with Misp"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this page, you can add a total of 5 streaming connections. At the moment there are two types of Azure resources you can connect to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Azure Storage&lt;/li&gt;
&lt;li&gt;Event Hub&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you choose for the Azure Storage option then the MDATP stream will save all the events in a *.json file as blobs.&lt;/p&gt;

&lt;p&gt;On each connection you can choose between 9 types of events:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AlertEvents&lt;/li&gt;
&lt;li&gt;MachineInfo&lt;/li&gt;
&lt;li&gt;MachineNetworkInfo&lt;/li&gt;
&lt;li&gt;ProcessCreationEvents&lt;/li&gt;
&lt;li&gt;NetworkCommunicationEvents&lt;/li&gt;
&lt;li&gt;FileCreationEvents&lt;/li&gt;
&lt;li&gt;RegistryEvents&lt;/li&gt;
&lt;li&gt;LogonEvents&lt;/li&gt;
&lt;li&gt;ImageLoadEvents&lt;/li&gt;
&lt;li&gt;MiscEvents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For now, I am only going to focus on the connection between an Event Hub and MDATP for the &lt;strong&gt;FileCreationEvents&lt;/strong&gt;. If you want to make sure that you catch all of the files and processes on every device you should also add the &lt;strong&gt;ProcessCreationEvents&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When you add a new connection you will get all the options I just mentioned. You can make a choice here and configure the connection how you like. I am going to configure it for an event hub to only receive file creation events from MDATP.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2FAddEventHub.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2FAddEventHub.gif" alt="Using MDATP Streaming API with Misp"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that the Event hub is configured the data should start coming in and it will look something like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2FStreamingData.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2FStreamingData.png" alt="Using MDATP Streaming API with Misp"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt; : Only enable the types of events you really want to have since the volume of messages can be very high. This is not an issue for Event Hub but could be very costly if you connect it to a logic app where you pay per execution.&lt;/p&gt;

&lt;p&gt;For example 'NetworkCommunicationEvents' logs every connection made on every machine. I had to learn the hard way by wasting my entire worth of monthly Azure credits ($150) in 2 days because it was connected to a Logic app :| ...&lt;br&gt;&lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2FHighPeak.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2FHighPeak.png" alt="Using MDATP Streaming API with Misp"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see below most of the costs are in the connection and the executed actions for the logic app and not in the Event Hub. So be cautious as to what you connect to the Event Hub. The high event hub costs are due to the enabled 'Capture' feature and the standard tier. Not because of the number of events.&lt;br&gt;&lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2FCosts.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2FCosts.png" alt="Using MDATP Streaming API with Misp"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This however triggered me to look into the actual costs of using the MDATP streaming API with Event Hub. To do that we first need to know how many events are sent. I created a new Event Hub namespace, connected it to MDATP streaming API and selected all available events. The next 24h I let it run to capture all the events. To give some context to this I have counted all the different types of events and the number of machines in my tenant.&lt;/p&gt;

&lt;p&gt;NetworkCommunicationEvents: &lt;strong&gt;95,070&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
ImageLoadEvents: &lt;strong&gt;23,091&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
MiscEvents: &lt;strong&gt;57,444&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
ProcessCreationEvents: &lt;strong&gt;24,795&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
RegistryEvents: &lt;strong&gt;49,191&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
MachineInfo: &lt;strong&gt;2,213&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
MachineNetworkInfo: &lt;strong&gt;10,712&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
FileCreationEvents: &lt;strong&gt;39,487&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
LogonEvents: &lt;strong&gt;1,982&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
AlertEvents: &lt;strong&gt;4&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This leaves us with a total of &lt;strong&gt;303.989&lt;/strong&gt; events on &lt;strong&gt;83&lt;/strong&gt; different machines. The average size of one event is ~2.47 kilo byte and one machine gives ~3,662 events per day. On monthly costs, this would mean you have ~9 million events which will cost you around $0.25.&lt;/p&gt;

&lt;h2&gt;
  
  
  Consuming Eventhub with a Logic app
&lt;/h2&gt;

&lt;p&gt;Sometimes there are use cases that require a third-party threat intelligence system to check for malware. For example, to detect Android APK's with malware in them. A good example you can see &lt;a href="https://mobile.twitter.com/Maler360/status/1138695308462870528" rel="noopener noreferrer"&gt;here&lt;/a&gt;. For this example, we will be using MISP also know as a Malware Information Sharing Platform and Threat Sharing. This is a free and community-driven threat intelligence platform. In this post, we will not cover how to set this up but you can see how this can be done on Kali Linux &lt;a href="https://www.inspark.nl/misp-threat-intelligence-azure-sentinel/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is a list of goals we want to achieve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read the events from the event hub&lt;/li&gt;
&lt;li&gt;Check the file hashes against Misp&lt;/li&gt;
&lt;li&gt;Add the indicator to MDATP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do note that this is an implementation in the most basic form you can think off without any error handling or what so ever. Let's take a look at the Logic App overview&lt;br&gt;&lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2FLogicAppOverview.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2FLogicAppOverview.png" alt="Using MDATP Streaming API with Misp"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First we receive the events through the Event Hub Logic App trigger which is connected to the MDATPStream hub as shown before. When you save the Logic App with only the trigger you will get a response like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2FLogicAppEventHubMessage.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2FLogicAppEventHubMessage.png" alt="Using MDATP Streaming API with Misp"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we receive events we can call the Misp API with the following parameters to check if that file is known as a possible indicator of compromise (IoC).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2FLogicAppCallMisp-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2FLogicAppCallMisp-1.png" alt="Using MDATP Streaming API with Misp"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After this, we parse the response and check if there are any IoC's returned from Misp. If that is the case we have found a match. At this point, it is up to you what you do with this detection. The first thing you could do i.e. is, Posting an Alert directly to MDATP with the Windows Defender Advanced Threat Protection (WDATP) logic app connector.&lt;/p&gt;

&lt;p&gt;The way to achieve alerting of the found IoC is through creating an alert with the WDATP connector. You can do this by adding it to your logic app and connect it with a global admin account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2FAlertWDATP.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F07%2FAlertWDATP.png" alt="Using MDATP Streaming API with Misp"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To create an alert, you need to set the machine id which can be found in the event hub message. For the other fields, you can set them as you like. To give meaning to the alert, you should call the Misp once again and retrieve the event from Misp. An event in Misp gives context to the found IoC and therefore also contains fields like title, severity, comments, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Possibilities?
&lt;/h2&gt;

&lt;p&gt;Although this post only describes one possible implementation of the MDATP streaming API there a lot more possibilities. To name a few:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save the MDATP data to a separate storage to retain it indefinitely&lt;/li&gt;
&lt;li&gt;Instead of polling your MDATP alerts from the graph API you can now respond to the alerts real-time&lt;/li&gt;
&lt;li&gt;Monitor network communication real-time&lt;/li&gt;
&lt;li&gt;Stream your data to a 3rd party that is handling your security&lt;/li&gt;
&lt;li&gt;Stream all the evens into your Security Information and Event Management (SIEM) solution&lt;/li&gt;
&lt;li&gt;Add your data to Azure Sentinel, since there is no connector yet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And a few others, just for fun or because you can&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Draw a world map and show all the unlock and logins in real-time by processing LogonEvents&lt;/li&gt;
&lt;li&gt;Respond to people that they shouldn't work during their holidays by using the LogonEvents, ProcessCreation en FileCreationEvents ;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is re[mark]able how much data is inside the MDATP product and for now we only scratched the surface. This should give you a good indication of what is possible in real-time with the MDATP streaming API.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>threatintelligence</category>
      <category>microsoftazure</category>
      <category>security</category>
      <category>logicapps</category>
    </item>
    <item>
      <title>How to access data from the beta channel of Graph API</title>
      <dc:creator>Mark Foppen</dc:creator>
      <pubDate>Mon, 08 Jul 2019 19:59:59 +0000</pubDate>
      <link>https://dev.to/foppenma/how-to-access-data-from-the-beta-channel-of-graph-api-od5</link>
      <guid>https://dev.to/foppenma/how-to-access-data-from-the-beta-channel-of-graph-api-od5</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Va2QV8Qs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/stockvault-mesh-a-network-of-relations-between-entities202555.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Va2QV8Qs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/stockvault-mesh-a-network-of-relations-between-entities202555.jpg" alt="How to access data from the beta channel of Graph API"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All the new features of the Microsoft Graph API are first available in the beta version. By using the beta version you can get early access to new features. Microsoft often adds new features as can be seen on their GitHub changelog &lt;a href="https://github.com/microsoftgraph/microsoft-graph-docs/blob/master/concepts/changelog.md"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this post we will do three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an Azure Active Directory application registration&lt;/li&gt;
&lt;li&gt;Get the access token through the registered application&lt;/li&gt;
&lt;li&gt;Call the Graph API on the beta version&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is all done by using the Azure portal and implementing the code to call the Graph API in C#.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding an Application to your Azure Active Directory
&lt;/h2&gt;

&lt;p&gt;To get access to the Graph API we need to register an application in the Azure Active Directory (AAD). This application can be used to add permissions. An administrator of that AAD can then consent to the permissions selected by you. Let's go through this step by step.&lt;/p&gt;

&lt;p&gt;Open the Azure portal and go to the AAD that you want to add the application to. Now you can add the new application like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YYicMd1R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/AddApplication.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YYicMd1R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/AddApplication.gif" alt="How to access data from the beta channel of Graph API"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the application registration is created you can see 2 important id's we need in a later stage. This is the &lt;strong&gt;Application (client) Id&lt;/strong&gt; and the &lt;strong&gt;Directory (tenant) Id&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cBAkJcan--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/ids.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cBAkJcan--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/ids.png" alt="How to access data from the beta channel of Graph API"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next step is to add permissions to the application registration. These permissions give the application the ability to access resources. In our case, this is the Graph API. Let's add the &lt;strong&gt;Directory.Read.All&lt;/strong&gt; which gives us permission to read everything within this AAD but not change it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eXBlmh9k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/AddPermission.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eXBlmh9k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/AddPermission.gif" alt="How to access data from the beta channel of Graph API"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you might have seen there are 2 types of permissions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Delegated Permissions&lt;/strong&gt; - These permissions are used when there is a signed-in user. Typically used for portals or Azure functions that have AD authentication.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application Permissions&lt;/strong&gt; - Should only be used on background services. These permissions can only be granted by an administrator.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that the application registration has the permission we want, it is still not granted. To grant this permission on this AD we need an administrator account to give consent. This can be done on the 'API Permissions' page where we just added the new permission.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AyYzhG0e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/grant.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AyYzhG0e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/grant.png" alt="How to access data from the beta channel of Graph API"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After giving consent to the permission there is only one thing left to do and that is adding a secret to the application. This is basically the same as a password that gives you access to use the application. Only in this case, you can have multiple secrets with each a different expiry time. You can also delete these secrets. To add a secret we need to go to the "Certificates &amp;amp; secret page".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--epzfq8pS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/AddSecret.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--epzfq8pS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/AddSecret.gif" alt="How to access data from the beta channel of Graph API"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do keep in mind that you can only see the secret once. Now that we finished this we have the following data that we need to use in the next step:&lt;/p&gt;

&lt;p&gt;Tenant id: '5d1821a3-a004-4cc0-95d5-cb2e797ceaf1'&lt;br&gt;&lt;br&gt;
App Id or Client Id: '42903c50-6fc9-40db-a131-87f4522dcf56'&lt;br&gt;&lt;br&gt;
App Secret or Client Secret: 'fe_?xg+VhSxe_iq4RSw9TE4AUlddktg8'&lt;/p&gt;

&lt;p&gt;We only created an app registration for a single tenant with default settings mostly. If you want more detailed information on i.e. a multi-tenant application you can go to the Microsoft docs &lt;a href="https://docs.microsoft.com/nl-nl/azure/active-directory/develop/quickstart-register-app"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get the access token
&lt;/h2&gt;

&lt;p&gt;In order to access the Graph API, we first need to acquire an access token. This token can be used as a bearer authorization header later on. To do this I used the NuGet package &lt;strong&gt;Microsoft.Identity.Client&lt;/strong&gt; version 4.0.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private async Task&amp;lt;string&amp;gt; GetAccessToken(
    string tenantId,
    string clientId,
    string clientSecret)
{
    var builder = ConfidentialClientApplicationBuilder
        .Create(clientId)
        .WithClientSecret(clientSecret)
        .WithTenantId(tenantId)
        .WithRedirectUri("http://localhost/")
        .Build();

    var acquiredTokenResult = builder.AcquireTokenForClient(
        // Here we set the scope to https://graph.microsoft.com/.default
        new List&amp;lt;string&amp;gt; { "https://graph.microsoft.com/.default" });
    var tokenResult = await acquiredTokenResult.ExecuteAsync();
    return tokenResult.AccessToken;
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Call the Graph API
&lt;/h2&gt;

&lt;p&gt;Normally you would just use the Graph API client SDK which is the NuGet &lt;strong&gt;Microsoft.Graph&lt;/strong&gt; but even the preview versions do not have all the available calls. Therefore I am not using this NuGet. Instead by using a simple HttpClient we can achieve the same.&lt;/p&gt;

&lt;p&gt;The code below will do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retrieve the access token&lt;/li&gt;
&lt;li&gt;Set the version to beta&lt;/li&gt;
&lt;li&gt;Set the endpoint and the action we want to execute&lt;/li&gt;
&lt;li&gt;Create the HTTP client&lt;/li&gt;
&lt;li&gt;Set the headers including the authorization bearer header&lt;/li&gt;
&lt;li&gt;Sending the request which actually is an HTTP get&lt;/li&gt;
&lt;li&gt;Read the result as a string, since the response will be in JSON format&lt;/li&gt;
&lt;/ul&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private async Task CallGraphApiBetaChannel()
{
    // Retrieve the access token
    var accessToken = await GetAccessToken(
        "5d1821a3-a004-4cc0-95d5-cb2e797ceaf1",
        "42903c50-6fc9-40db-a131-87f4522dcf56",
        "fe_?xg+VhSxe_iq4RSw9TE4AUlddktg8");

    // Set the version to beta
    var graphApiVersion = "beta"; // 'beta' or 'v1.0'

    // Set the endpoint and the action we want to execute
    var endpoint = $"https://graph.microsoft.com/{graphApiVersion}";
    var action = "/applications";

    // Create the http client
    using (var client = new HttpClient())
    using (var request = new HttpRequestMessage(HttpMethod.Get, endpoint + action))
    {
        // Set the headers including the authorization bearer header
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

        // Sending the request which actually is a http get
        using (var response = await client.SendAsync(request))
        {
            if (response.IsSuccessStatusCode)
            {
                // Read the result as string, since the response will be json
                var result = await response.Content.ReadAsStringAsync();
                // Do something with the result
            }
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After you get the results you can parse the response how you like. Do keep in mind that if you generate a class model from the JSON it can be broken at any moment since they regularly push updates to the beta.&lt;/p&gt;

&lt;p&gt;If all went right you should be able to retrieve all the available applications in your Azure Active Directory. It is in my opinion re[mark]ably easy to use this and you can change the action variable to any method you can find in the beta reference docs &lt;a href="https://docs.microsoft.com/en-us/graph/api/overview?view=graph-rest-beta"&gt;here&lt;/a&gt;. Also by using this, you have control over how to parse the responses.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>gettingstarted</category>
      <category>graphapi</category>
      <category>azure</category>
    </item>
    <item>
      <title>Azure Sentinel: Taking Security To The Next Level</title>
      <dc:creator>Mark Foppen</dc:creator>
      <pubDate>Fri, 03 May 2019 08:15:00 +0000</pubDate>
      <link>https://dev.to/foppenma/azure-sentinel-taking-security-to-the-next-level-2ji7</link>
      <guid>https://dev.to/foppenma/azure-sentinel-taking-security-to-the-next-level-2ji7</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LvUgiI-1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/philipp-katzenberger-iIJrUoeRoCQ-unsplash.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LvUgiI-1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/philipp-katzenberger-iIJrUoeRoCQ-unsplash.jpg" alt="Azure Sentinel: Taking Security To The Next Level"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just before the RSA 2019 conference, Microsoft announced a new cloud-native SIEM solution called Azure Sentinel. Sentinel is meant to be the extra pair of eyes to keep your enterprise even more secure than before. Threats are more eminent than ever before since more and more companies go to the cloud. Therefore, attackers have more ways to breach your cloud environment. To counter this you can use Sentinel that enables you to ‘Collect’ data across all your users, applications and resources both on-premise and in the cloud. By using Sentinel you can ‘Detect’ threats using predefined use cases like any other SIEM or by using the build in AI. ‘Investigate’ and rapidly respond to threats manually or automatically.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yxRcodD7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/Blog-Azure-Sentinel-1-1024x723---Copy-1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yxRcodD7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/Blog-Azure-Sentinel-1-1024x723---Copy-1.jpg" alt="Azure Sentinel: Taking Security To The Next Level"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is this the next step?
&lt;/h2&gt;

&lt;p&gt;Currently, there are a lot of different security providers and products within the Microsoft cloud. Think of Azure Security Center or Windows Defender Advanced Threat protection. When one of the security solutions detect a possible malicious activity a SecOps employee has to take a look at what is happening. The employee would then determine what type of alert it is and login into the specific solution portal. For Windows Defender ATP that would look something like below, where in this case the mimikatz tool was downloaded and extracted before windows defender on the specific machine could intervene.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--biHHyVPL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/Blog-Sentinel-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--biHHyVPL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/Blog-Sentinel-2.png" alt="Azure Sentinel: Taking Security To The Next Level"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What we miss here is all the information that other security solutions could have caught on possibly the same activity. Like how did it get downloaded in the first place (patient zero)? To solve this there should be one central place to get an overview of the entire malicious activity. This is where Sentinel comes in.&lt;/p&gt;

&lt;p&gt;With Sentinel, you have a far more advanced overview (at time of writing not in public preview yet) of the activity. This would reduce the time spent on figuring out what is happening and instead is spend on solving it and making the affected customer safer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RGe5WgCy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/Blog-Sentinel-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RGe5WgCy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/Blog-Sentinel-3.png" alt="Azure Sentinel: Taking Security To The Next Level"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How can Azure Sentinel help?
&lt;/h2&gt;

&lt;p&gt;The majority of the CISO who run a SOC (Security Operation Center) to monitor their On-premise IT are hesitant to move to the cloud. In the past, there was a lack of controls to monitor the cloud IT and this sentiment has stuck with the majority of the CISO that we meet. Historically the heart of a SOC is its SIEM (Security Information and Event Management) tool. A SIEM is hard to build and takes a lot of maintenance and time from the technical and security staff. Some key issues with an on-premise SIEM are in my opinion:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hard to set up, there is a steep learning curve and a lot of different data to collect and make sense of.&lt;/li&gt;
&lt;li&gt;The need for probes, to get the bigger picture you need to install probes and agents. It takes a long time and a lot of skill to configure these properly;&lt;/li&gt;
&lt;li&gt;Often limited to on-premise IT, while IT tens to migrate to the cloud there is a lack of integration of “cloud log-data”;&lt;/li&gt;
&lt;li&gt;No machine learning, all logic must come from the SIEM vendor and the data analytics skills of the SecOps team;&lt;/li&gt;
&lt;li&gt;Slow updates, the AI of the traditional SIEM is embedded in the vendor’s software so in case of a new attack the SIEM will only learn the detection algorithm after a vendor’s update;&lt;/li&gt;
&lt;li&gt;Not easy scalable, the hard and software requirements need to be planned upfront and are not so easy to change and evolve as the business needs;&lt;/li&gt;
&lt;li&gt;Expensive to own and operate, to set up and maintain a SIEM there is a need for time and highly skilled SecOps personnel which are both had to come by.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Microsoft reimagined the SIEM tool as a new cloud-native solution called Microsoft Azure Sentinel. Some of the key features of Azure Sentinel are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;easy to collect security data&lt;/li&gt;
&lt;li&gt;hybrid IT organization&lt;/li&gt;
&lt;li&gt;devices&lt;/li&gt;
&lt;li&gt;users&lt;/li&gt;
&lt;li&gt;apps&lt;/li&gt;
&lt;li&gt;servers on any cloud&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sentinel integrates with all Microsoft (Security) alerts and logging and collaborates with many partners in the Microsoft Intelligent Security Association.&lt;/p&gt;

&lt;p&gt;Eliminating the need to spend time on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;setting up&lt;/li&gt;
&lt;li&gt;maintaining&lt;/li&gt;
&lt;li&gt;scaling infrastructure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sentinel is already integrated into the Azure portal and comes with build in connectors. All scaling and maintenance (patching) is done automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Azure Sentinel
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_TV4zV6P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/Blog-Sentinel-4-1024x550.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_TV4zV6P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/Blog-Sentinel-4-1024x550.png" alt="Azure Sentinel: Taking Security To The Next Level"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Intelligent security analytics at cloud scale and speed, as one Azure tenant gets attacked with a new attack Microsoft’s SecOps investigates and builds new AI for Sentinel and the AI of Sentinel is updated as soon as Microsoft releases it to the cloud.&lt;/li&gt;
&lt;li&gt;Identifying threats with ML, Azure Sentinel uses state of the art, scalable machine learning algorithms to correlate millions of low-level anomalies to come up with a few high-level security incidents&lt;/li&gt;
&lt;li&gt;Supported by opensource detection queries, apart from the ML and IA you can set your own triggers and alerts in Sentinel. This can be done by running custom KQL queries. Microsoft has this GitHub for you to get started and share your own.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With Azure Sentinel there are no upfront costs, you pay for what you use. This way you can have your SOC in the cloud faster with less effort and costs. Microsoft will let you connect your Office365, Azure AD, Syslog, Azure Security Center, and 3rd party data for free so when the organization moves to the cloud with Sentinel you can still rely on your SOC with SIEM, with the added bonus of the power of the cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Taking it to the next level
&lt;/h2&gt;

&lt;p&gt;In addition to everything an ‘ordinary’ SIEM is capable of, with Sentinel you can also enable “Sentinel Fusion”. Fusion is adding artificial intelligence with advanced machine learning models to your alert detection. Okay great! what does this mean and what does it do?&lt;/p&gt;

&lt;p&gt;A lot of alerts from the different Microsoft security solutions and providers confront you with low or medium severity detections. With the machine learning models from Sentinel Fusion, you can automatically detect if these ‘not so important’ detections are worth looking into it. The AI will also try to correlate events from different providers through the use of entities. These can be configured in sentinel through something that is called ‘Entity types’. For now, these entities are Account, Host or IP address. As you can see below the use cases you create in Sentinel have the ability to link any column to the appropriate entity type.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5oWa9tsp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/Blog-Sentinel-5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5oWa9tsp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/07/Blog-Sentinel-5.png" alt="Azure Sentinel: Taking Security To The Next Level"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>azuresentinel</category>
      <category>threatintelligence</category>
      <category>azure</category>
      <category>security</category>
    </item>
    <item>
      <title>Can a Azure Static Website really be this cheap?</title>
      <dc:creator>Mark Foppen</dc:creator>
      <pubDate>Sat, 09 Mar 2019 16:52:34 +0000</pubDate>
      <link>https://dev.to/foppenma/can-a-azure-static-website-really-be-this-cheap-4l7m</link>
      <guid>https://dev.to/foppenma/can-a-azure-static-website-really-be-this-cheap-4l7m</guid>
      <description>&lt;p&gt;So why should I change to Azure Static Websites? If this is a lot cheaper there are limitations right? Lets put it to the test.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is it?
&lt;/h2&gt;

&lt;p&gt;A while ago Microsoft announced the general availability of Azure Static Websites. This means that you can host your website files in a blob storage and host your website from there. You can read all about it here: &lt;a href="https://azure.microsoft.com/nl-nl/blog/static-websites-on-azure-storage-now-generally-available/" rel="noopener noreferrer"&gt;Microsoft Announcement&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What am I doing?
&lt;/h2&gt;

&lt;p&gt;For this test we need an actual website that we are able to load and produce some page views with. I got a free template from &lt;a href="https://colorlib.com/wp/template/appy/" rel="noopener noreferrer"&gt;Colorlib&lt;/a&gt; called Appy. You can browse to it by going to &lt;a href="https://azurestaticweb.z6.web.core.windows.net/" rel="noopener noreferrer"&gt;https://azurestaticweb.z6.web.core.windows.net/&lt;/a&gt; or by looking at the demo at Colorlib.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2rnxbk1pxzhd4d607x1f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2rnxbk1pxzhd4d607x1f.png" alt="page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since I didn't want to invest a lot of time into making a new website I deployed this template just "as is" into my blob storage account. This can be done by simply copying all the files into the blob folder called "$web". It should already be there since it is auto-created after enabling the static web site feature in the storage account. Next up is generating a load on the page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lets produce some page views
&lt;/h2&gt;

&lt;p&gt;In order to get a sense about the cost of the way we are hosting, we are going to produce some page views. To do this a setup a simple Selenium test that does the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start a new Firefox window with zero caching&lt;/li&gt;
&lt;li&gt;Browse to &lt;a href="https://azurestaticweb.z6.web.core.windows.net/" rel="noopener noreferrer"&gt;https://azurestaticweb.z6.web.core.windows.net/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Click on "Blog"&lt;/li&gt;
&lt;li&gt;Click on "Contact"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The other menu options will be left out since that are all single page navigation items that produce no load at all. This sequence produces three page views. What we really want to know is how many files are we getting from the blob storage since that. The Firefox network monitor reports that one page view is equal to requesting getting 54 files. Of course, this depends on how your website is built.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F03%2Fnetwork.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F03%2Fnetwork.png" alt="requests"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After this initial call, I put the selenium test in a loop and let it run for over 3 days in a row.&lt;/p&gt;

&lt;h2&gt;
  
  
  How is the performance?
&lt;/h2&gt;

&lt;p&gt;All of the above is great but how does this perform on heavier loads? Let's look at the graphs below that I got from application insights.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Number of page views over the last 3 days&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F03%2Fpageviews-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F03%2Fpageviews-1.png" alt="requests"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Number of transactions on the blob storage over the last 3 days&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F03%2Ftransactions-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F03%2Ftransactions-1.png" alt="requests"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avarage load times for the entire page (loaded all the 54 files)&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F03%2FAvg-responsetime-all-files-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F03%2FAvg-responsetime-all-files-1.png" alt="requests"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you may have noticed there is a huge spike in the beginning. This was a typo in my selenium test which caused it to produce 700 page views every minute. While most page views were under 1 second load time, with that many page views it sometimes happened that there was a spike up to 2 seconds. &lt;/p&gt;

&lt;h2&gt;
  
  
  What can we do to improve this?
&lt;/h2&gt;

&lt;p&gt;From a storage point of view, I think it is re[mark]able how well it can handle all the page views. Especially since this is data that is not cached. We have a couple of options to speed up while keeping the costs low:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redis Cache&lt;/li&gt;
&lt;li&gt;Cloudflare Cache&lt;/li&gt;
&lt;li&gt;Azure Blob Storage CDN&lt;/li&gt;
&lt;li&gt;Azure Front Door&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first two options seem nice at first but Redis cache starts at 16 dollars/month which kinda defeats the purpose of low-cost hosting. While Cloudflare is free but requires a purchased custom domain.&lt;/p&gt;

&lt;p&gt;With the third option, it is possible to replace all your files with versions in the CDN. While I think this is possible to automate it just isn't that straight forward. &lt;/p&gt;

&lt;p&gt;The last and in my opinion probably the best option is the Azure Front Door. Although it is still in preview it works really well! The pricing in the preview is 8 cents per GB. For more details, you can have a look &lt;a href="https://azure.microsoft.com/nl-nl/pricing/details/frontdoor/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. As you can see in the test results above 20k page views is about 1gb for this template website.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Azure Front Door
&lt;/h2&gt;

&lt;p&gt;First you need to create the Azure Front Door resource. While adding the resource there is a configuration step like below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F03%2Ffrontdoordesigner.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F03%2Ffrontdoordesigner.png" alt="frontdoordesigner"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are three steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frontend URLs&lt;/strong&gt;&lt;br&gt;
This is the URL your users are browsing to. There is an option to use a custom domain here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backend pools&lt;/strong&gt;&lt;br&gt;
In the backend pools, you can specify the resources where a frontend URL is pointing to. You can add multiple resources in a pool. The load balancer will switch between them. This makes it possible to create multiple storage accounts in different geo regions and the Front Door load balancer will automatically route you to the nearest resource to reduce loading time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F03%2Fbackends.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F03%2Fbackends.png" alt="backends"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Routing rules&lt;/strong&gt;&lt;br&gt;
Routing rules are the glue between the frontend URL and the backend pool. The routing rules include lots of settings and one of them is caching. This will reduce the load on your blob storage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F03%2Froutingrule.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F03%2Froutingrule.png" alt="routingrule"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After you did these steps your static website will be available within a few minutes on the new *.azurefd.net domain. For me this was &lt;a href="https://azurestaticweb.azurefd.net/" rel="noopener noreferrer"&gt;https://azurestaticweb.azurefd.net/&lt;/a&gt;. Keep in mind that the Azure Static Website is already pretty fast and that Azure Front Door is just an option to either reduce the load time or to scale your application. For now, let's continue on the Azure Static Website feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the limitations?
&lt;/h2&gt;

&lt;p&gt;There is no server running your code so it is &lt;strong&gt;not&lt;/strong&gt; possible to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install something like Node.js&lt;/li&gt;
&lt;li&gt;Deploy your ASP.net web app&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What &lt;strong&gt;is&lt;/strong&gt; possible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using Html, CSS and Javascript&lt;/li&gt;
&lt;li&gt;Use ReactJs or Angular&lt;/li&gt;
&lt;li&gt;Use WebAssembly&lt;/li&gt;
&lt;li&gt;Using Azure Functions as your server-side / backend&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Finally, What does this 20k page views, 1gig transferred and almost 2 million transactions cost?
&lt;/h2&gt;

&lt;p&gt;Well since it is really only the blob storage costs you will see something like this. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F03%2Fcost.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2019%2F03%2Fcost.png" alt="costs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that the Application insights is "really expensive" in comparison to the Azure Static Web host. But in all fairness, 3 cents (3.12 cents if dollars) is very cheap! This hosting solution is very cheap while still offering a lot of possibilities. As such you can use Azure Functions as your backend e.g. to connect to a database.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>azure</category>
      <category>azurefrontdoor</category>
      <category>azureblobstorage</category>
      <category>azurestaticwebsite</category>
    </item>
    <item>
      <title>Sending Telegram Messages With Azure Function Proxy and Logic App Custom Connector</title>
      <dc:creator>Mark Foppen</dc:creator>
      <pubDate>Sat, 02 Mar 2019 13:53:23 +0000</pubDate>
      <link>https://dev.to/foppenma/sending-telegram-messages-with-azure-function-proxy-and-logic-app-custom-connector-38o2</link>
      <guid>https://dev.to/foppenma/sending-telegram-messages-with-azure-function-proxy-and-logic-app-custom-connector-38o2</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O_1CGEuz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/03/logic-app-icon-5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O_1CGEuz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/03/logic-app-icon-5.png" alt="Sending Telegram Messages With Azure Function Proxy and Logic App Custom Connector"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The other day I was experimenting with new Geofencing feature in Azure Maps. What I was trying to achieve is sending a message to my telegram when I leave my home area. How hard can it be right?&lt;/p&gt;

&lt;p&gt;Then I discovered that there is no Logic App connector for Telegram and that their Bot API URL format isn't as straight forward as I would like. This explains why there isn't a connector yet. To solve this I used a Logic App connector to call an Azure Function Proxy. The proxy transforms the call to something the Telegram API would understand. This allowed me to make the connection once and easily send a message from multiple logic apps in that same Azure subscription. And above all, this is a 'no code' solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;For this to work, there is a prerequisite to registering a bot with Telegram. This is a simple process which is already explained by Microsoft. Register your bot by using this guide &lt;a href="https://docs.microsoft.com/en-us/azure/bot-service/bot-service-channel-connect-telegram?view=azure-bot-service-4.0"&gt;https://docs.microsoft.com/en-us/azure/bot-service/bot-service-channel-connect-telegram?view=azure-bot-service-4.0&lt;/a&gt; or have a bot key ready from a previously registered bot.&lt;/p&gt;

&lt;p&gt;Next to the bot registration we also need to retrieve the chat id. This can be done by starting a chat with @get_id_bot. Say anything and it will return your chat id. The @get_id_bot can also be added to groups to retrieve the group id.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sending a message with Telegram Bot API
&lt;/h2&gt;

&lt;p&gt;After retrieving the bot key and the chat id we should be able to send a message with the bot. This can be done by using the following url and replace the placeholders:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://api.telegram.org/bot&amp;lt;botKey_here&amp;gt;/sendMessage?text=&amp;lt;text_here&amp;gt;&amp;amp;chat_id=&amp;lt;id_here&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;An example would be:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://api.telegram.org/bot628752025:AAFjS9MR3MubX-RWpxqltVtR5Wju9EoUAAo/sendMessage?text=Hello World&amp;amp;chat_id=123456789
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice that there is a prefix "bot" in the URL we are calling. This is precisely why only a Logic App connector would not be sufficient. A Logic App Connector does not allow to use the API key from the Authentication Type "API Key" in the path. Only 'Header' and 'Query' are supported at this time. What we can do is make use of an Azure Function Proxy to rewrite the URL from only query string parameters to a valid Telegram Bot API URL. You can test the URL by just pasting it in your browser and you will get your first message from the Telegram Bot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Azure Function Proxy
&lt;/h2&gt;

&lt;p&gt;To be able to change the URL we need to add a new Azure Function App. I used the consumption plan for this but dedicated plan works as well. I created a function app like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--62bTe2gk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/03/CreateFunctionProxy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--62bTe2gk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/03/CreateFunctionProxy.png" alt="Sending Telegram Messages With Azure Function Proxy and Logic App Custom Connector"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the creation of the function app go to the advanced editor and use the JSON below:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "$schema": "http://json.schemastore.org/proxies",
    "proxies": {
        "telegramtrigger": {
            "matchCondition": {
                "route": "/{operation}",
                "methods": [
                    "GET"
                ]
            },
            "backendUri": "https://api.telegram.org/bot{request.querystring.apikey}/{operation}"
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;"route": "/{operation}" makes this proxy trigger on every call to the base URL that can be found in the proxy overview. The 'backendUri' is the new URL that this proxy will call.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_7bF7iJ9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/03/TelegramProxy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_7bF7iJ9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/03/TelegramProxy.png" alt="Sending Telegram Messages With Azure Function Proxy and Logic App Custom Connector"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The URL is then changed by adding the bot key in there. The {operation} at the end literally just copies everything that is behind your base URL and paste it in the new 'backendUri'.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logic App Custom Connector
&lt;/h2&gt;

&lt;p&gt;Next on the list is implementing the Logic App Custom Connector. You can download the custom connector template from &lt;a href="https://github.com/foppenm/TelegramLogicAppConnector"&gt;https://github.com/foppenm/TelegramLogicAppConnector&lt;/a&gt;. Open de JSON file in an editor like VS code and change to following to match your proxy URL:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d2Mc5Q1d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/03/ChangeJson.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d2Mc5Q1d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/03/ChangeJson.png" alt="Sending Telegram Messages With Azure Function Proxy and Logic App Custom Connector"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's create a Logic App Custom Connector and press edit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v32i3-Ha--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/03/EditConnector.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v32i3-Ha--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/03/EditConnector.png" alt="Sending Telegram Messages With Azure Function Proxy and Logic App Custom Connector"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After importing the changed JSON from the previous step you only have to press "Update Connector" and you can start using it in your logic apps. Optionally you can pick a color and choose an icon to use for this. This determines how it is presented in the logic apps designer.&lt;/p&gt;

&lt;p&gt;Now I am able to send a message to my Telegram when an area change is detected within Azure Maps Geofencing. To achieve this, first add the custom Telegram connector to your Logic App and use your bot key.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U4bYgvFS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/03/TelegramConnection.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U4bYgvFS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/03/TelegramConnection.png" alt="Sending Telegram Messages With Azure Function Proxy and Logic App Custom Connector"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then use the event grid trigger together with the 'Send Message' step from the custom connector to send messages on area updates from Azure Maps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OvDtVjjN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/03/EventGridTelegram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OvDtVjjN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.re-mark-able.net/content/images/2019/03/EventGridTelegram.png" alt="Sending Telegram Messages With Azure Function Proxy and Logic App Custom Connector"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Was this the best use of a custom connector and a function proxy? Probably not but it sure was fun to figure out what it can do and that it can be quite powerful in some scenarios. What I find re[mark]able is the fact that this is a no code solution. Of course you could just use an azure function with the telegram .net library but for this scenario for just sending simple messages is, in my opinion, a total overkill.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>logicapp</category>
      <category>functions</category>
      <category>serverless</category>
    </item>
    <item>
      <title>How to develop more secure solutions without the hassle</title>
      <dc:creator>Mark Foppen</dc:creator>
      <pubDate>Fri, 04 Jan 2019 10:04:11 +0000</pubDate>
      <link>https://dev.to/foppenma/how-to-develop-more-secure-solutions-without-the-hassle-297h</link>
      <guid>https://dev.to/foppenma/how-to-develop-more-secure-solutions-without-the-hassle-297h</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rOb00RGf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/blog-logo-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rOb00RGf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/blog-logo-1.png" alt="How to develop more secure solutions without the hassle" width="800" height="645"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As developers, we are constantly trying to implement our solutions in the best way possible. Often we "forget" to look for the vulnerabilities we introduce without really thinking about it. This can happen under pressure of a superior or simply because you can't know every vulnerability out there.&lt;/p&gt;

&lt;p&gt;In order to improve this we want to know what is wrong but (I personally) don't want it to be enforced on every local build we do.. For this to improve I found 2 solutions that work really well without you being bothered all the time.&lt;/p&gt;

&lt;p&gt;There are 2 different kinds of solutions we can use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Live information and tips during your development&lt;/li&gt;
&lt;li&gt;Vulnerabilities on added dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Security Code Scan
&lt;/h2&gt;

&lt;p&gt;For the first problem, I wanted to be notified during my development in visual studio en visual studio code. This can be done by installing one of the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visual Studio -&amp;gt; SecurityCodeScan ( &lt;strong&gt;preferred!&lt;/strong&gt; ) and/or DevSkim&lt;/li&gt;
&lt;li&gt;Visual Studio Code -&amp;gt; DevSkim&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this post, we will mainly be looking into Security Code Scan. In order to use this, you can get it either by installing the visual studio extension &lt;a href="https://marketplace.visualstudio.com/items?itemName=JaroslavLobacevski.SecurityCodeScan"&gt;Link&lt;/a&gt; or by adding it as a nuget on the project you want to monitor. I have added it as an extension and therefore will get vulnerability warnings on every solution that is open.&lt;/p&gt;

&lt;p&gt;After installing, make sure to check the "Enable full solution analysis" in Visual Studio &amp;gt; Tools &amp;gt; Text Editor &amp;gt; C# &amp;gt; Advanced, like in the screenshot below.&lt;br&gt;&lt;br&gt;
 &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DcMb_QYX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/vs-tools-setting.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DcMb_QYX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/vs-tools-setting.png" alt="How to develop more secure solutions without the hassle" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By now you will get warnings if something is detected. It can present itself in different ways.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--onFGcfT_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/warning.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--onFGcfT_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/warning.png" alt="How to develop more secure solutions without the hassle" width="800" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will also be able to fix it most of the time with the quickfix option.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ix58UNe8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/quickfix.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ix58UNe8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/quickfix.png" alt="How to develop more secure solutions without the hassle" width="800" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last but not least, you can also get an overview of all the warnings in the "Error list" view.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BclTWlrK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/error-list.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BclTWlrK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/error-list.png" alt="How to develop more secure solutions without the hassle" width="800" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this view, you also have the ability to open the issue in your browser to get additional information, how to fix it and why this is important. I mean you can always ignore it if you think this is not applicable in the current situation.&lt;/p&gt;

&lt;p&gt;Solutions for vulnerabilities can be found at &lt;a href="https://security-code-scan.github.io"&gt;Security Code Scan&lt;/a&gt; and it wil look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BAAaQ0Jo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/solution-for-issue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BAAaQ0Jo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/solution-for-issue.png" alt="How to develop more secure solutions without the hassle" width="800" height="834"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a second solution, you can also use DevSkim which can be found &lt;a href="https://github.com/Microsoft/DevSkim"&gt;here&lt;/a&gt; but in my opinion, this is less useful and it will produce errors on build time. DevSkim does catch some different possible issues like not secure URLs. Unfortunately, it does not support quick fixes or an explanation of why it is a vulnerability.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l_mBUb9L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/unsecure-url.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l_mBUb9L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/unsecure-url.png" alt="How to develop more secure solutions without the hassle" width="800" height="186"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Snyk
&lt;/h2&gt;

&lt;p&gt;After I implemented a solution, it works and I am ready to deploy it there is a possibility to check it for used dependencies vulnerabilities. This can be done by using &lt;a href="https://snyk.io/"&gt;Snyk&lt;/a&gt; which has a free tier for developers and unlimited tests (runs to check your solution) for public repositories. Keep in mind that for enterprises there are paid options.&lt;/p&gt;

&lt;p&gt;First, you need to register a free account. This will give you access to your Dashboard. Now you have two options. You can configure a public repository or use a local (on your machine) project. The public repositories can be configured by going to the "Integrations" page where you can configure a lot of providers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qvgbxRVI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/snyk-integrations.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qvgbxRVI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/snyk-integrations.png" alt="How to develop more secure solutions without the hassle" width="800" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example we are going to use a local project that is not in any repository since the local project is a little more difficult to setup.&lt;/p&gt;

&lt;p&gt;So let's get right to it and install Snyk on your machine. To install Snyk I used npm with the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g snyk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that you have to authenticate with your account.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;snyk auth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which will open the browser and you can login in with your Snyk account. Now you can use it to test your solution by going to project folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd c:\&amp;lt;your solution folder&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case, this was a solution with .NET project for an azure function. This is supported but not in the default way. Normally you can just run "sync test" and it will automatically check for a lot of different variations of package files in your current folder (see &lt;a href="https://snyk.io/docs/using-snyk/"&gt;docs&lt;/a&gt;). For .NET projects you need to specify the solution file like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;snyk test --file=MySolution.sln
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the summary of your test, you can already see if there are vulnerabilities&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h7Bygpl6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/snyk-test.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h7Bygpl6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/snyk-test.png" alt="How to develop more secure solutions without the hassle" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To get it in your dashboard on snyk.io you need to run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;snyk monitor --file=MySolution.sln
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will send the data to your Snyk account and you will be able to see it in the dashboard and browse through the found vulnerabilities by severity.&lt;/p&gt;

&lt;p&gt;A nice added bonus to this monitoring is that it will keep your packages config and alert you when there are newly found vulnerabilities. This way you will get an email when this happened and you can respond to that. This can be set to check on a daily or weekly base.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--en5MBw7z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/snyk-dashboard.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--en5MBw7z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.re-mark-able.net/content/images/2019/01/snyk-dashboard.png" alt="How to develop more secure solutions without the hassle" width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Is This Usable?
&lt;/h2&gt;

&lt;p&gt;I can only speak for my self but for me, these two steps are easy to implement in local and ci builds and require no hassle to use. An added bonus is that I can use the warnings to improve the solution but I don't have to. If you want it to take a step further you can always take a look into &lt;a href="https://github.com/Microsoft/BinSkim"&gt;BinSkim&lt;/a&gt;. This tool can analyze your DLL's and Executables for know vulnerabilities.&lt;/p&gt;

&lt;p&gt;All in all, I think it is really "remarkable" that all this is free to use while it can have real added value to the solutions we make!&lt;/p&gt;

</description>
      <category>security</category>
      <category>developer</category>
    </item>
    <item>
      <title>Securing Logic App Http triggers</title>
      <dc:creator>Mark Foppen</dc:creator>
      <pubDate>Fri, 14 Dec 2018 14:17:46 +0000</pubDate>
      <link>https://dev.to/foppenma/securing-logic-app-http-triggers-553d</link>
      <guid>https://dev.to/foppenma/securing-logic-app-http-triggers-553d</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2018%2F12%2Flogicapplogo-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2018%2F12%2Flogicapplogo-2.png" alt="Securing Logic App Http triggers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For all developers that are using logic app http triggers, here is a brief solution of how we can secure logic apps a little more.&lt;/p&gt;

&lt;p&gt;This is a solution without Azure Api Management or making use of proxies to hide the signature from the url and posting it as a header.&lt;/p&gt;

&lt;p&gt;In my case I had a scheduled function app that did some data processing and posted the result to a logic app. For this example we will create a downsized/stripped solution of this. To achieve this we need to create the following things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A logic app&lt;/li&gt;
&lt;li&gt;App registration&lt;/li&gt;
&lt;li&gt;A scheduled function app&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's dive right in and create a simple logic app that only has a http trigger.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2018%2F12%2Flogicapp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2018%2F12%2Flogicapp.png" alt="Securing Logic App Http triggers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After saving the logic app an url will be created and it will look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://prod-41.westeurope.logic.azure.com:443/workflows/1dd2822de5034e543088be263d4dd412/triggers/manual/paths/invoke?api-version=2016-10-01&amp;amp;sp=%2Ftriggers%2Fmanual%2Frun&amp;amp;sv=1.0&amp;amp;sig=0qwAP5sOqZ6aA4As8eGjZipRiLRYOTuwnHuaMjwEMGb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't worry, this http trigger isn't live anymore.&lt;/p&gt;

&lt;p&gt;Now anyone with this url can trigger the logic app. Therefore it would be wise not to share this or store it.. Wait what? How are you supposed to call it then? We can retrieve the url from the logic app resource. But in order to do that we need to create a app registration first.&lt;/p&gt;

&lt;h3&gt;
  
  
  App registration
&lt;/h3&gt;

&lt;p&gt;In order to solve this problem we need to create an app registration on the Active Directory (AD) and subscription where your logic app is created. This can be done by going to &lt;a href="http://aka.ms/registeredappsprod" rel="noopener noreferrer"&gt;http://aka.ms/registeredappsprod&lt;/a&gt; or by navigating to &lt;a href="https://portal.azure.com" rel="noopener noreferrer"&gt;https://portal.azure.com&lt;/a&gt; &amp;gt; Azure Active Directory &amp;gt; App registration. Just create a new one with no permissions. Also the redirect url can be left empty. Before we can use it, we need to generate a new client secret.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2018%2F12%2Fnewsecret-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2018%2F12%2Fnewsecret-1.png" alt="Securing Logic App Http triggers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also add this app with "Reader" role to the same subscription as your logic app. You can do this by going to 'Access Control' of your subscription and adding a new role assignment&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2018%2F12%2Faccesscontrol.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2018%2F12%2Faccesscontrol.png" alt="Securing Logic App Http triggers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a scheduled function app
&lt;/h3&gt;

&lt;p&gt;To make use of the just created app registration we can create a scheduled function app that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[FunctionName("Scheduled_ProcessData")]
public static async Task Run([TimerTrigger("0 */1 * * * *")]TimerInfo myTimer, ILogger log)
{
    // Do something here
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this example we used a function app but since access to the logic app resource is just a REST call you can access it from any solution that is able to do REST calls.&lt;/p&gt;

&lt;h3&gt;
  
  
  Secure it a little
&lt;/h3&gt;

&lt;p&gt;Now we got the basic plumbing done What we can do now is, instead of retrieving the url from a config or from a keyvault, retrieve the url from the logic app (resource)!&lt;/p&gt;

&lt;p&gt;In the code below we will do the following things in order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setup all the values need to execute the calls&lt;/li&gt;
&lt;li&gt;Construct the url from where we can retrieve the logic app url&lt;/li&gt;
&lt;li&gt;Retrieve the logic app url (which is not the same url you see in when editing the app)&lt;/li&gt;
&lt;li&gt;Post a message to this new url&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this code to work you need to add the nuget for "Microsoft.Azure.Management.ResourceManager.Fluent;" and insert the using for it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Setup 
var tenantId = "6a76fe50-e9d9-477f-9831-e43347c8f9d4";
var clientId = "a66fcb38-c768-4afc-ab79-d544d2e147d0";
var secret = "your app password/secret here";
var subscriptionId = "554395c0-759d-4299-9134-554e608f7f68";
var resourceGroupName = "Your Azure Resource Group here";
var logicAppName = "Your Logic app name here";

// Setup resource client
var creds = new AzureCredentialsFactory().FromServicePrincipal(clientId, secret, tenantId, AzureEnvironment.AzureGlobalCloud);
var restClient = RestClient.Configure()
    .WithEnvironment(AzureEnvironment.AzureGlobalCloud)
    .WithBaseUri("https://management.azure.com/")
    .WithCredentials(creds)
    .Build();

// Construct meesage
var url = $"https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Logic/workflows/{logicAppName}/triggers/manual/listCallbackUrl?api-version=2016-06-01";
var message = new HttpRequestMessage(HttpMethod.Post, url);

// Add authentication headers on message
await restClient.Credentials.ProcessHttpRequestAsync(message, new System.Threading.CancellationToken(false));

// Retrieve logic app url
var httpClient = new HttpClient();
var httpResponse = await httpClient.SendAsync(message);
var apiResponse = await httpResponse.Content.ReadAsStringAsync();

// Send Message to logic app
var authenticatedUrl = (string)JsonConvert.DeserializeObject&amp;lt;dynamic&amp;gt;(apiResponse).value;
await httpClient.PostAsync(authenticatedUrl, new StringContent("Message to logic app"));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me first state that the hardcoded values in the setup is a real 'no go'. If you want to use this example please get them from a KeyVault. This can be done by adding the Managed Identity in the Access Policies of the KeyVault and using the KeyVault SDK. For simplicity I kept hardcoded values. A more detailed explanation can be found &lt;a href="http://www.re-mark-able.net/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For now I just send an StringContent to the logic app but of course, you can send anything that the logic app is able to receive. Now run the function and wait for it to trigger a run. When the function has been executed you can see we successfully posted a message to the logic app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2018%2F12%2FpostedToLogicApp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2018%2F12%2FpostedToLogicApp.png" alt="Securing Logic App Http triggers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The url will stay valid until the primary access key of the logic app is regenerated.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Secure it even a little further
&lt;/h3&gt;

&lt;p&gt;Even though the url's to call the logic app are retrieved on runtime and not saved, the static url is still available. I must admit that the chance of that url leaking somewhere or being brute-forced is very small. To limit this even more is regenerating it every x minutes/hours/days. We can do this by basically calling the same code but with a different url and we need to add some content to the post.&lt;/p&gt;

&lt;p&gt;Change the url to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Logic/workflows/{logicAppName}/regenerateAccessKey?api-version=2016-06-01
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And add this 1 row of code to add content to the message you post:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;message.Content = new StringContent(JsonConvert.SerializeObject(new { keyType = "Primary" }), Encoding.UTF8, "application/json");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The 'keyType' property can be set to "Primary" or "Secondary" which will then regenerate the specified key. This is the same functionality as in the azure portal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2018%2F12%2Fazureportalaccesskeys.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2018%2F12%2Fazureportalaccesskeys.png" alt="Securing Logic App Http triggers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A nice added feature is that when changing the primary key all the retrieved logic app urls will be invalid after 10 minutes or so.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When changing the access key, keep in mind that you probably need to refresh the azure portal and wait a few minutes. It occurred a several times that, when opening the logic app runs without the portal refresh, an error was show about not being authorized to view the content like below:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2018%2F12%2Funauthorized.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.re-mark-able.net%2Fcontent%2Fimages%2F2018%2F12%2Funauthorized.png" alt="Securing Logic App Http triggers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, that is it! Now you have a solution with rolling keys for logic apps and a way to access your logic apps without configuring a URL. Of course, you have to be realistic and wonder what the change is that someone guesses/brute-force an URL and signature.. that would be kinda "remarkable". But if you are the person that wants all the extra security possible then this is maybe for you :)&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>logicapp</category>
      <category>security</category>
      <category>functions</category>
      <category>serverless</category>
    </item>
  </channel>
</rss>
