1

I've built a small MVC3 Application that has some different configuration needs based upon the environment (Dev/Prod).

This is mainly in 2 areas:

  1. Rights: Rights are managed via Active Directory groups but my Development environment is in another domain then my Production environment:

    //
    // GET: /Host/Search
    [Authorize(Roles = @"WIN2012\Main_v2_Read")]
    public ActionResult Search()
    {
        return View();
    }
    
  2. Database connection: In Dev, Integrated security is fine. For production a Service Account should be used:

    < add name="MainContext" connectionString="Data Source=Main-DEV;Initial Catalog=Main;Integrated Security=True" providerName="System.Data.SqlClient" />
    

How should I handle this?

Bart De Vos
  • 571
  • 2
  • 7
  • 23
  • 1
    In prod, I always use integrated security, where the web site is running under an app pool running as a new account with just the permissions I want, but yeah to a different database so your question is well taken. – John Buchanan Nov 04 '12 at 21:40
  • Aren't there multiple web.config files in the solution. One for example with the details for prod and one for dev. (I vaguely remember something like that, can't test it on my tablet though.) – Styxxy Nov 05 '12 at 00:41
  • @Styxxy There are, but they don't look like they do anything in my solution. Do I need to configure them somewhere? This would indeed solve point 2. – Bart De Vos Nov 05 '12 at 07:30
  • You can add the correct parts of the config in those config files (eg the database connection for dev and prod in the web.config for dev and prod). – Styxxy Nov 05 '12 at 07:58

3 Answers3

2

To use different web.config in different configuration you have to swap this configuration and during build, publish, deploy this configuration will be used. You can change active configuration by from configuration manager on bottom of Build menu. Or from select right after green Run arrow.

For web.congig transformations regarding DataSource read hear:

http://blog.discountasp.net/how-web-config-transformation-simplifies-web-deployment/

As for first part of question I would recommend custom Authorize attribute that will swap some your predefined roles names from your code to equivalent of those saved also in web.config. This will be easier for accomplish since you have can have more than to environments and just different web.config transformation for each of them.

n.podbielski
  • 595
  • 6
  • 11
  • Definitely web.config transformations to deal with connection string changes, and a custom Authorize attribute to deal with perms. The IoC approach is too complex for the needed functionality. – Heather Nov 14 '12 at 18:06
1

If you need to inject different values at runtime, then you probably should look at using IOC to do so. You can replace the default FilterProvider with an implementation of your own, that uses an IOC Container.

Here is an implementation of the filterprovider for unity:

public class InjectibleFilterProvider : FilterAttributeFilterProvider
{
    private IUnityContainer cont;
    public InjectibleFilterProvider(IUnityContainer container)
    {
        this.cont = container;
    }

    public override IEnumerable<Filter> GetFilters(ControllerContext controllerContext,
              ActionDescriptor actionDescriptor)
    {
        var filters = base.GetFilters(controllerContext, actionDescriptor);
        if (filters != null)
        {
            foreach (var filter in filters)
            {
                cont.BuildUp(filter.Instance.GetType(), filter.Instance);
            }
            return filters;
        }
        return default(IEnumerable<Filter>);
    }
}

Then you just need to wrap the AuthorizeAttribute a little bit:

public class ModifiedAuthFilter : AuthorizeAttribute
{
    [Dependency]
    public IRoleManager Manager { get; set; }
    public string DesiredRoles { get; set; }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        this.Roles = Manager.GetRealRoleNames(this.DesiredRoles);
        base.OnAuthorization(filterContext);
    }
}

I'll leave the RoleManager up to you to implement and inject to your IOC Container. Now you simply use your new attribute instead of your old:

[ModifiedAuth(DesiredRoles = @"Read_V2_Group")]
public ActionResult Search()
{
    return View();
}

Register your provider in the global.asax likes so:

var oldProvider = FilterProviders.Providers.Single(
         f => f is FilterAttributeFilterProvider
    );
FilterProviders.Providers.Remove(oldProvider);
FilterProviders.Providers.Add(new InjectibleFilterProvider(this.Container));
Chad Ruppert
  • 3,650
  • 1
  • 19
  • 19
0

I would go for this solution: Specifying Roles in web.config of an asp.net MVC application

Then use a debug.web.config with one set of settings and release.web.config with production settings. Should work as a breeze :)

Community
  • 1
  • 1
Magnus Karlsson
  • 3,549
  • 3
  • 31
  • 57