How to use Active Directory groups to restrict access to controller actions in ASP.NET MVC and make your application even more secure!

It’s been a year and one of the most popular posts in this blog still today is How To: Secure your ASP.NET MVC application and use Active Directory as the Membership Provider. In that post I promised to write about how to use Active Directory groups to restrict access to controller actions to make your application even more secure by consolidating access based in already defined groups in Active Directory (AD). I finally got to it and here it is.

Remember that if you are not already using Active Directory as your membership provider in your application, you need to first follow the steps described in the first post mentioned above.

In a business, the use of Active Directory to organize user and computer accounts is very common. When we create new web applications for that business it is likely that we want to have some access control to certain areas of the application. For example, let’s say that you have a web application that helps accounting and customer support get details about a certain customer such as reports, invoice details, account information, etc… In such application there is a good chance that accounting and customer service employees will have different access to different areas in the application.

The Example

Here is an example of what such a task will look like in the controller of your MVC application:

public ActionResult DeactivateMembership(Membership model)
 {
    // your business logic here
    return View("DeactivateMembership", model);
 }

And here is what is going to look like with an attribute that will only allow users in the customer service group to execute such task

[AuthorizeAD(Groups = Constants.CSgroup)]</strong>
 public ActionResult DeactivateMembership(Membership model)
 {
    // your business logic here
    return View("DeactivateMembership", model);
 }

The custom AuthorizeAD attribute

The custom attribute labeled AuthorizeAD is what makes this happen, below is the declaration of this custom attribute that access Active Directory to determine if an specific user or group within AD has access to a defined controller action:

namespace Application.Filters
{
public class AuthorizeADAttribute : AuthorizeAttribute
{
    public string Groups { get; set; }
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (base.AuthorizeCore(httpContext))
        {
           /* Return true immediately if the authorization is not 
           locked down to any particular AD group */
           if (String.IsNullOrEmpty(Groups))
               return true;

           // Get the AD groups
           var groups = Groups.Split(',').ToList();

           // Verify that the user is in the given AD group (if any)
           var context = new PrincipalContext(
                                 ContextType.Domain, 
                                 "yourdomainname");

           var userPrincipal = UserPrincipal.FindByIdentity(
                                  context,
                                  IdentityType.SamAccountName,
                                  httpContext.User.Identity.Name);

           foreach (var group in groups)
           if (userPrincipal.IsMemberOf(context, 
                IdentityType.Name, 
                group))
               return true;
        }
         return false;
}

protected override void HandleUnauthorizedRequest(
AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
             var result = new ViewResult();
             result.ViewName = "NotAuthorized";
             result.MasterName = "_Layout";
             filterContext.Result = result;
        }
        else
             base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

The code above overrides the AuthorizeCore call which allow us to customize the authorization check so we can use the Active Directory in our domain.

The implementation

To limit access to controller actions you will use the new custom attribute like this:

[AuthorizeAD(Groups = Constants.CSgroup)]

Where Constant.CSGroup is just a constant value I created that translates to the actual name of the AD group. This can also be used to aggregate two or more AD groups as one value if needed. In the class below I set the value of CSgroup to be the name of two different AD groups in my domain, the csr group and csr_leads group:

public static class Constants
    {
        /// <summary>
        /// CS - Customer support and customer support leads
        /// </summary>
        public const string CSgroup = "csr, csr_leads";
}

If you don’t need to do this then you can use the custom attribute by simply providing the name of your AD group, a user name or the name of a Role within your Active Directory:

// Only give access to a group
[AuthorizeAD(Groups = "yourADgroup")]

</strong>
<strong>// Give access to a group and a user
[AuthorizeAD(Groups = "yourADgroup", Users = "someuser")]</strong>
<strong>
// Give access to a Role
[AuthorizeAD(Roles = "Admin")]

That’s it! Hope this is helpful for you and as always, if you have a recommendation, a comment or question please use the comment’s section below.

 

Tips to have success as a remote worker

I still remember when I first had the opportunity to work remotely, it took some convincing but my employer at the time understood and agreed to give it a try, it was 2002. Nowadays is very common to find professionals, especially developers and designers doing some of their work remotely. There are even some successful companies where not only some employees work remotely but almost their entire work force is remote, in these companies working remotely is just part of the culture.

Tips to have success as a remote workerBelow are some of my own experiences as a remote worker, and although I have never been a 100% remote worker, still think some of the following tips might help some of you, and if you have additional tips please feel free to share it with us in the comment’s section.

Have a schedule and let co-workers know about it

Unless you work remotely 100% of the time, you should let people know in advance about the days and hours you are working remotely, that way no in-person meetings are scheduled and no expectations of you being physically at the office are set. Your company and co-workers will appreciate this.

This also helps you plan for personal things such as running errands, doctor appointments, walking the dog, going to the gym, or whatever it is that you do when you are not attached to specific working hours during the day. The real benefit and very productive thing about working remotely is having the ability to work when you are the most productive, not necessarily from 9-5PM.

Work when you are the most productive, avoid the 9-5

Most people benefit from working remotely because if done correctly, it truly gives you a chance to balance your busy life with your work. Unfortunately many employers and professionals do not understand this and instead request that people working remotely work the same hours as if they were at the office, and while this might be seemed as a good idea it isn’t. Working the same hours while working remotely does not let you realize the full potential of working remotely, and it also brings the same problems you tried to avoid by working remotely such as constant distractions by coworkers pinging you, and the pressure of not being able to work when you are the most productive which in many cases is not from 9-5PM.

Make yourself unreachable

That is right, be unreachable. The whole point about working remotely is so you can be more productive and you can only achieve this by eliminating distractions. If you are in a position where you can work remotely, then you can certainly make yourself unreachable for a day or two. If you or your employer feel uncomfortable with this, then none of you are ready to work remotely or to have a remote workforce. Here are some tips to make yourself unreachable and to train people around you to understand that you are not openly available while working from home, a coffee shop or anywhere you decide to work from:

  • Only read and reply to very important emails that truly require your input.
  • Do not answer the phone if the caller is unknown.
  • Do not engage in online discussions in IM, Twitter, etc…
  • Avoid phone conferences while working remotely.
  • Disable email, IM and other automatic notifications.

Give yourself permission to decline interruptions, and set expectations with your team about this.

Use the right equipment

A good laptop, good internet connection and plenty of electrical power is absolutely needed to succeed as a remote worker. Having two computers such as one sitting at work and another one at home won’t cut it, trust me I tried and failed miserably. Also, remember that working remotely doesn’t mean working only from home, there are going to be days when you decide or need to work from another location such as a coffee shop, a hotel or a co-working space, and you’ll need to make sure that you have all of the above… laptop, fast internet connection and a source of power. Caffeine is in my list of must-have as well.

If possible, have an extra battery (charged) for your laptop, a cell phone and all of the cables you need to power up your devices, never leave home without them.

Use the right software

This advice really varies depending on what you do and who you work for. For example, if your company provides remote access to network shares, and other resources within the company’s network then make sure you have access to it as well as the security software and knowledge to connect to it. For example, most companies will require you to first connect to a virtual private network (VPN) before you can access your email, network folders, databases, etc… Another good idea is to know how to access your company’s email using a browser (webmail) since there are going to be times when your VPN connection might not work when you need to read or sent an important email message. It will happen, trust me on this one.

Here are some other applications that can prove to be very useful while working remotely:

In summary, make sure you test all of your software while at home and confirm that you have everything to do your job remotely.

The above list is what comes to mind based on my experience as the basics for successfully working remotely, and I am sure that depending on your company and the type of work you do there might be the need for other software or equipment to make this happen. If you have other tips or suggestions please add them in the comment’s section below.

How to build a software product in your spare time

I have been writing code professionally since the early days of .NET although I remember doing lots of classic ASP as well. As a student, I did some C++, BASIC and even some Pascal but not enough to be good at it. I consider myself a great decent developer and very enthusiastic about coming up with ideas to use new frameworks and platforms to design and build new software products. It is my idea of fun and have been doing it for quite some time now. Sometimes with the idea and ambition of building companies around my product ideas.

My guess is that most software developers enjoy testing new technologies and some even do it in their spare time, outside of work and probably late at night (it’s the best time to code, especially if you have children!). However, one thing that I get asked often is where do I get the time to think about products and more specifically where do I find the time to do it. You see, to me is not about building the next killer app or anything like it, it is about thinking of how I could use that cool new JavaScript framework, experimenting with a new platform or perhaps some mobile app that will finally get me into mobile development… and it all sounds good until you start finding excuses and convince yourself that you just don’t have the time to do it. If you are in my age group you will likely find excuses involving the kids, the wife, the house chores, the full-time job, etc… and if you are much younger than me then your excuses are going to be the friends, games, parties, or even a job or school.

Excuses are evil, they offer an easy and sometimes pleasant way to avoid doing something new. I hope some of the tips provided below can help you avoid excuses and get you motivated to build a new app or try out some cool new framework.

Originating ideas

Believe it or not, coming up with ideas might be challenging sometimes, one thing I find very useful is to just take a moment, walk, and think of the things I do on a daily basis that I could do better. This task will take you probably a few minutes and you’ll be surprised with the number of ideas you will originate. Some examples of things I have built doing this are, a translation app, a spam blocker, a profile finder and a useful contact merge tool, etc… all of these were created based on this procedure.

Another great way is to ask people around you, or better yet, observe them and find out what things they struggle with while doing their work, using the computer, etc… For example, years ago while at a customer’s site I saw how some people were doing data entry on their computers and getting the information from a piece of paper, after that they scanned the piece of paper and then named it manually… one page at a time, yikes! From this came the idea of creating an application that would allow people to scan all documents at once, then display the scanned pages on the screen along with the data entry fields right next to the image so they could then do the data entry and indexing needed, reducing the task to just a few steps, much quicker and the data entry more accurate. This eventually became a product for a company. Just look around you and think… how can I do this better, how can I reduce the number of steps and if you are brave enough go out and ask people these same questions and you’ll get plenty of ideas!

Designing your product

You have an idea, now what? it is really easy as software developers to just start writing code, this is both fun and common but if you start your application from scratch then it will take you more time, especially if you are using a new framework, etc… The assumption is that you are trying to build this in your spare time at 2 AM in the morning, so you need to plan and optimize for it. The advice here is not to write any code just yet, instead search for open source projects that are using the technology or framework you want to try, download it and build on top of it. It is not cheating, it is a great way to get started and building on top of an existing open source application or software sample will get you ahead and save you a lot of time. Remember, the goal is to build something fast and useful.

Forget about adding any features, focus on the one thing you are trying to solve and nothing else… do not worry about the look or adding extra functionality, first, make sure what you build achieves what you are going after and then you can iterate and add features and improve the look and feel of it.

Finding the time to do it

This is by far the main reason people will never do something they say they want to do. The lack of time according to most is the reason a new language is not learned, a book is not read, a class is not taken and an app is not built! Time is a very valuable thing that we all protect because none of us seem to have enough of it. Let me tell you this, that is bull-crap. the idea of not enough time is overrated, we use it as an excuse to not do the things we need to be doing or worse, to avoid learning or doing something new. Also, I am against working super long hours, it is not healthy and not even productive, instead try to prioritize your tasks, and eliminate or avoid your time-wasters. All of us have a bag full of those.

I used to watch TV every evening, but haven’t had cable for about 5 years now and do not miss it. Yes, I do watch some shows but when I do it is usually using Netflix or Hulu and is usually playing in the background as I am writing or coding. The time I used to spend in front of the TV I now use to write blog postsbuild software, and organize meetups. I know many of you might say you lack the time to do any of this but I disagree, there are way too many hours in the day, spending just 2 hours every day to write that mobile app you’ve been thinking about for a while is very feasible. Above I mentioned I usually write software late at night, that is when my kids are in bed and the house is quiet – it is the perfect time! I don’t spend more than a few hours but sometimes I will spend more time learning about email marketing, writing blog posts, finding useful things on Twitter, etc… it is my hobby and I don’t see any of that as a task, it is enjoyable for me. At the same time, I help around the house, wash dishes, take the kids to school, to swimming lessons, etc. There is enough time to spend with the family since luckily I don’t have to travel much, having a balanced life is not only possible but very real, it is all about spending time on the things that really matter and avoiding the things that are neither useful nor productive.

There is also plenty of time while at work… and I am not suggesting you work in your personal projects during work hours but at times such as lunch. Yep, I love going to lunch with my co-workers but that does not mean I have to do it every day. At least twice a week I spent my lunch time eating a sandwich or cheap sushi and coding away (my own app), writing a blog post, or doing some marketing for some of my projects using email and social networks.

Are you in a different situation where you still cannot find the time to do this? if the answer is Yes then chances are you are not really motivated to do it… excuses are easy to come up with, and I am sure the next time you are watching a TV show, a movie or a game you’ll remember this and think… I guess I do have time if I really wanted to. Do not get me wrong… I love watching some TV shows and movies… maybe too much, but still find the time to do what I like which is developing software apps, sites and writing blog posts like this.

Finally, if you are lucky and use public transportation for your work commute… then use that time to do this, and perhaps, even more, things such as finish reading that book, learning that new language, etc…

Do you have any tips or ideas to add to the above post? please share them with everyone in the comments.