Generate a token based on the windows user who makes the request - c#

I have searched all over for an answer to this, and not found anything that seems to answer my question. Which feels like it should be an easy one (but clearly isn't).
I have an API which authenticates using a token. This token I generate from my application - more specifically, I have a new Token Generation web call that will return a token. Currently, I pass in a cookie with the user and password information, and it uses this to identify who I am and what I should be allowed to do. This is all working absolutely fine and hunky-dory.
I am achieving this process by making the Token Generation use OWIN Cookie Authentication, which means that the cookie is read and the Identity is set. I am then able to use this identity to confirm whether the user is allowed to access the system.
What I now want to do is replace this Cookie Authentication process by authenticating against a Windows User (everything is windows based, and this will be an option so non-windows users can still use the cookie authentication route). But I cannot discover how to straightforwardly do this.
Note that I don't actually need to validate that the user is genuine or refer back to the AD at all. If you provide a windows user that matches a user in the system, you can log in.
So how can I - easily - get the requesting user into the Identity Name? Or is this not possible?

If you are looking for information on the current user accessing your program, assuming the program is running on the user's machine and is windows based, you can simply query windows for the user's username or any other publicly available information about the user.
Refer to https://learn.microsoft.com/en-us/dotnet/api/system.environment?view=netframework-4.8 for information on the Enviroment class and what it's features are.
If you could provide some code or further clarity I could help you further.

Related

How to obtain credentials for Http Basic Authentiction

I'm writing a C# application and need to scrape some information from an rss page that only offers Http Basic Authentication.
This seems to leave me with two choices
Ask the user to input their credentials into my app (which has trust issues as the app is then a potential middleman attacker?)
Get windows to insert the credentials on behalf of my app somehow (does this facility exist?)
All the examples I've seen on SO have the username/password hardcoded in the app or passed in as parameters from somewhere unspecified. My use-case is I'd like to give this app to people who may not want to trust it with their password.
How is this usually handled? Thanks
Short answer: It is not possible with basic auth. It is generally not possible with the OS a the trusted instance.
Long answer:
The proper way to solve this would involve a procedure where your application hands control to the OS (Windows), which then asks the user "Do you trust application XY to use your identity?". After user acceptance, your application would receive a security token which you could use afterwards to make your HTTP request to get the RSS feed. The problem is, that the site in question does only accept basic auth. This means, that the "security token" is the base64-encoded username and password. So the username and password would be exposed to your application anyway.
The second problem is that the OS and the RSS site have to share a secret (i.e. an encryption key not available to you or anyone else not allowed to log in site users), to enable the OS to issue a secure token that is trusted by the RSS site.
How the problem can actually be solved
The default, real-world example for the access of web resources with third-party software on behalf of the user without knowing his password is OAuth, see for example the Facebook login flow. (However, this requires the website/resource in question to provide third-party access. As your question indicates, this does not apply for your use case.)
The pattern employed is the following:
Prerequisite: You need to register your application with the RSS service provider to obtain an application ID and an application secret.
Your application redirects the user to the login endpoint of the identity provider.
The user accepts (or declines) the access of your application to his identity and data (e.g. the RSS stream).
The identity provider redirects to your app
Your application receives a token which can be used to make authenticated requests on behalf of the user. This may involve additional steps like exchanging the token for another.
Alternative Solution (does not answer your question):
Sometimes (protected) RSS feeds can be accessed via secret user-specific URLs. Of course, the user would have to provide your application with that url.

ASP.NET Manual user authentication

I am working for the DOD. The application they have requested is web based, and will be on their internal network. The request is for CAC authentication, which is easy enough... The remaining problem is authenticating a user. The CAC authentication is happening at the IIS level, so by the time the user gets to the application, all I am doing (or had planned on doing) is checking the ID on the CAC, and comparing it to a user table in the database. If the user exists (and has been approved), then they are off and running in the system. If they do not exist, then they are pushed to the registration screen.
Given my lack of experience with web development, I am unsure if I need to actually authenticate the user in some way beyond the CAC authentication, or if I can just manually assign roles to the user and let the roles dictate what can or cannot be done in the application. Windows authentication is not an option; while this application is internal for the military, it is accessible from different mil networks.
If I do indeed need to authenticate a user... this is where I run into trouble. I have not found anything that says there is a way to manually authenticate a user. I could use the standard ASP tables in the database, but it seems... messy... to include things that won't be used (meaning the password field would always be an empty string - why include it in the db if it isn't being used?).
Thanks in advance for any help... If there's links to where I can read more about the authentication process, those would be very much appreciated as will.
I'm working on several DOE projects that use the same idea. What we normally do for web applications is to enable Windows authentication on the app. This will allow pass-through of user credentials and keep out anyone without credentials.
I also like to add role based authorization into the mix and then use AD groups to allow/deny users on specific apps.

MVC authentication with additional user details

