Is Windows Authentication for WCF Enough? - c#

I am developing an application where the security requirements for data transferred and access are fairly high. As I understand, Windows authentication is the preferred method for TCP over an intranet.
How do you deal with situations where Domains are not used and only simple workgroups are available? (Some customers will not be using domains to manage the networks).
Is using the interactive clients details (currently logged in user) enough, or should I get them to separately re-enter their username and/or password, as otherwise aren't I leaving security up to the network administrator to make sure they have an appropriate policy (ie. the computer is locked after a period of time)? This is particularly important as I know some of the users are prone to leaving their computers logged in, so how do I ensure that the account owner is the actual user?
If so, whats the point of using Windows authentication over say username/password authentication if they are just re-entering their authentication details?
Thanks

The point of using Windows authentication is to have a centralized directory for network objects management. If you have workgroups I say you better go with another technology, maybe membership provider and role provider.
This article talks about the cons of doing something like this.

The purpose of using Windows Authentication is to take advantage of the pre-existing membership scheme. In enterprise level development this means the administrator has the centralised membership control panel they are used to using to manage the domain level security. The additional benefit for users is a single login to the computer grants access to multiple applications without having to re-enter their details.
If you don't have domain level security already established and there are no plans to migrate in that direction the membership provider option would be the better option in aspnet. Obviously you will then need to plan how the enterprise would handle the maintenance of multiple login and authentication providers.
[Edit]
Ah...Igor got there first.

Related

How to securely connect to a SQL Server database in a single tier Winforms application?

Background
I'm building a single tier application Winforms application using C#. A SQL Server localdb database is attached to the application that runs when the application does. The plan was to use Windows Authentication to verify that the user is part of the MyApplication role/group and can use the application. But, in order to prevent users from accessing the database via other means, I was thinking of using an Application Role so that only the one SQL application user can edit the db tables.
Question
My understanding is that in order to use an Application Role, you need to provide a username and password in the connection string. I can encrypt this information, but obviously it will need decoded before being sent to the database. Is this a concern in a single tier application? What are other alternatives?
To use an application Role, you'll use the sp_setapprole stored procedure where you will provide the name of the application role and the password, rather than sending it in the connection string. When you use application roles, you still connect using an ordinary login, but once you successfully sp_setapprole, your connection loses its user permissions and instead gains the permissions of the application role. Having the decoded password in memory is a concern if you have reason to believe that users may decide to use a debugger to attach to your process to extract the password. Any administrator would also be able to decrypt the encrypted password on disk as well if you choose to use windows machine-level key containers. Using only a single tier for an application that uses a database is a security risk, and you have to decide based on the circumstances surrounding the application whether it is an acceptable risk to gain the reward of skipping a few weeks of design and development.
Source:
https://technet.microsoft.com/en-us/library/ms190998(v=sql.110).aspx
I highly recommend implementing a web api to manage your application's interactions with the database as well as security. This web api could use a windows "service" account to authenticate with the database, and users would authenticate with the api using their individual windows accounts. This has the added benefit of you never having to think about passwords. As far as managing API permissions, that is an issue that is up to you to design and implement as you see fit. The main issue you need to understand and deal with is uniquely identifying AD users. Take a look at this SO post for more info on that: What Active Directory field do I use to uniquely identify a user?
Your service account would have all necessary permissions on the database to do what the application needs to do, but not all api users would necessarily have permission to use all api functions. You would manage a store of uniquely identified AD users that have permission to use the application and what permissions they have. The rest is design and implementation details that are up to you.
Define user with privilege only to execute stored procedures. By this way if someone use SQL Management Studio, s/he cannot browse/edit tables and even cannot see the table names.

Authorization with using Windows Account

