0

I am creating a new website, and it's already online, but I want to block access to everyone! And just let my client use it to check the development process everyday, so he don't need to download everything and set up on his computer..

I was wondering about using ASP Identity, is there any simple "hack" to achieve this?

Or my only way is the following:

  1. Add the Register Page to the WebSite
  2. Register an account with Administrator role
  3. Delete Register Page of the WebSite
  4. Use always the same account to check the page

Waiting for an answer, how to simply and easily achieve this?

EDIT: Maybe there is a way to create a default username (that in this case will be my Administrator?)

Thank you! Thank you very much!

TiagoM
  • 3,458
  • 4
  • 42
  • 83
  • 1
    are you working as an individual or part of company with infrastructure setup? You could easily host it internally in your company and give a VPN Access to your network to access the site – techspider Sep 28 '16 at 18:53
  • I am working as an individual with my own infrastructure setup. I think I already know how to achieve this, thank you. – TiagoM Sep 29 '16 at 07:22

3 Answers3

2

As the user @trailmax suggested I was not choosing the best place to insert default users for Identity, since I was inserting the users each time the constructor of the context was called.

After analysis of course that's not a good option, because every time I access my DbSets I use the context constructor, triggering additional sql queries to Roles and Users DbSets, without need (because I only need that query on the startup to insert the users if they don't exist).

So.. since my web-hosting plan don't allow any Update Migrations neither Seed Methods to be runnable from Package Manager Console (because it always reference the 'master' database which I don't have permissions), I figured out this solution:

1) I create all my tables running a sql script on my remote mssql database (to get the generated SQL Script from my contexts and models, I type the following command in Package Manager Console:

Update-Database -Script -SourceMigration:0

2) Then I need to set Database Initializer to null, so EF doesn't try to drop/create a Database and finnaly I just invoke a method on my Context Class from my Global.asax in the method Application_Start:

protected void Application_Start()
{
     AreaRegistration.RegisterAllAreas();
     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
     RouteConfig.RegisterRoutes(RouteTable.Routes);
     BundleConfig.RegisterBundles(BundleTable.Bundles);
     Database.SetInitializer<MyContext>(null);
     new MyContext().CreateDefaultUsers();
}

3) And here is my method, that is only called on Application Startup (I am almost sure about it, at least I hope so, I wanna save CPU Clocks!)

public class MyContext : IdentityDbContext<IdentityUser>
{
        public MyContext() : base("MyContext")
        {
        }


        internal void CreateDefaultUsers()
        {
            if (!Roles.Any(r => r.Name == "admin"))
            {
                var RoleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(this));
                RoleManager.Create(new IdentityRole("admin"));
            }


            if (!Users.Any(u => u.UserName == "myadmin"))
            {
                var store = new UserStore<IdentityUser>(this);
                var manager = new UserManager<IdentityUser>(store);

                var user = new IdentityUser { UserName = "myadmin" };

                manager.Create(user, "mysupersafepwlulz");
                manager.AddToRole(user.Id, "admin");
            }
        }
     //More stuff not relevang for the question...

}

I hope this helps someone out there, and thank you @trailmax !

Community
  • 1
  • 1
TiagoM
  • 3,458
  • 4
  • 42
  • 83
0

How secure do you need this to be? You could go about it in another fashion, by restricting by IP.

Option 1 - Only allow specific IPs to your site

I'd recommend blocking all access to the site in your web.config and only whitelist the IP(s) that you and the client would be connecting from - it'll save you time, and it would ensure that you're only getting connections from IPs you trust.

Modify the appropriate web.config

