Advertise with Googlier.com  Steve Spencer's Blog - ASP.NET Blogging on Azure Stuff http://blogs.recneps.net/ http://www.rssboard.org/rss-specification BlogEngine.NET 2.9.1.0 en-US http://blogs.recneps.net/opml.axd http://www.dotnetblogengine.net/syndication.axd Steve Spencer Steve Spencer's Blog 0.000000 0.000000 Custom Application Roles in Azure AD <p>Previously I’ve talked about how you can control access to your web applications in Azure AD (<a href="http://blogs.recneps.net/post/Managing-Application-Access-with-Azure-AD-Part-1" target="_blank">Part 1</a> &amp; <a href="http://blogs.recneps.net/post/Managing-Application-Access-with-Azure-AD-Part-2" target="_blank">Part 2</a>) and also how to use Role Based Access Control (<a href="http://blogs.recneps.net/post/Introduction-to-Azure-Role-Based-Access-Control-(RBAC)" target="_blank">RBAC</a>) to manage access to resources in Azure. This post will build on these previous posts and show you how you can create your own custom roles for use in your own web applications and how you can use these roles to control access to parts of your application.I’ll use the same example used in <a href="http://blogs.recneps.net/post/Managing-Application-Access-with-Azure-AD-Part-1" target="_blank">Part 1</a>.</p><p>Firstly you need to created the roles for your application to use, assign the roles to users and finally change your code to make it role aware.</p><p>To add roles to your application. Navigate to the Azure portal and click on Azure Active Directory and App Registrations. Select the Web App you created previously.</p><p><a href="http://blogs.recneps.net/image.axd?picture=image_190.png"><img width="744" height="401" title="image" style="display: inline; background-image: none;" alt="image" src="http://blogs.recneps.net/image.axd?picture=image_thumb_190.png" border="0"></a></p><p>Click on “App roles | Preview” then “Create App Role”</p><p><a href="http://blogs.recneps.net/image.axd?picture=image_191.png"><img width="372" height="586" title="image" style="display: inline; background-image: none;" alt="image" src="http://blogs.recneps.net/image.axd?picture=image_thumb_191.png" border="0"></a></p><p>Enter the role information and click Apply and repeat for all the roles you require.</p><p>You should now see your roles in the grid:</p><p><a href="http://blogs.recneps.net/image.axd?picture=image_192.png"><img width="601" height="166" title="image" style="display: inline; background-image: none;" alt="image" src="http://blogs.recneps.net/image.axd?picture=image_thumb_192.png" border="0"></a></p><p>I’ve added a standard user role and a test administrator role.</p><p>To assign these roles to users, Navigate to the Enterprise Applications blade and click your application. Then select “Users and groups”</p><p><a href="http://blogs.recneps.net/image.axd?picture=image_193.png"><img width="745" height="275" title="image" style="display: inline; background-image: none;" alt="image" src="http://blogs.recneps.net/image.axd?picture=image_thumb_193.png" border="0"></a></p><p>To Add roles to an existing assigned user, tick the user and then click “Edit”</p><p><a href="http://blogs.recneps.net/image.axd?picture=image_194.png"><img width="584" height="410" title="image" style="display: inline; background-image: none;" alt="image" src="http://blogs.recneps.net/image.axd?picture=image_thumb_194.png" border="0"></a></p><p>Select the role and click “Select”</p><p><a href="http://blogs.recneps.net/image.axd?picture=image_195.png"><img width="740" height="225" title="image" style="display: inline; background-image: none;" alt="image" src="http://blogs.recneps.net/image.axd?picture=image_thumb_195.png" border="0"></a></p><p>You should now see the role is assigned to the user. Similarly to add a role to a new user click “Add user”</p><p><a href="http://blogs.recneps.net/image.axd?picture=image_196.png"><img width="740" height="225" title="image" style="display: inline; background-image: none;" alt="image" src="http://blogs.recneps.net/image.axd?picture=image_thumb_196.png" border="0"></a></p><p>This time you need to select the new user and then the role:</p><p><a href="http://blogs.recneps.net/image.axd?picture=image_197.png"><img width="748" height="525" title="image" style="display: inline; background-image: none;" alt="image" src="http://blogs.recneps.net/image.axd?picture=image_thumb_197.png" border="0"></a></p><p>You can add multiple roles to a user by repeating the Add user process.</p><p><a href="http://blogs.recneps.net/image.axd?picture=image_198.png"><img width="750" height="290" title="image" style="display: inline; background-image: none;" alt="image" src="http://blogs.recneps.net/image.axd?picture=image_thumb_198.png" border="0"></a></p><p>Here I’ve added both new roles to one user.</p><p>You are now ready to user these roles in your application.</p><p>The sample code already shows how to <a href="https://github.com/AzureADQuickStarts/AppModelv2-WebApp-OpenIDConnect-DotNet/blob/fe61021b02414c8c97e46ded79ecc71de12cf4b8/AppModelv2-WebApp-OpenIDConnect-DotNet/Views/Claims/Index.cshtml#L23" target="_blank">view the claims</a> for a user. </p><p><a href="http://blogs.recneps.net/image.axd?picture=image_199.png"><img width="557" height="140" title="image" style="display: inline; background-image: none;" alt="image" src="http://blogs.recneps.net/image.axd?picture=image_thumb_199.png" border="0"></a></p><p>When I sign in to the application with the user that has two roles I see the following entries in the claims table:</p><p><a href="http://blogs.recneps.net/image.axd?picture=image_200.png"><img width="558" height="76" title="image" style="display: inline; background-image: none;" alt="image" src="http://blogs.recneps.net/image.axd?picture=image_thumb_200.png" border="0"></a></p><p>Adding the roles to the application and the assigning the roles to a user is enough to make them appear as roles in your application when the user signs in. There is a limit to the number of roles that an application can have. These are stored in the manifest of the App Registration. There is a <a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/reference-app-manifest#manifest-limits" target="_blank">limit of 1200</a> items in the App Registration Manifest and this includes all the configuration items not just roles. </p><p>There are a number of ways in which you can use Roles in code. Firstly in your views you can add conditional code to limit what a standard user can see</p><blockquote><p>@if (Request.IsAuthenticated &amp;&amp; User.IsInRole("Test.Admin"))<p>{<p>&lt;h2&gt;You Are An Admininstrator&lt;/h2&gt;<p>&lt;br /&gt;<p>}</p></blockquote><p>When you sign in with the Test,Admin role you will get this additional text which is not visible for the User role</p><p><a href="http://blogs.recneps.net/image.axd?picture=image_201.png"><img width="418" height="154" title="image" style="display: inline; background-image: none;" alt="image" src="http://blogs.recneps.net/image.axd?picture=image_thumb_201.png" border="0"></a></p><p>You can also control access at the controller and controller action levels by adding the Authorize attribute on the controller or controller action:</p><blockquote><p>[Authorize(Roles = "Test.Admin ")]<p>public class ClaimsController : Controller<p>{</p></blockquote><p>or for multiple roles<blockquote><p>[Authorize(Roles = "Test.Admin,User")]<p>public class ClaimsController : Controller<p>{</p></blockquote><p>at the action level:<blockquote><p>[Authorize(Roles = "Test.Admin")]<p>public async Task&lt;ActionResult&gt; Index()<p>{<p>}</p></blockquote><p>or both<blockquote><p>[Authorize(Roles = "Test.Admin,User")]<p>public class ClaimsController : Controller<p>{<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Authorize(Roles = "Test.Admin")]<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public async Task&lt;ActionResult&gt; Index()<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<p><br><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Authorize(Roles = "User")]<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public async Task&lt;ActionResult&gt; Index2()<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<p>}</p></blockquote><p>In this example the user needs either the User or Test.Admin role to access the controller but only the Test.Admin role can access the Index action and the User role can access the Index2 action. This allows you to put controls in at multiple levels and provide a more custom experience for your users.<p>App Roles makes it easy to add custom roles to your application. If you have a higher Azure AD subscription you can assign these roles to groups and assign the groups to the applications. This means that you can add users to groups to assign the roles rather than adding them to each individual user. I can have a Standard user group that has the User role assigned and all users in that group will have the User role passed through to the application. <p>You now have Role Based Access control in your Azure AD application and can start to build your application features out based on the roles you define. http://blogs.recneps.net/post/Custom-Application-Roles-in-Azure-AD http://blogs.recneps.net/post/Custom-Application-Roles-in-Azure-AD#comment http://blogs.recneps.net/post.aspx?id=334b0a22-6f2e-4b36-a60b-ba70adcb2beb Sun, 22 Nov 2020 10:33:55 +0000 ASP.NET Azure AD Azure App Service C# Security steve http://blogs.recneps.net/pingback.axd http://blogs.recneps.net/post.aspx?id=334b0a22-6f2e-4b36-a60b-ba70adcb2beb 3 http://blogs.recneps.net/trackback.axd?id=334b0a22-6f2e-4b36-a60b-ba70adcb2beb http://blogs.recneps.net/post/Custom-Application-Roles-in-Azure-AD#comment http://blogs.recneps.net/syndication.axd?post=334b0a22-6f2e-4b36-a60b-ba70adcb2beb Custom ASP.NET MVC app running in a Windows Container <p>With the introduction of Windows Containers on&nbsp; Window Server 2016 and the ability to run containers in Service Fabric I thought it was time to investigate Windows Containers and I wanted to know how to build one that will run a web site using IIS.</p> <p>As I’m new to containers, although I’ve done a very similar exercise with Docker on Linux, I decided to follow the <a href="https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-server">Windows Quick Start Guide</a>. I hit a few problems early on so I’ve put the steps I followed here:</p> <p>After opening a PowerShell window as administrator I ran the following commands:</p><strong><em><font face="Consolas">Install-Module -Name DockerMsftProvider -Repository PSGallery –Force</font> </em></strong>– Ran OK<br><strong><em><font face="Consolas">Install-Package -Name docker -ProviderName DockerMsftProvider</font> </em></strong>– Had an error <br><font color="#ff0000" size="1">WARNING: Cannot verify the file SHA256. Deleting the file.</font> <br><font color="#ff0000" size="1">WARNING: C:\Users\ADMINI~1.DEV\AppData\Local\Temp\DockerMsftProvider\Docker-1-12-2-cs2-ws-beta.zip does not exist</font> <br><font color="#ff0000" size="1">Install-Package : Cannot find path 'C:\Users\ADMINI~1.DEV\AppData\Local\Temp\DockerMsftProvider\Docker-1-12-2-cs2-ws-beta.zip' because it does not exist.</font> <br> <p>&nbsp; <p>Not sure what was causing this to fail but I followed the instructions to manually install (from <a href="https://github.com/OneGet/MicrosoftDockerProvider/issues/15">https://github.com/OneGet/MicrosoftDockerProvider/issues/15</a>) <p><font face="Consolas"><strong><em>Start-BitsTransfer -Source https://dockermsft.blob.core.windows.net/dockercontainer/docker-1-12-2-cs2-ws-beta.zip</em></strong><strong><em> -Destination /docker.zip </em></strong><br><strong><em>Get-FileHash -Path /docker.zip -Algorithm SHA256 </em></strong><br><strong><em>mkdir C:\Users\Administrator\AppData\Local\Temp\DockerMsftProvider\</em></strong> <br><strong><em>cp .\docker.zip C:\Users\Administrator\AppData\Local\Temp\DockerMsftProvider\ </em></strong><br><strong><em>cd C:\Users\Administrator\AppData\Local\Temp\DockerMsftProvider\ </em></strong><br><strong><em>cp .\docker.zip Docker-1-12-2-cs2-ws-beta.zip </em></strong><br><strong><em>Install-Package -Name docker -ProviderName DockerMsftProvider -Verbose </em></strong><strong><em>Restart-Computer –Force</em></strong><br></font></p> <p>After Rebooting I tried to download and run a sample container</p> <p><font face="Consolas"><strong><em>docker run microsoft/dotnet-samples:dotnetapp-nanoserver</em></strong></font></p> <p><font face="Arial">but I got the following error</font></p> <p><font color="#ff0000" size="1">docker : C:\Program Files\Docker\docker.exe: error during connect: Post </font><a href="http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.25/containers/create"><font color="#ff0000" size="1">http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.25/containers/create</font></a><font color="#ff0000" size="1">: open //./pipe/docker_engine: The </font> <p><font color="#ff0000" size="1">system cannot find the file specified..</font> <p><font color="#ff0000" size="1">At line:1 char:1</font> <p><font color="#ff0000" size="1">+ docker run microsoft/dotnet-samples:dotnetapp-nanoserver</font> <p><font color="#ff0000" size="1">+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</font> <p><font color="#ff0000" size="1">+ CategoryInfo : NotSpecified: (C:\Program File...ile specified..:String) [], RemoteException</font> <p><font color="#ff0000" size="1">+ FullyQualifiedErrorId : NativeCommandError</font> <p>It turns out that the docker service wasn’t running after the reboot, so open services.msc and find the docker service to start it. <p>Running the same command again will download the image from docker hub, create a container from it and then run it. As this is a visual container it runs once and then stops. <p><a href="http://blogs.recneps.org/image.axd?picture=clip_image001_4.png"><img title="clip_image001" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="clip_image001" src="http://blogs.recneps.org/image.axd?picture=clip_image001_thumb_4.png" width="422" height="431"></a> <p>Every time I do <strong><em>docker run microsoft/dotnet-samples:dotnetapp-nanoserver</em></strong> it creates a new container. What I want to do is to run one that is stopped and view the output on the screen.</p> <p>For this I needed to start the container I had already created. If you run </p> <p><font face="Consolas"><strong><em>docker –ls –a</em></strong></font></p> <p>This will list all the containers that are both running and stopped and you can see from the image below that I had run docker run a number of time. Each time it tried to download the image (which was already downloaded) and then create a new container from it.</p> <p><a href="http://blogs.recneps.org/image.axd?picture=clip_image001%5B6%5D.png"><img title="clip_image001[6]" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="clip_image001[6]" src="http://blogs.recneps.org/image.axd?picture=clip_image001%5B6%5D_thumb.png" width="994" height="74"></a></p> <p><font face="Consolas"><strong><em>docker container start -a 12d382ae0bd6</em></strong></font> (-a attached STDOUT so you can see the output)</p> <p><a href="http://blogs.recneps.org/image.axd?picture=clip_image001%5B8%5D.png"><img title="clip_image001[8]" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="clip_image001[8]" src="http://blogs.recneps.org/image.axd?picture=clip_image001%5B8%5D_thumb.png" width="415" height="567"></a></p> <p>Now I know how to create and start containers I wanted to build one of my own. This is easier than I first though as there a lots of base templates stored on docker hub and git hub. </p> <p><a title="https://docs.microsoft.com/en-us/virtualization/windowscontainers/samples#Application-Frameworks" href="https://docs.microsoft.com/en-us/virtualization/windowscontainers/samples#Application-Frameworks">https://docs.microsoft.com/en-us/virtualization/windowscontainers/samples#Application-Frameworks</a></p><a title="https://hub.docker.com/r/microsoft/" href="https://hub.docker.com/r/microsoft/">https://hub.docker.com/r/microsoft/</a> <p>I picked one on docker hub that has IIS and ASP.Net installed already, so all I needed to do after was to add my own website and configure IIS correctly. Using docker pull,</p> <p><font face="Consolas"><strong><em>docker pull microsoft/aspnet</em></strong></font> (see <a title="https://hub.docker.com/r/microsoft/aspnet/" href="https://hub.docker.com/r/microsoft/aspnet/">https://hub.docker.com/r/microsoft/aspnet/</a>) <p>This retrieves the template from Docker Hub and I want to use that template to install my ASP.Net MVC site and configure IIS to serve the pages on port 8000. Following the instructions here (<a href="https://docs.microsoft.com/en-us/dotnet/articles/framework/docker/aspnetmvc">https://docs.microsoft.com/en-us/dotnet/articles/framework/docker/aspnetmvc</a>). I published my MVC site and copied the publish folder to my docker machine. Then I needed to create a Dockerfile recipe to instruct docker what to install in my image. So I created a folder that contained the Dockerfile and also the published website as below <p><a href="http://blogs.recneps.org/image.axd?picture=clip_image001%5B10%5D.png"><img title="clip_image001[10]" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="clip_image001[10]" src="http://blogs.recneps.org/image.axd?picture=clip_image001%5B10%5D_thumb.png" width="178" height="61"></a> </p> <p>The contents of the Dockerfile are: </p> <p><font face="Consolas"><strong><em># The FROM instruction specifies the base image. You are</em></strong></font><br><font face="Consolas"><strong><em># extending the microsoft/aspnet image.</em></strong></font><br><font face="Consolas"><strong><em>FROM microsoft/aspnet</em></strong></font><br><font face="Consolas"><strong><em># Next, this Dockerfile creates a directory for your application</em></strong></font><br><font face="Consolas"><strong><em>RUN mkdir C:\sdsweb</em></strong></font><br><font face="Consolas"><strong><em># configure the new site in IIS.</em></strong></font><br><font face="Consolas"><strong><em>RUN powershell -NoProfile -Command \</em></strong></font><br><font face="Consolas"><strong><em>Import-module IISAdministration; \</em></strong></font><br><font face="Consolas"><strong><em>New-IISSite -Name "sdsweb" -PhysicalPath C:\sdsweb -BindingInformation "*:8000:"</em></strong></font><br><font face="Consolas"><strong><em># This instruction tells the container to listen on port 8000. </em></strong></font><br><font face="Consolas"><strong><em>EXPOSE 8000</em></strong></font><br><font face="Consolas"><strong><em># The final instruction copies the site you published earlier into the container.</em></strong></font><br><font face="Consolas"><strong><em>ADD sdswebsource/ /sdsweb</em></strong></font><br></p> <p>Now I need to run this to create the image <p>In PowerShell, I changed directory to the folder containing my Dockerfile, then ran <p><font face="Consolas"><strong><em>docker build -t sdsweb .</em></strong></font> <p>This has created an image and we need to now get this running as a container <p><a href="http://blogs.recneps.org/image.axd?picture=clip_image001%5B12%5D.png"><img title="clip_image001[12]" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="clip_image001[12]" src="http://blogs.recneps.org/image.axd?picture=clip_image001%5B12%5D_thumb.png" width="693" height="82"></a> <p>using docker run again <p><strong><em><font face="Consolas">docker run -d -p 8000:8000 --name sdsweb sdsweb</font></em></strong> <p><a href="http://blogs.recneps.org/image.axd?picture=clip_image001%5B14%5D.png"><img title="clip_image001[14]" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="clip_image001[14]" src="http://blogs.recneps.org/image.axd?picture=clip_image001%5B14%5D_thumb.png" width="700" height="68"></a> <p>My container is now running and I should be able to view the web pages in my browser on port 8000, but I need to know the IP address first <p><strong><em><font face="Consolas">docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" sdsweb</font></em></strong> <p><a href="http://blogs.recneps.org/image.axd?picture=clip_image001%5B16%5D.png"><img title="clip_image001[16]" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="clip_image001[16]" src="http://blogs.recneps.org/image.axd?picture=clip_image001%5B16%5D_thumb.png" width="757" height="48"></a> <p>Now I can browser to <a href="http://172.17.97.235:8000">http://172.17.97.235:8000</a> </p> <p><a href="http://blogs.recneps.org/image.axd?picture=clip_image001%5B18%5D.png"><img title="clip_image001[18]" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="clip_image001[18]" src="http://blogs.recneps.org/image.axd?picture=clip_image001%5B18%5D_thumb.png" width="605" height="342"></a></p> <p>I changed the default web page to show the machine name serving the pages under Getting Started. Listing the containers will show the container ID and this matches the machine name displayed on the web page</p> <p><a href="http://blogs.recneps.org/image.axd?picture=image_19.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://blogs.recneps.org/image.axd?picture=image_thumb_19.png" width="391" height="56"></a></p> <p>That’s it running in a container. There are a couple more things I’d like to do before I’ve finished. The first is to make sure that when my Windows Server restarts, then my sdsweb container also starts. At the moment it will not start as I didn’t add a restart parameter when I called docker run. Adding –restart always will cause the container to restart when windows restarts.</p> <p><strong><em><font face="Consolas">docker run -d -p 8000:8000 --name sdsweb --restart always sdsweb</font></em></strong></p> <p>The final thing I want to do is to be able to share this image so I’d like to push it up to docker hub</p> <p><strong><em><font face="Consolas">docker login</font></em></strong> - enter username and password <p><strong><em><font face="Consolas">docker push recneps/sdsweb</font></em></strong> <p><a href="http://blogs.recneps.org/image.axd?picture=clip_image001%5B20%5D.png"><img title="clip_image001[20]" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="clip_image001[20]" src="http://blogs.recneps.org/image.axd?picture=clip_image001%5B20%5D_thumb.png" width="506" height="121"></a> <p>Then to use it on another machine <p><strong><em><font face="Consolas">docker pull recneps/sdsweb</font></em></strong> <p><a href="http://blogs.recneps.org/image.axd?picture=clip_image002_3.png"><img title="clip_image002" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="clip_image002" src="http://blogs.recneps.org/image.axd?picture=clip_image002_thumb_3.png" width="513" height="85"></a> <p>In my next post I am going to look at how I can create a container that can be hosted in Service Fabric</p> http://blogs.recneps.net/post/Custom-ASPNET-MVP-app-running-in-a-Windows-Container http://blogs.recneps.net/post/Custom-ASPNET-MVP-app-running-in-a-Windows-Container#comment http://blogs.recneps.net/post.aspx?id=bebc9b1a-3038-4191-a3eb-64ceea78ace5 Sat, 11 Feb 2017 16:39:36 +0000 ASP.NET PowerShell Visual Studio Windows Containers Docker steve http://blogs.recneps.net/pingback.axd http://blogs.recneps.net/post.aspx?id=bebc9b1a-3038-4191-a3eb-64ceea78ace5 50 http://blogs.recneps.net/trackback.axd?id=bebc9b1a-3038-4191-a3eb-64ceea78ace5 http://blogs.recneps.net/post/Custom-ASPNET-MVP-app-running-in-a-Windows-Container#comment http://blogs.recneps.net/syndication.axd?post=bebc9b1a-3038-4191-a3eb-64ceea78ace5 System.Web.Mvc not found after deploying to Azure Web Apps using Release Manager <p>I’m currently evaluating Release Manager in Visual Studio Team Services and I am using it to deploy website to Azure Web Apps. I recently tried to deploy an Asp.Net MVC 4 application and ran into some issues.</p> <p>I’ve created a build that packages and zips up my web application which runs successfully.I’ve linked a Release pipeline to this build and I can deploy to my test Azure site without any errors, but when I try and run the web application I get the following error:</p> <p><i>Could not load file or assembly 'System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.</i> <p><a href="http://blogs.recneps.org/image.axd?picture=image_10.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://blogs.recneps.org/image.axd?picture=image_thumb_10.png" width="871" height="112"></a> <p>I’m using Visual Studio 2013 with MVC as a nuget package.Looking at the properties of System.Web.Mvc I can see that it is set to Copy Local = True <p><a href="http://blogs.recneps.org/image.axd?picture=image_11.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://blogs.recneps.org/image.axd?picture=image_thumb_11.png" width="440" height="178"></a> <p>I tried a few different things to try to get the assembly to be copied like redoing the nuget install and eventually I toggled the Copy Local to False, saved the project file and then set it back to true. When I looked at the diff of the project file I found an additional property <p><a href="http://blogs.recneps.org/image.axd?picture=image_12.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://blogs.recneps.org/image.axd?picture=image_thumb_12.png" width="229" height="37"></a> <p>This seems to fix the build. When I checked this in and rebuild, System.Web.Mvc now appears in the zip file. The build was then release to Azure and the web app worked correctly. http://blogs.recneps.net/post/SystemWebMvc-not-found-after-deploying-to-Azure-Web-app-using-release-manager http://blogs.recneps.net/post/SystemWebMvc-not-found-after-deploying-to-Azure-Web-app-using-release-manager#comment http://blogs.recneps.net/post.aspx?id=86c00947-52e9-4085-859c-556e0e896967 Sat, 09 Apr 2016 19:06:56 +0000 ASP.NET Azure Azure Web Apps TFS Visual Studio Team Services Visual Studio Release Manager steve http://blogs.recneps.net/pingback.axd http://blogs.recneps.net/post.aspx?id=86c00947-52e9-4085-859c-556e0e896967 4 http://blogs.recneps.net/trackback.axd?id=86c00947-52e9-4085-859c-556e0e896967 http://blogs.recneps.net/post/SystemWebMvc-not-found-after-deploying-to-Azure-Web-app-using-release-manager#comment http://blogs.recneps.net/syndication.axd?post=86c00947-52e9-4085-859c-556e0e896967 Changing Website Settings through the Azure Portal <p>When using configuration in Microsoft Azure websites, ensure that you put configuration that you are likely to change often in AppSettings. This allows you to make configuration changes in the Management portal of Azure rather than having to edit the web.config file directly. An example of where you might like to do this include settings that allow you to disable site features temporarily such as during an upgrade or routine maintenance.</p> <p>App settings in the web config file are names/value pairs and are accessed as follows:</p> <p>System.Configuration.ConfigurationManager.AppSettings["StevesSetting"]</p> <p>Which can be seen in the web.config as follows:</p> <p>&lt;configuration&gt;<br>&nbsp; .<br>&nbsp; &lt;appSettings&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;add key="StevesSetting" value="Webconfig setting" /&gt;<br>&nbsp; &lt;/appSettings&gt;<br>&nbsp; .<br>&lt;/configuration&gt; <p>In order to manage this configuration in the portal you need to navigate to your website and click the configure tab (in the old portal) <p><a href="http://blogs.recneps.net/image.axd?picture=image.png"><img width="497" height="41" title="image" style="border: 0px currentColor; display: inline;" alt="image" src="http://blogs.recneps.net/image.axd?picture=image_thumb.png" border="0"></a> <p>and scroll down to app settings, then add in the setting you wish to change <p><a href="http://blogs.recneps.net/image.axd?picture=image_1.png"><img width="272" height="88" title="image" style="border: 0px currentColor; display: inline;" alt="image" src="http://blogs.recneps.net/image.axd?picture=image_thumb_1.png" border="0"></a> <p></p> <p>Or in the old portal navigate to the website and click settings then applications settings and scroll down to the app settings section</p> <p><a href="http://blogs.recneps.net/image.axd?picture=image_2.png"><img width="299" height="199" title="image" style="border: 0px currentColor; display: inline;" alt="image" src="http://blogs.recneps.net/image.axd?picture=image_thumb_2.png" border="0"></a></p> http://blogs.recneps.net/post/Changing-Website-Settings-through-the-Azure-Portal http://blogs.recneps.net/post/Changing-Website-Settings-through-the-Azure-Portal#comment http://blogs.recneps.net/post.aspx?id=b14f2e5f-7adc-4983-9121-36f2640c00b5 Mon, 02 Mar 2015 15:09:00 +0000 ASP.NET Azure Websites Microsoft Azure steve http://blogs.recneps.net/pingback.axd http://blogs.recneps.net/post.aspx?id=b14f2e5f-7adc-4983-9121-36f2640c00b5 24 http://blogs.recneps.net/trackback.axd?id=b14f2e5f-7adc-4983-9121-36f2640c00b5 http://blogs.recneps.net/post/Changing-Website-Settings-through-the-Azure-Portal#comment http://blogs.recneps.net/syndication.axd?post=b14f2e5f-7adc-4983-9121-36f2640c00b5 Azure Websites: Blocking access to the azurewebsites.net url <p>I’ve been setting up one of our services as the backend service for Azure API management. Part of this process we have mapped DNS to point to the service. As the service is hosted in Azure Websites there are now two urls that exist which can be used to access the service. I wanted to stop a user from accessing the site using the azurewebsites.net url and only access it via the mapped domain. This is easy to achieve and can be configured in the web.config file of the service.</p> <p>In the &lt;system.webServer&gt; section add the following configuration</p><p>&lt;rewrite&gt;<br>&nbsp;&nbsp;&nbsp; &lt;rules&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;rule name="Block traffic to the raw azurewebsites url"&nbsp; patternSyntax="Wildcard" stopProcessing="true"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;match url="*" /&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;conditions&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;add input="{HTTP_HOST}" pattern="*azurewebsites.net*" /&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/conditions&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;action type="CustomResponse" statusCode="403" statusReason="Forbidden"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; statusDescription="Site is not accessible" /&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/rule&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/rules&gt;<br>&lt;/rewrite&gt;</p> <p>Now if I try and access my site through the azurewebsites.net url, I get a 403 error, but accessing through the mapped domain is fine.</p> http://blogs.recneps.net/post/Azure-Websites-Blocking-access-to-the-azurewebsitesnet-url http://blogs.recneps.net/post/Azure-Websites-Blocking-access-to-the-azurewebsitesnet-url#comment http://blogs.recneps.net/post.aspx?id=ee32ca2b-b393-4131-8809-3ea02d304eaf Thu, 18 Dec 2014 15:34:00 +0000 ASP.NET Azure Azure Websites Microsoft Azure Steve http://blogs.recneps.net/pingback.axd http://blogs.recneps.net/post.aspx?id=ee32ca2b-b393-4131-8809-3ea02d304eaf 12 http://blogs.recneps.net/trackback.axd?id=ee32ca2b-b393-4131-8809-3ea02d304eaf http://blogs.recneps.net/post/Azure-Websites-Blocking-access-to-the-azurewebsitesnet-url#comment http://blogs.recneps.net/syndication.axd?post=ee32ca2b-b393-4131-8809-3ea02d304eaf Windows Azure and SignalR with Gadgeteer <p>I&rsquo;ve been playing with Gadgeteer (<a href="http://www.netmf.com/gadgeteer/">http://www.netmf.com/gadgeteer/</a>) for a while now and I am a big fan of the simple way we can build embedded hardware applications with high functionality. We have a proof of concept device that includes a Colour touch screen, RFID reader and an Ethernet connections. This device is capable of connecting to a web api REST service which we have hosted in Windows Azure and we can use this service to retrieve data from our service depending upon the RFID code that is read. This works well but there are times when we would like to notify the device when something has changed. <a href="http://www.asp.net/signalr/">SignalR</a> seems to be the right technology for this as it removes the need to write polling code in your application.</p> <p>Gadgeteer uses the .Net Micro framework which is a cut down .Net framework and doesn&rsquo;t support the ASP.NET SignalR libraries. As we can use web api using the micro framework using the WebRequest classes,&nbsp; I wondered what was involved to get SignalR working on my Gadgeteer device.</p> <p>The first problem was to work out the protocol used by SignalR and after a short while trawling the web for details of the protocol I gave up and got my old friend fiddler out to see what was really happening.</p> <p>After creating a SignalR service I connected my working example to the signalR hub running on my local IIS..</p> <p>The first thing that pleased me was that the protocol looked fairly simple. It starts with a negotiate which is used to return a token which is needed for the actual connection.</p> <p>GET /signalr/negotiate?_=1369908593886</p> <p>Which returns some JSON:</p> <p><span style="font-size: xx-small;">{"Url":"/signalr","ConnectionToken":"xyxljdMWO9CZbAfoGRLxNu54GLHm7YBaSe5Ctv6RseIJpQPRJIquHQKF4heV4B_C2PbVab7OA2_8KA-AoowOEeWCqKljKr4pNSxuyxI0tLIZXqTFpeO7OrZJ4KSx12a30","ConnectionId":"9dbc33c2-0d5e-458f-9ca6-68e3f8ff423e","KeepAliveTimeout":20.0,"DisconnectTimeout":30.0,"TryWebSockets":true,"WebSocketServerUrl":null,"ProtocolVersion":"1.2"}</span></p> <p>I used this JSON to pull out the connection id and connection token. This was the first tricky part with the .Net Micro framework. There is not the same support for JSON serialisation you get with the full framework plus the string functions are limited as well. For this I used basic string functions using Substring and IndexOf as follows:</p> <pre class="csharpcode"><span class="kwrd">int</span> index = negJson.IndexOf(<span class="str">"\""</span>+token+<span class="str">"\":\""</span>); <span class="kwrd">if</span> (index != -1) { <span class="rem">// Extracts the exact JSON value for then name represented by token</span> <span class="kwrd">int</span> startindex = index + token.Length + 4; <span class="kwrd">int</span> endindex = negJson.IndexOf(<span class="str">"\""</span>, startindex); <span class="kwrd">if</span> (endindex != -1) { <span class="kwrd">int</span> length = endindex - startindex; stringToExtract = negJson.Substring(startindex, length); } }</pre> <p>With the correct token received Fiddler led me to the actual connection of signalR:</p> <p>GET /signalr/connect?transport=webSockets&amp;connectionToken=yourtoken&amp;connectionData=%5B%7B%22name%22%3A%22chathub%22%7D%5D&amp;tid=2 HTTP/1.1</p> <p>Looking at this I could determine that I needed to pass in the token I retrieved from negotiate, the transport type and the name of the hub I want to connect to. After a bit of investigating I used the transport of longPolling.</p> <p>Now as I think I understood the protocol, I tried to implement it in SignalR. The first issue that arose was what to send with the negotiate call. I figured that this was some sort of id of the client that is trying to connect so I decided to use the current tick count. This seemed to work and I guess that as long as my devices don&rsquo;t connect at exactly the same time then Signal R would work. I&rsquo;ve had no problems so far with this.</p> <p>Upon connecting to the hub I needed to create a separate thread to handle signalR so that the main device wouldn't stop running whilst the connection to the SignalR hub was waiting for a response. Once a response is received the response returns with a block of JSON data appropriate to the SignalR message being received. This needs to be decoded and passed onto the application. You then need to reconnect back to the SignalR hub. The period between receiving data and then reconnecting back to the hub needs to be small. Whilst the message is being processed it cannot receive any more message and may miss some data. I retrieve the response stream and then pass the processing of the stream to a separate thread so that I can reconnect to the hub as fast as possible.</p> <p>This is not a full implementation of SignalR on the .Net Micro-framework but it is the implementation of a simple client and can be used fairly successfully on the Gadgeteer device. I still need to do a little more work to try to speed up the connections as it is possible to miss some data.</p> <p>The SignalR hub is hosted on a Windows Azure website along side the web api service which allows both web, Windows 8 and Gadgeteer applications to work side by side.</p> <p>Gadgeteer has opened up another avenue for development and helps us to provide more variety of devices in a solution</p> http://blogs.recneps.net/post/Windows-Azure-and-SignalR-with-Gadgeteer http://blogs.recneps.net/post/Windows-Azure-and-SignalR-with-Gadgeteer#comment http://blogs.recneps.net/post.aspx?id=53c93762-34ba-4ac6-8eca-54396af64ea2 Thu, 30 May 2013 13:37:00 +0000 ASP.NET Gadgeteer SignalR Web API Windows Azure Windows Azure Websites Steve http://blogs.recneps.net/pingback.axd http://blogs.recneps.net/post.aspx?id=53c93762-34ba-4ac6-8eca-54396af64ea2 60 http://blogs.recneps.net/trackback.axd?id=53c93762-34ba-4ac6-8eca-54396af64ea2 http://blogs.recneps.net/post/Windows-Azure-and-SignalR-with-Gadgeteer#comment http://blogs.recneps.net/syndication.axd?post=53c93762-34ba-4ac6-8eca-54396af64ea2