In my Windows Store App (c#) I have own authorization mechanism:
User past their account name / password and sent it to server.
Server generate unique token and returns it to user.
For all next requests user used this token.
Now I'm in trying to make authorization with using only Windows Account.
MSDN provide UserInformation class and I can get name for the user account or domain name for the user. But I thing this is not enough for my authorization scheme.
Also method GetSessionInitiationProtocolUriAsync looks very interesting, but I don't know how correct use such Uri for authorization.
How I can use Windows Account for authorization in my application?
note: I'm interested in both situation: when user inside domain or not.
Thanks.
There is numerous was to implement this but if you want to keep it simple and own the process you could implement your own authentication method which on a successful authentication you could build a hash value from their password and secret salt which could be returned to the user as a cookie etc. which you use to validate on every request there after.
On regards to authorisation you can implement your own or use a role based provider linked to the local machine group or active directory by using the classes below or just using the plain old RoleProviders.
You could implement your own method of authentication using the method described below or using the Authentication and Authorisation provider for ASP.Net (if your server runs on .net). Basically the Asp.Net Membership and role Providers. However the method detailed below will allow you to access and modify roles and other information about the user too.
In .Net 3.5+ there is a new namespace called System.DirectoryServices.AccountManagement.
Snippet from MSDN
The System.DirectoryServices.AccountManagement namespace provides
uniform access and manipulation of user, computer, and group security
principals across the multiple principal stores: Active Directory
Domain Services (AD DS), Active Directory Lightweight Directory
Services (AD LDS), and Machine SAM (MSAM).
System.DirectoryServices.AccountManagement manages directory objects
independent of the System.DirectoryServices namespace. Managed
directory services applications can take advantage of the
AccountManagement API to simplify management of user, computer and
group principals. Solutions that previously required intricate
knowledge of the store or lengthy code, such as finding all groups to
which a user belongs, are accomplished in a few lines of code with the
AccountManagement API.
You can easily authenticate a user credential on AD using the code below:
bool valid = false;
using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
{
valid = context.ValidateCredentials( username, password );
}
If you want to validate using a local machine account you can change the constructor too:
new PrincipalContext(ContextType.Machine)
You can check the documentation for other options and additionally this will let you get all sort of information from the store like membership etc.
The new namespace was Microsoft attempt to simplify DirectoryServices which I think was successful but if you want even more control you could use the DirectoryServices classes but that would increase the complexity of the solution.
I hope this helps if you require further information or you think it is not quite what you are looking for let me know I will endeavour to improve the answer.
First, I'm afraid you're confusing authentication and authorization.
Authentication - proving a user's identity (like me presenting an ID when going to the bank)
Authorization - deciding whether an identity is allowed to perform some action (like whether the client "Nitz" can drain account #44422).
A Microsoft account can only provide you with authentication - the client will use some scheme to prove to your server that it belongs to bla#microsoft.com, and it's up to you to decide if it is allowed to do stuff in your application (authorization).
With domain accounts, you can use domain group membership to help with your authorization (it's even common in windows server applications), which you usually get "for free" with the user's authentication token.
Assuming I understood you correctly and you're indeed looking for authentication, you have to provide two behaviors - one for using domain authentication and one for Microsoft account authentication. This is because libraries and communication protocols are very different between the two.
Providing authentication
Using this this tutorial from Microsoft Azure's guys, you can set up a sample application / website combination that utilizes Microsoft account authentication.
To use domain authentication (kerberos / NTLM), you can follow this post and simply enable "integrated windows authentication" in your web site/service (I'm assuming it's IIS). If you're new to enteprise authentication, I'll shortly say that when set up properly (no time differences, AD issues etc.), the authentication is seamless. If there are issues, fall back to a simple "hello world" website and test it from Internet Explorer.
For each scenario, you best create a "hello world" method returning the user's authentication information, to make sure you got it right.
Providing authorization
with each authentication method you end up with a unique ID (Microsoft account: UserId. Domain accounts: SID). Your logic should translate this info to a set of permissions - e.g. Maintaining a table that has the ID in one column, and isAdmin in another. Your application should consult this logic when deciding whether to allow or deny an action from a client.
Combining enterprise and public
Since the methods to authenticate public users are different from the ones used for enterprise users, you'll probably end up with different IDs for the same user when connected from different methods (e.g. DOMAIN\bla and bla.blason#outlook.com). If you intend to provide both authentication methods at the same time, you have to account for that (for example, by creating a "user" table that has one column for Microsoft account IDs, and one for Domain SIDs). It usually makes little sense to provide both authentication methods at the same time, but it's your app.
Hope I helped!
Once i had the similar situation, (A client app need to connect to server with few identity credentials. after the custom authentication , a token will be grant for the client with few claims, then each client request will be validated against the given token) , if you are in something like this, consider this link, it helped me to solve the issue.
http://bitoftech.net/2014/06/09/angularjs-token-authentication-using-asp-net-web-api-2-owin-asp-net-identity/
Note: you can implement custom authentication, and authorization by extending claimsAuthenticationManager and Claimsauthorizationmanager respectively

What is the potential security risk of including the db password in the web.config

The Entity data Model wizard says :
This connection string appears to contain sensitive data (for example, a password) that is required to
connect to the database. Storing sensitive data in the connection string can be a security risk. Do you want
to include this sensitive data in the connection string?
I have included the db password in many live projects, How risky is it?
It is all about minimizing your risk. Lets say a attacker found a way of getting a copy of the code from the server but not a way to execute code on the server:
If you stored the username and password in the code the attacker now has direct access to your database with the same privileges as your code.
If you used integrated authentication the attacker still does not have any way to get data from your database as he can not impersonate the user to perform integrated authentication.
If you use proper IIS encrption you must be able to execute code on the server itself (the encryption key is tied to the server not the code) to be able to get the username and password. So the attacker still would not have access to the database.
Risk is something only you can evaluate. Is it a test server in your bedroom that is not connected to the internet? Not much risk. Is it an internal company server for a small company without any real sensitive information? Maybe not much risk.
Is it connected to the internet? It's risky. It's always risky if you're connected to the internet. Why? Because the internet is not a safe place. It doesn't matter how big or small you are, you're a target. There are automated bots that roam the net looking for vulnerable systems and automatically taking them over. Then, they infect the systems with Malware to spread to your users. Or they sell your credentials to other hackers so they can use your servers for command and control centers for spam networks. Or any number of other situations.
If you're on the internet, you are at risk. Period. So always take security seriously.
It comes down to how secure is your domain and IIS on your web server? IIS and web.config is at the root of your web application. If you have problems with domain security and people being able to access your inetpub or wwwroot directories and their children, then your website is always at risk. If you are using a third party provider such as go daddy or 1 and 1, they are relatively secure.
If you are hosting it yourself, you want to limit access, especially directory listing privileges. You want to mitigate permissions as much as possible. Also with your SQL Account you use for your web applications, limit database privileges and mitigate access as much as possible. Also do not use generic accounts for access, and have each web app with their own account. In a domain, you want to make sure you take the necessary precautions in your DMZ to help secure that web server if it sits on the edge of your network.
Internal threats are more prevalent than external threats. Those already on your domain with elevated privileges may already have access to your root of your web application without you even knowing it! Keep an eye on your delegate accounts, too that IIS uses for web apps and web services.
You should encrypt the connection string using aspnet_regiis Take a look at this link too (How To Encrypt web.config), for some useful information.
With regards to other aspects of the web application, you need to make sure you are setting the least privileges possible, making sure you research all web application vulnerabilities and how to protect against these.
Replace user name and password with Integrated Security in the Connection string.
Ensure that the process using the connection executes with a user that has been registered on the SQL server with (just enough) privilegies to perform its tasks. This should minimize the risk of your system being compromised.

WCF: Configure roles to access database resources

I have a WCF service set up on the web server. This service, when accessed, does some database operations. What sort of account (roles and permissions) should this WCF service have to interact with the data base and how the same can be created. Is network service the way to achieve this?
This service will be accessed by vast group of users and these users will be having varying levels of restriction. How should i go about implementing this in a most secure and robust manner??
Thanks in advance.
Well, this depends on many factors.
You have to first answer at least those two questions:
who is responsible of authentication: your active directory (user valid against AD), the database (SQL Server user), or do you use a custom authentication system (User table in your DB)?
who is responsible of authorization: your active directory (user group), the database (SQL Server roles), or do you use a custom authentication system (Role, UserRole tables)?
When you answer those questions, that are related to the way you want to manage security (not how to actually implement this with WCF), then you can find a way using WCF.
More specifically, you'll have to choose the WCF security configuration for authentication:
Message vs Transport security
Windows (great to integrate your application in an AD)
Username (login + password)
...etc.
Then a role-based authorization provider, if any:
SqlRoleProvider (SQL Server roles)
Windows groups (for Windows domains)
custom
etc.
So you have to make some choices first, then I recommend you to read this MSDN article to choose the security configuration to use, depending on how you expect managing authentication and authorization.

Should we develop a custom membership provider in this case?

Summary
Long story short, we've been tasked with gutting the authentication and authorization parts of a fairly old and bloated asp.net application that previously had all of these components written from scratch. Since our application isn't a typical one, and none of us have experience in asp.net's built in membership provider stuff, we're not sure if we should roll our own authentication and authorization again or if we should try to work within the asp.net membership provider mindset and develop our own membership provider.
Our Application
We have a fairly old asp.net application that gets installed at customer locations to service clients on a LAN. Admins create users (users do not sign up) and depending on the install, we may have the software integrated with LDAP.
Currently, the LDAP integration bulk-imports the users to our database and when they login, it authenticates against LDAP so we dont have to manage their passwords. Nothing amazing there.
Admins can assign users to 1 group and they can change the authorization of that group to manage access to various parts of the software.
Groups are maintained by Admins (web based UI) and as said earlier, granted / denied permissions to certain functionality within the application.
All this was completely written from the ground up without using any of the built in .net authorization or authentication. We literally have IsLoggedIn() methods that check for login and redirect to our login page if they aren't.
Our Rewrite
We've been tasked to integrate more tightly with LDAP, they want us to tie groups in our application to groups (or whatever types of containers that LDAP uses) in LDAP so that when a customer opt's to use our LDAP integration, they dont have to manage their users in LDAP AND in our application.
The new way, they will simply create users in LDAP, add them to Groups in LDAP and our application will see that they belong to the appropriate LDAP group and authenticate and authorize them.
In addition, we've been granted the go ahead to completely rip out the User authentication and authorization code and completely re-do it.
Our Problem
The problem is that none of us have any experience with asp.net membership provider functionality. The little bit of exposure I have to it makes me worry that it was not intended to be used for an application such as ours. Though, developing our own ASP.NET Membership Provider and Role Manager sounds like it would be a great experience and most likely the appropriate thing to do.
Basically, I'm looking for advice, should we be using the ASP.NET Membership provider & Role Management API or should we continue to roll our own? I know this decision will be influenced by our requirements so I'm going over them below
Our Requirements
Just a quick n dirty list
Maintain the ability to have a db of users and authenticate them and give admins (only, not users) the ability to CRUD users
Allow the site to integrate with LDAP, when this is chosen, they don't want any users stored in the DB, only the relationship between Groups as they exist in our app / db and the Groups/Containers as they exist in LDAP.
.net 3.5 is being used (mix of asp.net webforms and asp.net mvc)
Has to work in ASP.NET and ASP.NET MVC (shouldn't be a problem I'm guessing)
This can't be user centric, administrators need to be the only ones that CRUD (or import via ldap) users and groups
We have to be able to Auth via LDAP when its configured to do so
I always try to monitor my questions closely so feel free to ask for more info. Also, as a general summary of what I'm looking for in an answer is just. "You should/shouldn't use xyz, here's why".
Links regarding asp.net membership provider and role management stuff are very welcome, most of the stuff I'm finding is 5+ years old.
Security in the context of your problem involves two separate operations: authentication and authorization and those are divided in .NET into MembershipProviders and RoleProviders. I would strongly recommend using both (meaning custom or built-in) to do your authentication and authorization. Doing so, provides a path to upgrade should you later find better tools to do the job and makes it easier for other developers to understand the security.
Now, for authentication, I would, as others have stated, use either the SqlMembershipProvider or the ActiveDirectoryMembershipProvider. My experience has been that in 99% of the cases the ActiveDirectoryMembershipProvider provides enough functionalty for what is need when working against a full AD store (i.e. not ADAM aka ActiveDirectory Application Mode). I have had problems with the ActiveDirectoryMembershipProvider in multi-domain situations but in general finding a way of using it rather than rolling your own is much better. Similarly, the SqlMembershipProvider for authentication, works well and scales well.
Authorization however is an entirely different kettle of fish. This is really where your pain will be felt. First, there is no "ActiveDirectoryRoleProvider". That means if you want to integrate with AD groups, you have three choices:
Use AzMan
Do it yourself via a custom RoleProvider
Find someone that has done it for you.
Use ADFS or Microsoft's new Federated Services
Choice 1: AzMan
AzMan (Authorization Manager) (See also Windows Authorization Manager) is a tool Microsoft wrote to manage application authorization. AzMan has some nice features to it:
It can link your roles to AD groups (or Windows groups)
It can be stored as a file so you can keep it with the application.
Nicely breaks up authorization into tasks, operations and roles.
Comes with a separate administrative tool
The 2008 version will interact with SQL authentication stores.
The catch is that AzMan can be a bear to develop against and understanding the tool is not for someone that isn't experienced. I found that documentation was scant but that was a few years ago. In addition, the AuthorizationStoreRoleProvider does not support Tasks even though AzMan itself does. Tasks are the most granular things that can be done and are group into Operations which themselves can be grouped into Roles into which users or AD groups can be dropped. Documentation has gotten a little better. I do know that when I last worked with AzMan, it's lack of inherit interaction with a database authentication store made it a bit of a pain to work with.
Choice 2: Write your own RoleProvider
This can be a painful experience with LDAP. You would only need a custom RoleProvider in the case where you wanted to query against AD groups and did not want to use AzMan if you planned on using the SqlRoleProvider in non-AD environments.
Another alternative which I have used, is to manage roles in the database and allow the MembershipProvider to be whatever it wants. This still entails writing a custom provider (but a significantly simpler one) and it makes it easy to move the application into an AD environment with little mess. If you store roles in the database and if you want to allow administrators to associate multiple levels of groups to your roles, then you'll have to write that into your custom RoleProvider.
If you plan on using the SqlRoleProvider you also can run into a few issues. If you use the SqlRoleProvider with the SqlMemberProvider in a single application environment then it will work quite well and is very easy to setup. However, if you have multiple applications that you want to authenticate against a single store, then the SqlRoleProvider will not work properly in all cases out of the box without modification.
Choice 3: Find someone that has done it for you.
Specifically, I mean find someone that has developed an ActiveDirectoryRoleProvider. You can easily Google for various choices but I have not used them and would want to pour over any code that anything to do with security in my application.
Choice 4: Active Directory Federated Services
Microsoft has really been pushing this solution which does promise single sign-on if you can get it working. The catch to this solution is getting it setup especially between you and a partner.
I have been very please with the ease of the Membership Provider and Role Provider classes. They just work. The best part in my opinion, is that for my local development, I'm using a SQL Provider to logon to the local database which has the same user names as some of the people I want to test as (Admin, advanced user, basic user) with generic passwords. Then, when I publish my application, it uses the ActiveDirectory Membership Provider and integrates seamlessly. I don't have to change one piece of code for access restrictions. (Except for the differences between my web.config files)
With your situation, it does seem best to write your own custom provider, simply because you want to discover the user in your database but compare their password to LDAP. Also, these seamlessly integrate with both Webforms and MVC.
I would recommend Scott Mitchell's Multipart Series on the providers. Very extensive and thorough.
Also I would add that just because some of the articles are old, doesn't meant they don't still apply. The membership provider framework has been out for a number of years now, so it makes sense that some of the articles are gathering Ethernet dust.
I'm dealing with some of this same stuff so I'm going to start this answer with just a little bit and hopefully build onto it over time.
A quick answer is that, given your requirements, I'm going to suggest that you might want to research the TWO built-in providers that Microsoft makes available to you: SQL Server-based and Active Directory-based. Out of the box, with just the flip of some configuration in your .config file, you can flip the switch from using SQL Server to using Active Directory. Unless I'm misunderstanding your needs, it may sound like this is exactly what you need in your two scenarios. If you do it this way, 100% of your application can look and function identically, even with the same codebase. Migrating data from an existing application of one deployment to the other gets more interesting (and I have no experience with that, unfortunately), but clean deployments of one versus the other should be pretty simple.
Now obviously, if you don't like the behavior of the built-in providers, you can create your own.
Where I am at in my work is that we have been using the SQL-based provider and we need to move to Active Directory and the built-in provider may or may not be sufficient for our needs (I am still evaluating that, and very active in doing so at the moment). I have also worked with some proof-of-concept code so that, in the case that we need to, I have confidence that we can create our own provider reasonably well.
So I know that this is not exactly an answer to your question(s) but I hope that this gives you something to think about for now and helps you in some way. Like I said, I'm happy to add more to this as I grow in knowledge here myself.
FYI material
[How Do I:] Create a Custom Membership Provider? - Video Tutorial from ASP.Net official site. A very nice introduction into the topic.
Simple LDAP Membership Provider - Forum post of a very simple LDAP membership provider.
GPL .Net LDAP Membership Provider - It's GPL, so it may not work for commercial applications. Also hasn't been worked on in a while. But I guess it's still worth mentioning.
Notes
You may have to fight the clients temptation to use LDAP as a database. Be strong! LDAP can be use for Authentication and even Authorization. But you may eventually need to store a lot more information. The only reasonable way to do this is to map your LDAP uid to a database user table and run off that. Your membership provider can make this transparent to the rest of your project. But the client must understand that although LDAP affords them single sign-on, it's shouldn't be used as a database replacement.
Personally, I would stick to the Membership API but try to write a performant backend. Maybe something of a little caching and automatically maps LDAP users to the database user table on the uid as a key. The nice thing about LDAP is it has quite a bit of support in .Net. You won't have to manage sockets, etc. unless you really want to. Due to this, my LDAP/directory access code is usually under a dozen lines per method easily. And that's often good enough for production.
Just to throw another idea into the ring - have you considered Federated authentication and Claims-based authorization? It looks like it may be a good fit for your scenario. Basically this enables you to decouple the authentication from your application into a federated service provider (think OpenID) that manages authentication and issues a token to your application. There are service providers available that will integrate with LDAP, AD, and other directory standards. ADFS (Active Directory Federation Services, formerly Geneva Server) is one example that links with AD.
When configured appropriately, properties that are associated with an identity, such as group membership, can be passed to your application as a "claim" that is associated with the identity - your application can do what it likes with the claim. The point is that your application can find out which groups a user belongs to, and other properties e.g. email address, by examining the claims that are passed within the token.
The advantage of federated authentication is twofold. First, you can integrate with any directory you like, not just LDAP, as long as there is a provider (or of course you can write your own provider). Second, it keeps authentication out of your application code so you can vary the implementation in the future to support different scenarios.
Check out http://msdn.microsoft.com/en-us/magazine/ee335707.aspx for an introduction to the Windows Identity Foundation (formerly code-named 'Geneva Framework'). Or check out the team blog.

Categories

Resources