<configuration>
  <system.webServer>
    <security>
      <ipSecurity allowUnlisted="false">                    
        <clear/> 
        <add ipAddress="127.0.0.1" allowed="true"/> 
        <add ipAddress="x.x.x.x" allowed="true"/>   <!-- your internal or external ip -->
        <add ipAddress="x.x.x.x" allowed="true"/>   <!-- your client's ip -->
        <add ipAddress="a.b.c.0" subnetMask="255.255.255.0" allowed="true"/>  <!-- your IP range (or client's IP range), if connecting from multpipe IPs on same subnet -->
      </ipSecurity>
    </security>
  </configuration>
</system.webServer>

Add as many <add> directives as needed

Option 2 - add basic authentication to web.config

This is not a permanent solution. Look into other authentication methods for long term.

<system.web>      
  <authentication mode="Forms">      
    <credentials passwordFormat="Clear">      
      <user name="jdoe1" password="someinsecurepassword" />      
    </credentials>      
  </authentication>      
  <authorization>      
    <allow users="jdoe1" />      
    <deny users="*" />      
  </authorization>      
</system.web>      
Mr Lister
  • 45,515
  • 15
  • 108
  • 150
  • Again, I will reiterate, that this should not be a permanent solution, and is just a "hack". – bitwisebytefoolish Sep 28 '16 at 14:37
  • Thanks for your answer but using authentication I would need to make a new form, and I am using MVC.. the other option using IP it's not suitable for me at the moment, because their IP will be always changing.. – TiagoM Sep 29 '16 at 07:21
0

So I manage to this with a specific DbContext that creates my default user if he doesn't exist on the Database.

Here is the follow up code:

namespace MyNamespace
{
    public class MyContext: IdentityDbContext<IdentityUser>
        {

            public MyContext() : base("DefaultConnection")
            {
                if (!Roles.Any(r => r.Name == "admin"))
                {
                    var RoleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(this));
                    RoleManager.Create(new IdentityRole("admin"));
                }                


                if (!Users.Any(u => u.UserName == "mydefaultuser"))
                {
                    var store = new UserStore<IdentityUser>(this);
                    var manager = new UserManager<IdentityUser>(store);

                    var user = new IdentityUser { UserName = "mydefaultuser" };

                    manager.Create(user, "password");
                    manager.AddToRole(user.Id, "admin");
                }
            }

            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);
                modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            }

            public DbSet<MyItem1> myStuff1 { get; set; }
            public DbSet<MyItem2> myStuff2 { get; set; }
            public DbSet<MyItem3> myStuff3 { get; set; }
            public DbSet<MyItem4> myStuff4 { get; set; }
            public DbSet<MyItem5> myStuff5 { get; set; }
        }
}

Then I needed to specify the config class for the Identity creating this class on App_Start:

namespace MyNamespace
{
    public class IdentityConfig
        {
            public void Configuration(IAppBuilder app)
            {
                app.CreatePerOwinContext(() => new WeirdMachineContext());
                app.UseCookieAuthentication(new CookieAuthenticationOptions
                {
                    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                    LoginPath = new PathString("/Home/Login"),
                });
                FormsAuthentication.SetAuthCookie("CookieValue", false);
            }
        }
}

And last I had to add the following in Web.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections></configSections>
  <appSettings>
    <!-- A lot of other stuff here.. -->
    <add key="owin:AppStartup" value="MyNamespace.IdentityConfig" />
  </appSettings>
    <!-- More stuff here.. -->
</configuration>

I hope it helps someone out there ;)

Good luck!

TiagoM
  • 3,458
  • 4
  • 42
  • 83
  • 1
    Creating users and roles in DbContext is the worst solution I've seen so far - this means you fire 2 unnecessary sql request every time you create a DbContext - that is on every HTTP request. Plus doing this in constructor can cause deadlocks. Just make sure this is _very_ temporary solution. – trailmax Sep 29 '16 at 11:52
  • 1
    See this answer: http://stackoverflow.com/a/39738064/809357 - slightly better place to put your user creation – trailmax Sep 29 '16 at 11:53
  • That's actually a good approach, I didn't though about that, thank you! If you want just write an answer with that solution and after I test it I will be happy to accept it as solution! ;) Thank you @trailmax – TiagoM Sep 29 '16 at 15:07
  • 1
    Nah, don't really like that answer either - I usually insert my default users via EF migration or directly into the DB - only happens once and not more. – trailmax Sep 29 '16 at 15:13
  • Hey @trailmax I just added a new answer with your solution, it's working good and better, at least it seems!! Thank you! – TiagoM Oct 01 '16 at 18:21