We are currently starting to use MVC and are now looking at authentication. .net Authentication isn't necessarily our strongest point, so looking for some advise or pointers.
Our current set up:-
Basic Windows authentication
system uses the authenticated user to query a 3rd party system to get their current roles
these roles are then stored in session variables and used when ever authorisation is required
Any additional user details are called upon as and when needed from various tables
What we'd like to achieve :-
Basic Windows authentication (perhaps create a forms authentication cookie on the back of it)
System users the authenticated user to query 3rd party system to get their current role/s,
These roles are stored within the cookie, and can be accessed via User.Roles etc
Any additional user details (i.e. user favourite colour) will be called on authentication and store against the user profile. The additional user details will be stored in a single table as key value pairs.
Is this the correct way to go about this? we're struggling to find any samples etc to match the scenario we are after.
unfortunately, we need to use this 3rd party system to access the roles, this is achieved via a web service call.
Are there any new advances with MVC 4 which could greater handle authentication with additional user details?
any help, or advise would be greatly appreciated. :)
Sounds like a perfect candidate for federated authentication. You could even use WIF (Windows Identity Foundation) which is now part of the Base Class Library.
In general, federated authentication consist of following parts: delegating the authentication to an external identity provider, consuming identity provider's response, persisting the identity locally (in a cookie perhaps).
WIF has solutions for all these concerns, it is built around the WS-Federation protocol. The really, really great benefit of this is that you can switch between different identity providers easily. This is something that you could consider useless, until you see it in action and immediately you start to create complicated business scenarios in your head.
Using WIF requires some knowledge and specific questions can be answered easily. However, until you get at least some basic knowledge, this sounds like a mumbo-jumbo. You should definitely start by reading a free ebook, Claims-Based Identity and Access Control from here
http://msdn.microsoft.com/en-us/library/ff423674.aspx
Just download it and start reading. I promise you'll immediately find answers to many of your questions and page by page you'll feel this constant "wow, so that's how it should be done!".
Just to provide a specific answer to one of your questions: user data can be persisted in the authentication cookie. If you stick with WIF's model of Claims, expressing arbitrary data is natural: a claim is a pair (claim type, claim value). This requires however to switch to SessionAuthenticationModule as forms authentication module could possibly produce cookies that are too large:
http://www.wiktorzychla.com/2012/09/forms-authentication-revisited.html
(the session authentication module has a special "session" mode where the large part of the identity is stored locally at the server in the session container so that the cookie is really small)
And yes, the federated identity model works with MVC authorization tags. Claims of type role are interpreted as user roles. The remote identity provider can then even set user roles and you can guard your MVC controllers in the usual way.
If you are lucky your 3rd party component might bring a Claims provider with it so you could use Claims based authentication and let the Claims provider supply the additional user data in form of Claims that you can use in your application. For a tutorial see this link. If you cannot access a Claims provider, the known security building blocks still work for MVC. So for your additional roles, you could create a RoleProvider that requests the roles and configure it in your application. You can then secure your controllers or actions with the Authorize-attribute.
In order to optimize the request for roles so that you do not have to request it from the 3rd party system over and over again, there are some alternatives:
As you propose in your question, you can store them in the cookie. But be aware that cookies are stored on the client computer and could be tampered with. So if you have a Forms authentication cookie that you can use, you could store it in the UserData of this cookie. This cookie is already encrypted so that users cannot change it easily. As you want to use Windows authentication at least in the first step, you do not have a Forms authentication cookie that you could use. In the context of security, it is always advisable to set up upon a widely used and well tested framework, so I'd not recommend to create a cookie of your own and store the roles there (though it wouldn't be a too daunting task in this specific case to encrypt/sign the cookie data).
You could also store the roles in a Session variable. Downside is that the session times out after a while and you'd have to be prepared for this case. On the other hand, session memory is located on the server so that it is not that easy for users to tamper with (and if they could, you'd have lots of other problems).
Another component you could use is the Cache on the server; though you'd have to be careful not to mix data for various users as it is shared among users, it is also located on the server and provides a more fine grained control on when the data are invalidated. So you could configure a time frame after that any user would be authorized with a new role set in case it was changed.
Your RoleProvider would need to implement the caching technology (Cookie, Session or Cache).
As for your last point regarding the user profiles, I can imagine that the User Profiles of ASP.NET 2.0 still work. I don't have any experience with it, so I can't give you a recommendation on whether to use it or not. On the other hand, these data don't seem to be too security critical so you can also store them in a cookie or session memory once the user has been authenticated.

How to get one login page for multiple systems?

