Domanda

I'm new to Azure and I'm working on a project that uses the new Websites model as opposed to Cloud Services. I want to set up a continuous delivery process like this one: http://www.windowsazure.com/en-us/develop/net/common-tasks/publishing-with-tfs/

However, I don't want my site to be publicly addressable after each continuous deployment. Instead, I want my continuous deployments to be accessible only by my team for testing purposes. How can this best be achieved?

Thoughts so far:

  • Wrap the whole site in forms authentication - but I don't like the fact that this means I will be deploying a different version of my site to production than that which I deploy to testing.
  • IP address restrictions - but I don't know if this can be done with Azure Websites and whether this is a good solution?
È stato utile?

Soluzione

The Azure Websites Authentication / Authorization feature was designed to support this exact scenario. Basically, you create a site slot, add AAD authentication to it using a few clicks, and from then on your staging slot will always require a valid login, even after you do a swap operation.

Blog Post: http://azure.microsoft.com/blog/2014/11/13/azure-websites-authentication-authorization/

Demo Video: http://azure.microsoft.com/en-us/documentation/videos/azure-websites-easy-authentication-and-authorization-with-chris-gillum/

Altri suggerimenti

You can add IP restrictions using the URL Rewrite Module, which Azure web sites seem to have enabled by default.

Your web.config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="SayNoToZombies" stopProcessing="true">
                    <match url=".*" />
                    <conditions>
                        <add input="{REMOTE_ADDR}" pattern="::1" negate="true" />
                    </conditions>
                    <action type="CustomResponse" statusCode="403" statusReason="Forbidden: Access is denied." statusDescription="Sorry, you're not allowed" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

You can replace pattern="::1" (localhost in IPv6) with a suitable regex to match your permitted IP, e.g., pattern="87.236.134.47" or if more than one:

pattern="(62\.231\.142\.233)|(87\.236\.134\.47)|(::1)|(127\.0\.0\.1)"

I had to do something similar for a client, but couldn't find a way to restrict access to the site from the Azure portal itself. I went with the IP address restriction option, but did it through code in the application itself. My application was already using forms authentication, so I could perform the IP address check in the sign in action.

In your case I would suggest a custom action filter. Perform the check in the filter and if the IP address is not allowed, return a http 401 (unauthorised) status code.

Create an app setting called AllowedIpAddresses or some such, in which you can add a comma separated list of allowed IP addresses. When you perform the check, you can set your site to allow all traffic if AllowedIpAddresses is empty or doesn't exist. That way, you can ignore this setting in production and all traffic will be allowed by default. You can set up custom app settings for each site within the Azure portal.

Here's what a custom filter might look like. I haven't tested this!

public class AccessRestrictionFilterAttribute : ActionFilterAttribute
{
    // simple wrapper around ConfigurationManager.AppSettings for testability
    private readonly IAppSettingsHandler appSettingsHandler;

    public AccessRestrictionFilterAttribute(IAppSettingsHandler appSettingsHandler)
    {
        this.appSettingsHandler = appSettingsHandler;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var isAllowed = false;
        var userIpAddress = filterContext.HttpContext.Request.UserHostAddress;
        if (appSettingsHandler.AllowedIpAddresses.Split(new[] { ',' }).Any(x => x == userIpAddress))
        {
            isAllowed = true;
        }

        if (!isAllowed)
        {
            filterContext.Result = new HttpUnauthorizedResult();
        }

        base.OnActionExecuting(filterContext);
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top