<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>2019-03 on Funky Si's Blog (Dev)</title><link>https://blog-dev.funkysi1701.com/2019/03/</link><description>Recent content in 2019-03 on Funky Si's Blog (Dev)</description><generator>Hugo -- gohugo.io</generator><language>en-gb</language><managingEditor>funkysi1701@gmail.com (Simon Foster)</managingEditor><webMaster>funkysi1701@gmail.com (Simon Foster)</webMaster><lastBuildDate>Wed, 27 Mar 2019 20:00:45 +0000</lastBuildDate><atom:link href="https://blog-dev.funkysi1701.com/2019/03/index.xml" rel="self" type="application/rss+xml"/><item><title>Documenting your API</title><link>https://blog-dev.funkysi1701.com/posts/2019/documenting-your-api/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Wed, 27 Mar 2019 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2019/documenting-your-api/</guid><category term="Swagger">Swagger</category><category term="API">API</category><media:content medium="image" type="image/png" url="https://blog-dev.funkysi1701.com/images/2019/03/image-3.png"/><description>&lt;p&gt;So you have created a super API that does something amazing. How do you document it so people will use it?&lt;/p&gt;
&lt;p&gt;One way of easily documenting your API is to install the Swashbuckle package.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Install-Package Swashbuckle.AspNetCore
Install-Package Swashbuckle.AspNetCore.Swagger
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then in you startup.cs add the following lines&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//In ConfigureServices&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;services.AddSwaggerGen(c =&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; c.SwaggerDoc(&lt;span style="color:#e6db74"&gt;&amp;#34;v1&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Info { Title = &lt;span style="color:#e6db74"&gt;&amp;#34;API&amp;#34;&lt;/span&gt;, Version = &lt;span style="color:#e6db74"&gt;&amp;#34;v1&amp;#34;&lt;/span&gt;, Description = &lt;span style="color:#e6db74"&gt;&amp;#34;An API Description&amp;#34;&lt;/span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; c.IncludeXmlComments(&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#e6db74"&gt;@&amp;#34;{0}\API.xml&amp;#34;&lt;/span&gt;, System.AppDomain.CurrentDomain.BaseDirectory));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//In Configure&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;app.UseSwagger();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;app.UseSwaggerUI(c =&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; c.SwaggerEndpoint(&lt;span style="color:#e6db74"&gt;&amp;#34;/swagger/v1/swagger.json&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;API V1&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; c.RoutePrefix = &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;.Empty;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now when you browse to your API you will see the swagger documentation system.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Image" src="https://blog-dev.funkysi1701.com/images/2019/03/image-3.png" loading="lazy"
width="883" height="602"
/&gt;
&lt;/p&gt;
&lt;p&gt;The RoutePrefix setting controls the path in which swagger will display. I have my docs at the root, but you might want them under the /docs or similar path.&lt;/p&gt;
&lt;p&gt;The IncludeXmlComments setting from the ConfigureServices method allows you to load in any XML comments you have added to methods. For this to work you need to enable a setting to your build.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Image" src="https://blog-dev.funkysi1701.com/images/2019/03/image-4.png" loading="lazy"
width="997" height="822"
/&gt;
&lt;/p&gt;
&lt;p&gt;The XML documentation file must be ticked and contain a path. Everytime you do a build, a XML file will be generated which contains all the comment blocks you have added to your code.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Image" src="https://blog-dev.funkysi1701.com/images/2019/03/image-5.png" loading="lazy"
width="610" height="184"
/&gt;
&lt;/p&gt;
&lt;p&gt;Swagger will then use this XML documentation file to produce lovely looking documentation without you having to do anything extra.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Image" src="https://blog-dev.funkysi1701.com/images/2019/03/image-6.png" loading="lazy"
width="1796" height="705"
/&gt;
&lt;/p&gt;</description></item><item><title>Azure Key Vault</title><link>https://blog-dev.funkysi1701.com/posts/2019/azure-key-vault/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Tue, 19 Mar 2019 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2019/azure-key-vault/</guid><category term="Website">Website</category><category term="Security">Security</category><category term="Azure">Azure</category><description>&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-gb/azure/key-vault/" target="_blank" rel="noopener noreferrer"&gt;Azure Key Vault&lt;/a&gt;
is a secure way of storing your keys, certificates and secrets so your application can access everything it needs to but you don’t have them being stored insecurely anywhere such as in source control.&lt;/p&gt;
&lt;p&gt;I have been wanting to give Azure Key Vault a try for a while now as it can make use of Azure Active Directory to give your web app an identity so it can authenticate itself into the key vault to access secrets. Pretty clever but with a lot of moving parts a bit complex.&lt;/p&gt;
&lt;p&gt;For my example I am just going to connect to my Key Vault and get a secret and display it somewhere on a web page. This is of course not what you want to do as secrets are secret and shouldn’t be displayed just used to authenticate into whatever, however it is an easy way to prove I am connecting to the Key Vault and everything is working.&lt;/p&gt;
&lt;p&gt;Lets look at some code. I have a .net core application and to start with lets install three nuget packages.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Microsoft.Azure.KeyVault
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Microsoft.Azure.Services.AppAuthentication
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Microsoft.Extensions.Configuration.AzureKeyVault
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I’ve not include version numbers as these will no doubt get updated over time but hopefully it will still work.&lt;/p&gt;
&lt;p&gt;Now in your Program.cs add the following code, replacing [KeyVaultName] with the name of your Key Vault.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Program&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; Main(&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;[] args)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; CreateWebHostBuilder(args).Build().Run();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; IWebHostBuilder CreateWebHostBuilder(&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;[] args) =&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; WebHost.CreateDefaultBuilder(args)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .ConfigureAppConfiguration((context, config) =&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; builtConfig = config.Build();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; azureServiceTokenProvider = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; AzureServiceTokenProvider();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; keyVaultClient = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; KeyVaultClient(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; KeyVaultClient.AuthenticationCallback(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; azureServiceTokenProvider.KeyVaultTokenCallback));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; config.AddAzureKeyVault(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;$&amp;#34;https://[KeyVaultName].vault.azure.net/&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; keyVaultClient,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; DefaultKeyVaultSecretManager());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .UseApplicationInsights()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .UseStartup&amp;lt;Startup&amp;gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now all you need to do is look at your configuration to pull out secrets from your Azure Key Vault. If you have a secret called AppSecret then you can use the following code snippet to retrieve its value, assuming _configuration is an implementation of Microsoft.Extensions.Configuration.IConfiguration.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;_configuration[&amp;#34;AppSecret&amp;#34;];
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now if you do all of this and run from an Azure Web App or run locally it will fail to pull anything from the Key Vault. You need to give your web app an identity and configure your key vault to allow access from that identity.&lt;/p&gt;
&lt;p&gt;Once my code has been deployed to an Azure Web App I get the following error.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Image" src="https://blog-dev.funkysi1701.com/images/2019/image.png" loading="lazy"
width="1102" height="486"
/&gt;
&lt;/p&gt;
&lt;p&gt;Lets look at fixing that, first lets give my web app an Identity. Open up the Azure portal and find the identity section of your web app and turn the setting on.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Image" src="https://blog-dev.funkysi1701.com/images/2019/image-1.png" loading="lazy"
width="1218" height="728"
/&gt;
&lt;/p&gt;
&lt;p&gt;Now you need to grant that identity permission to your key vault. In the portal open up Access Policies in your key vault and click add Policy, select the identity of your web app in the principal box and select the following settings to grant access to your secret.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Image" src="https://blog-dev.funkysi1701.com/images/2019/image-2.png" loading="lazy"
width="411" height="855"
/&gt;
&lt;/p&gt;
&lt;p&gt;Now you have a website that can pull secrets out of Key Vault but only that unique identity. Anyone who has access to your source code will not have access to your secrets, even if they push your code to a different Azure Web App.&lt;/p&gt;</description></item><item><title>Tech I want to learn more about</title><link>https://blog-dev.funkysi1701.com/posts/2019/technology-i-want-to-learn-more-about/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Tue, 05 Mar 2019 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2019/technology-i-want-to-learn-more-about/</guid><category term="C-Sharp">C-Sharp</category><category term="Azure">Azure</category><category term="Security">Security</category><description>&lt;p&gt;While at &lt;a href="https://www.funkysi1701.com/posts/2019/microsoft-ignite-the-tour-london" target="_blank" rel="noopener noreferrer"&gt;Microsoft Ignite&lt;/a&gt;
I heard about a lot of cool tech that I want to know more about. The best way to learn something is use it to solve a problem.&lt;/p&gt;
&lt;p&gt;So what can I build that is both useful and will let me play with some new tech?&lt;/p&gt;
&lt;p&gt;I have a Xamarin Forms app Pwned Pass that has over 500 downloads on Google Play and over 80 downloads on the Microsoft Store. This has given me a small user base that I can use to make use of whatever I build.&lt;/p&gt;
&lt;p&gt;My app makes use of the &lt;a href="https://haveibeenpwned.com/API/v3" target="_blank" rel="noopener noreferrer"&gt;HIBP API&lt;/a&gt;
created by Troy Hunt. I am going to build my own API, initially it will just make calls to the HIBP API. Building this will give me experience of building something with .net Core from design to deployment. I have made a start already on doing this, I have an empty .net core API project which deploys to an Azure web app using the build and release pipelines from Azure DevOps.&lt;/p&gt;
&lt;p&gt;You may be wondering why I am not making use of Azure Functions to build this API. Azure functions is certainly a great technology that is worth learning about. However I have done a little bit with them in the past and I don’t believe I would be able to learn all the things I want to if I used Azure Functions. My primary goal is learning and sharing that learning via this blog. It may well be I move to using Azure Functions later on.&lt;/p&gt;
&lt;p&gt;Another tech I am keen to learn more about is &lt;a href="https://learn.microsoft.com/en-gb/azure/key-vault/" target="_blank" rel="noopener noreferrer"&gt;Azure Key Vault&lt;/a&gt;
. This is a technology that allows the securing of keys, connection strings and certificates. I want my app to securely get keys and security information without any of it having to be committed to source code or shared insecurely.&lt;/p&gt;
&lt;p&gt;Monitoring my app is also a key learning from me. I use application insights already, but I would like to extend my understanding of this so telemetry can be fed back into the build and bad deployments stopped.&lt;/p&gt;
&lt;p&gt;Below is my complete list of learning and tech I want to touch on. It is a long list and I imagine it will get longer as I work through it. I want to regularly blog and share what I have been working on. I currently have a working build and release pipeline but nothing of note to build or release. I know Key Vault needs looking at early as the identity of the website in Azure is key to getting that tech working correctly.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Build API with .net core&lt;/li&gt;
&lt;li&gt;Add build and release pipeline&lt;/li&gt;
&lt;li&gt;Make use of Azure KeyVault for secrets, connection strings etc&lt;/li&gt;
&lt;li&gt;Plugin My Xamarin app to make use of it&lt;/li&gt;
&lt;li&gt;Monitor my API with Application Insights&lt;/li&gt;
&lt;li&gt;Secure it with CSPs and log this into &lt;a href="https://report-uri.com/" target="_blank" rel="noopener noreferrer"&gt;Report URI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Consider building a web frontend to my API using a javascript library or framework. Maybe react but this can be decided later.&lt;/li&gt;
&lt;li&gt;Dockerize the API and add the creation of docker images to the build/release pipeline&lt;/li&gt;
&lt;/ol&gt;</description></item></channel></rss>