I have four systems running on the same server. I want to let the users to log in once for all the systems. I made one user-management system to create users and edit them.
I tried to save in the session but it didn't help.
Any suggestions? I am working on asp.net.
There are two approaches.
Most resolve around the login happening at a central site, which then returns with an identity information field (login token) that the target site uses to retreive the user.
When you go to another site, the site redirects you shortly to the central site and if you are logged in (persistent cookie) you get back the identity of you.
Alternatively you can do a lot with referrers and playing around.
YOu want to do some research on the internet - what you loo kfo is "Single Sign On".
http://www.codeproject.com/Articles/27576/Single-Sign-on-in-ASP-NET-and-Other-Platforms
has some technical discussions.
Across complete separate websites (domains) you can read up on
http://aspalliance.com/1513_Cross_Site_Authentication_and_Data_Transfer
howw to do it - obviously shared cookies will not work there.
The best way to do this is with Federated Security. If you were using Windows Authentication then you could use Active Directory Federation Services (ADFS). In this model, users reference a Web application and the principal on the current thread is checked. If the value is null then information stored in the web.config will redirect the request to a login page automatically. This is assuming there is no a Windows security context, otherwise the user can be automatically logged in.
After the user is successfully logged into the environment, the principal on the thread is populated and a set of claims are issued that are specific for that user. Since the claims are associated with the principal and not with a specific application, they can be used across the board by any claims aware application.
If you aren't using Windows Authentication, you can still accomplish the same thing, the only problem is that you cannot use ADFS. Instead, you'll have to implement your own Identity Provider to replace ADFS. The .NET Framework does provide base classes and interfaces to help you accomplish that.
I would suggest looking into ActiveDirectory or any LDAP server for single signon to access all applications. If you cannot (or do not wish to) use LDAP, you could implement similar functionality (but with more development work/time spent) with any memory/disk store. If this is not possible, please share why as it might be useful to others.
Hope this helps.

Identify roles from Azure ACS

As we knew in Web got a lot of tutorial for Azure ACS, but most of it stop at inset simple ACS into website or application. Now, i wondering is that possible to identify and link up all the famous user oauth provider, and add them a new user in database then assign role to them ? After the process, they just simply click any provider then will bring them back to the same account ? Do you having such tutorial can share? Here is the process flow i want to make:
Window live + google + Yahoo + Facebook, one person may having all four account, but then i need their info also, then i create my cuatom data entering page and the problem is how can i link up ? How can withdraw the unique id to identify ? So i can recognize it..and assign role to it..
Question 1: how to link up ?
Question 2: how to identify in system?
Question 3: how to give role ? Not giving from azure admin page but through the code
Thx
There is one thing you should be aware of, when working with ACS (and with Claims in general) - you shall get to know the Claims.
Now, to the ACS specific question. Windows Azure Access Control service is not the magic wand that will do what you desire automatically. ACS is the easiest way to get working with Claims, and to work with only one set of specific claims, and don't bother with all different implementations of different protocols. In fact, what you work with, when creating browser based application, is WS-Federation protocol (and SAML token by default, but you can also use SWT token), and not OAuth protocol. The user uniqueness you get, when someone logs-in with your site, when using ACS is the strict combination of following two factors:
User identity
ACS namespace
The uniqueness you get is NameIdentifier claim (represented by: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier).
The first catch is that, say I am "john.doe#gmail.com" identified to your site through http://yourcompany.accesscontrol.windows.net you will get nameidentifier "X". When, I, the same "john.doe#gmail.com" identify myself to your site, through http://yourcompany-live.accesscontrol.windows.net/, you get nameidentifier "Y"! And this is true for all identity providers, which you link via your Access Control Service.
The second catch is: Live ID identity provider, when configured via ACS, will only give you a NameIdentifier claim. And nothing more.
Now to the questions:
Question 1: how to link up ?
The only feasible way to link up identities, is to built your own linking logic in your application. What I would do, is to stop using all the auto generated code and passive redirection to ACS, but to handle some of the Passive Federation manually. This would mean - I will watch out whether the user is logged-in or no. If not logged in, I will redirect the user to my own custom login page, where I will get from ACS the configured login options. When the user is logged-in, I will create an entry in my own user data base for that user. I will have fields (or linked table) for all possible identity providers that I would like to link up to a single user. Understand, I will store all the NameIdentifiers the user may have. Now, how will I link a user account. There may be different approaches. First, you must indentify the user to allow him/her to link an account. Then create let's say a "linkage ticket" with some unique ID (not GUID, to be easily remembered by the user). Show this ID to the user, and offer him an option to login with another provider (retrieve the list of privers from ACS). When user comes with another provider - show the field when one could enter the ticket. Check the ticket, and if it is valid - link to the existing account.
Question 2: how to identify in system?
As mentioned in answe one - you will need to have your own custom user database, where you will have one account per user, but that account will hold all the NameIdentifier claims, issued by the different authorities. Thus you will be able to uniquely identify the users with linked accoutns.
Question 3: how to give role ? Not giving from azure admin page but
through the code
In your architecture it will be very hard to maintain the roles in the ACS, because of the complexity you enter when requiring to link multiple accounts. I suggest that you keep user-role assignment withing the application database. The part that you have local user accounts, you will assign role(s) to each account.
Note, when I say local user account, I don't mean to support local login credentials, but just user profiles!

Categories