Identify roles from Azure ACS - c#

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!

Related

Generate a token based on the windows user who makes the request

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.

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.

Options for single sign-on between ASP.NET and MVC.NET solutions?

I have an ASP.NET solution that acts as the primary customer portal for my customers. On this website the users can log-in access their important financial information and more. The website uses a custom authentication scheme that checks the user's username (their email) and their password (salt-hashed) against a Users table in a local database.
I am building a new MVC.NET solution that is more of a web-app tool to be used by these same customers for ordering. I want to re-use the sign-on mechanism of the ASP.NET portal to authenticate users. The goal is to save the user from remembering two log-ins or even having to supply the same log-in twice.
What are my options for allowing users who sign on to the ASP.NET solution to then be auto authenticated to the MVC.NET solution? I've listed some ideas below but are these "bad" or is there a more elegant solution? I'd love your input.
Common Cookie I could create a common cookie that the ASP.NET site creates and the MVC.NET site looks for. But is that secure enough?
Token in Query String I could create a token id on the ASP.NET site that is stored in the local database and is then passed in the query string of the link to the MVC.NET site which takes the token id and validates it against the same database.
Hybrid A bit of both?
Other? Got a better idea?
I've recently done something quite similar (the major difference being that it was internal to the company rather than for external customers) using OpenId.
The implementation of OpenId for .NET is called DotNetOpenAuth which should be suitable for your purposes.
It did take me a while to implement; but it works very well, is very flexible, and extremely secure.
More information about openid (from Wikipedia):
OpenID is an open standard that allows users to be authenticated by certain co-operating sites (known as Relying Parties or RP) using a third party service, eliminating the need for webmasters to provide their own ad hoc systems and allowing users to consolidate their digital identities.
Users may create accounts with their preferred OpenID identity providers, and then use those accounts as the basis for signing on to any website which accepts OpenID authentication. The OpenID standard provides a framework for the communication that must take place between the identity provider and the OpenID acceptor (the "relying party").2 An extension to the standard (the OpenID Attribute Exchange) facilitates the transfer of user attributes, such as name and gender, from the OpenID identity provider to the relying party (each relying party may request a different set of attributes, depending on its requirements).
The OpenID protocol does not rely on a central authority to authenticate a user's identity. Moreover, neither services nor the OpenID standard may mandate a specific means by which to authenticate users, allowing for approaches ranging from the common (such as passwords) to the novel (such as smart cards or biometrics).
Oh, and if you'd like further encouragement, Stack Exchange uses it!
#Jmrnet: in response to your last comment:
Perhaps I was unclear. OpenId in and of itself is simply for validating credentials from one location to another (more or less). It's entirely possible to implement as an SSO model where users do nothing different whatsoever - they don't have to choose a provider, or register, or anything like that. For example, in my setup, the user enters a username and password in a web portal, and then clicks a button to launch another site being automatically logged in by OpenId. Nothing different for the user at all! OpenId can be used with any initial authentication model you can think of (note the bolded section in the snippet from wikipedia).
Take a look at SAML:
http://en.wikipedia.org/wiki/Security_Assertion_Markup_Language
It works using XML and supports encryption.
I am currently implementing two SSO solutions for the same project.
In one, we are interfacing with an external partner and are using SAML.
In the other, we are allowing logged in users access to our Sharepoint and using the "Token in Query String" approach, since we trust Sharepoint to access our membership tables. This approach is much easier than dealing with SAML tokens.
There are many methods you can use, Mansfied described OpenID and RandomUs1r described SAML. Also, you can store relevant information in localStorage or in the session. I believe you should store relevant information with session.
It is not safe to put this in the query string, because if I register and log in, I will see something like UserID=1234 in the URL. If I change that to UserID=1235 and the ID is existent, then I can do some things in the name of the other user. This is called identity theft, which should be prevented by any means possible. So you should never have this kind of info in your URLs. Also, if you store the id of the user, you should obfuscate it somehow. For instance if you store the value in local storage and instead of 1234 you store encrypt(1234, salt), then the consistency of user action will be maintained.

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.

ASP.NET Implementing "Act As" functionality when using Windows Authentication and Custom Role Provider

I'm trying to implement "Act As" functionality for an ASP.NET application while at the same time using Windows Authentication and a custom role provider. Essentially what I want to be able to do is:
Use Windows Auth to get the current user's domain account to verify they are an approved domain user
Use a custom role provider to get permission information from a SQL Server database.
Implement functionality to allow the admins of the application to be able to "act as" another user, without requiring them to actually log into the application as that user.
The scenario I'm trying to fulfill is that an application admin is attempting to assist a user with a problem and clicks the "act as" button to act as that user and see the application as they would see it. So the Role Provider would need to understand that the current user is acting as someone else and get permissions information for that user instead of the current user.
My plan was to implement an impersonation feature that would delete the roles cookie and add a value to a session variable indicating that the user is currently impersonating another user. As the session is not populated at the time that authorization occurs however, this isn't possible. I don't want to use cookies as I don't want this to cause a potentially persistent state on the admins machine (such that the admin couldn't open another window to the app and either act as another user or view their own data).
I can't find a good way (without cookies) to save the "Acting as user..." information given that the session is unavailable. I'd like to use the role provider, etc., so that I can leverage the built in security trimming in .NET. This all may simply be impossible, but I'm hoping someone out there has either tried this before or has a suggestion for something I can attempt to implement.
Thanks in advance!!
See my answer to a similar question here
The gist of it is:
The way I did this, which is admittedly a little crude, was to have an
impersonation table in my database which contains the logon name of
the user who is doing the impersonating and the logon of the user they
wish to impersonate.
I added some override code so that when the user first goes to the
page (it uses Windows authentication), it will check to see if that
user has an impersonation set in the table and then place this user id
in an object in the session state. If there was no impersonation, it
would place the actual user id in this same object.
To prevent me from doing things to the user's data as them, there are
two properties in this object, one for logon_name, which is what is
used by the system for content-customization, and another called
NameForLog, which is used when logging any actions. All actions I make
will be logged as me.
All areas on the site that display user-customized content look at
this session object, so they will always use the impersonated ID and
therefore always show me what the user is seeing. Beyond the first
page and the logging code, it doesn't even know that it is me it is
dealing with.
For your scenario, you could implement a roles provider and override GetRolesForUser to return the roles for the impersonated user plus some role that will allow the impersonating user to access the impersonation functionality for the purposes of turning it off.
You could even return the impersonated user's roles with the impersonating user's roles in order to give the admin user access to all of their own features as well as the user they are impersonating, it all depends how much this would affect the usefulness of the feature in your particular scenario.
I have implemented something similar...though not exactly like your scenario but pretty close.
Admin Login (Has one role like Admin)
Then admin is redirected to "Select Client" Page. Admin can search Client by ID, Name, etc. From the list Admin selects a Client. I store the client ID in a cookie.
I have custom RolesProvider that calls my custom GetRoles(loggedinUserid);
GetRoles(int loggedinUserId) method then determines the type of the user i.e. if it's Admin or non-admin. If it is admin then, fetch ClientID from cookie. Pass loggedInUserID, typdofuser and ClientId to the stored procedure that will return all roles for the admin + all roles for that ClientId and return to roles provider.
This way I have all my menuitems for Admin available as well as menus needed for ClientID.
Admin can go to "Select Client" page anytime and switch to another client. When they select a client, new ClientId will be stored in the cookie.
Now you have two options after this:
You can let rolesprovider call this upon every request or
Store the fetched roles in HttpCache and update this cache whenever ClientId is changed.
Hope this helps.

Categories