Hope you can help with this scenario. We have a browser-based support app that uses SignalR for customer chat. The solution comprises two web apps: admin.[domain].com and support.[domain].com. Both are C# ASP.NET CORE 3.1 MVC apps.
The admin app is used by the support engineers to service the chats. The SignalR hub is hosted within the admin app. The admin app uses ASP.NET CORE identity for authentication and authorization.
However, the support app has no identity mechanism - we need a "low friction" solution where the user simply connects to support.domain.com/{GUID}, no password required. The GUID is a SignalR group name pre-generated by the support engineer. Upon hitting this route, the support app calls AddToGroup(GUID).
The SignalR documentation states that Groups are not an effective security mechanism. However if the group names are GUIDs and we never send to all clients, then is this a reasonably secure approach?
Messages are only ever sent or received within a group. The GUID makes the Group Name very safe I would have thought.
Can the chats be eavesdropped easily if the group name is an unknown GUID? Is there a better/more secure alternative to this approach, without having the client enter a password?
As you correctly said, the groups are not a security mechanism. But in your case, what you want to do is fine because, as long as a user connects to the Hub, and the groups management is made by the admin, after a chat session the admin can remove the group so the user can't join it latter.
You need to make it clear that this is a public session like you can see in apps like whiteboards where users can join if they have a invitation link.
I also would recommend implement some ttl mechanism to groups expire after a while to user don't join a session latter.
At last, just do some defensive codding like, allowing only be 1 admin and 1 user in each group at a time, etc...
Related
What is the best method of securing a REST Web API with the following requirements. The system has an Angular JS frontend with the REST APIs implemented in ASP.net.
There are two "roles" in the system, users will have one of the
roles. One role should allows access to some APIs (call it "VIEW"),
the other role allows access to other APIs
All users are in Active Directory, so if I have a username, I can check what role they are in- Some clients are on Windows boxes, the others are on Linux
I would like to persist the session so I don't have to look up AD for every API call
I would like single sign on. On the Windows machines, I don't require them to enter user and pass as I already can retrieve their username using Windows Authentication.
I believe that Oauth would be my best option.
There are two "roles" in the system, users will have one of the roles.
One role should allows access to some APIs (call it "VIEW"), the other
role allows access to other APIs
For role based authentication, you can use [Authorize("Role" = "Manager")]. The token will be provided by the identity server and will contain the claim as Role.
All users are in Active Directory, so if I have a username, I can
check what role they are in- Some clients are on Windows boxes, the
others are on Linux
If you have ADFS then you can have an Identity server that trusts the ADFS. The ADFS will provide a token which will have the claim for role and your Identity Server will do the claims transformation and will return the same Role claim back to angular app.
I would like to persist the session so I don't have to look up AD for
every API call
For this while requesting the token, you can ask for offline scope so the Identity server will provide the Refresh Token with Access Token so you don't need to ask for AD again and again.
I would like single sign on. On the Windows machines, I don't require
them to enter user and pass as I already can retrieve their username
using Windows Authentication.
For this one, you can have your Identity sever trust the WSFederation for windows Authentication.
So basically you need to setup Identity server that will provide you with the token and the REST API will use that token to verify claims to return the correct information back to the user.
I am not sure what you expect exactly. Anyway, first I'm gonna reformulate your question with requirements:
you accounts and role are in active directory
you want to manage roles based on an active directory group
you want anybody whatever the system (windows, linux, mac, mobile...) to connect on your application using the same authentication
you want to avoid your AD to be hit constantly (not at any call for example)
if the user is connected on an application that uses the authentication system, he doesn't have to do it so again on another application that uses the same authentication system
If these requirements are yours. I believe the only standard (and clean) solution is to use OAuth. I'm not gonna go in detailed description of OAuth, but this authentication protocol is the most standard one on the net (facebook, google, twitter...). Of course as you don't want to use facebook, google or twitter accounts in your business applications but your active directory accounts you'll have to install/setup/develop your OAuth identity provider using accounts of your active active directory server. Your choice will depend on how well you know ADFS protocol and its different flows (code, implicit, assersion) You have two solutions for it:
Use ADFS: install ADFS; it provides a OAuth portal that will work out of the box with asp.net mvc. This uses the code flow of OAuth that is the only OAuth flow supported by ADFS. For roles and its related AD groups, you'll have to map role claims with AD groups. (it's in the setup of adfs, you'll find many tutos on the net). You'll find lot of tutos as well about how to use ADFS with asp.net mvc/asp.net webapi. I mention .net here, but every technology has an implementation for OAuth authentication (nodeJs/express, php, java...).
Use thinktecture identity server (.net technology). This will provide all the foundation to implement a custom identity server with the least effort: http://www.thinktecture.com/identityserver / https://github.com/IdentityServer/IdentityServer3. It contains an addin to plug its accounts to active directory. With this, you can use implicit and assertion flows.
Use oauth2orize (for nodeJs): https://www.npmjs.com/package/oauth2orize. This will permit you to make the same than thinktecture identity server but in nodeJs. Apparently you'll have to make all the wirering with ad manually. With this, you can use implicit flows (not sure about assertion flows).
At application side, most of frameworks can authenticate easily using OAuth with a lot of existing frameworks. For example, even if you make a single page application, you can use adal.js or oidc.js for angular if you use angular. As I mentioned above, all this is taken in charge by asp.net mvc/webapi out of the box but I know it's the case for other server technologies. If you have more questions, don't hesitate as I'm not sure of what you expect exactly.
We have a hosted .NET web application (Windows Server 2012 R2 environment) and we need to provide Single sign-on (SSO) to users from a corporate LAN environment. We have used ADFS to enable SSO and it is working as expected thus when a user hits our web application login page URL he is authenticated against ADFS and is automatically logged in to the application.
We have an additional requirement where we need to obtain a list of all users, their groups, email addresses some additional information periodically from their Active Directory so that this information can be bulk loaded into our web application however since ADFS is implemented we do not have direct access to the Active Directory.
Is it possible to connect to ADFS and obtain a list of all users, their email addresses etc. programmatically?
If the above is not possible then what is the recommended approach for this kind of a setup?
Thank you.
No, this is not possible. There is no such API because with SAML and WS-Federation, users can come from anywhere. This does not have to be AD, technically it's possible create a "Log in with Facebook" implementation.
What would you need the information for? The user's claims contain all information which you might need (user name, e-mail address, group memberships).
If you really need that information about all users in your application, perhaps ADFS is not the solution you are looking for.
As Alex mentioned above - the way it works, ADFS does not provide any way of importing data from the AD or other trust stores. It just gives you the information that are carried over with the token.
In case you need more information, you should extend the number of claims being issued by ADFS. You can then collect the information - when the user comes for the first time, use the data from the token and fill the profile. If it is returning user - update the information if necessary.
The other solution (but I wouldn't say it's recommended - rather a workaround) would be to implement custom solution for importing information from AD to your application. I'd say it's fair as long as you use your local AD for reading this data. In the moment you decide to extend the access to third party (e.g. partner company), which might be using different identity provider, which doesn't have to be backed by Active Directory any more - you find yourself in tough spot.
I am currently evaluating possible Identity Management (IdM) solutions that enable single user identity store and SSO across applications.
I am leaning heavily toward Thinktecture IdentityServer v2, but I am not able to validate that all of the following requirements can be met with it.
I am also familiar with and have used the MembershipReboot project as a replacement for the ASP.NET Membership Provider. I like it that MR provides a lot of the self-serve and pwd mgmt requirements I'd need, but I don't fully understand how this would "fit in" with IdentityServer - and by that I don't mean the actual implementation of the I*Repository interfaces, but rather from a high level architecture.
Would someone tell me which of the following are (or are not) possible with it, and perhaps provide other options that may better address these requirements?
Support for ASP.NET (WebForms and MVC)
Maintain central user identity store
Self service password management
Password policy configuration
Ability to authenticate both AD users as well as user in SQL store (centralized)
store (forms) - this means we want to have some internal users (AD) and some custom (forms/sql) users in the same application
Customization of pages (e.g. login, self service, etc.)
Roles/Claims management specific to each application (I know this is
Authorization, not Authentication, but I need to understand how to
manage app-specific claims related to central user identities)
Permissions management (not sure if this should this be in app, or centralized)
SSO across different domains
Support for token standards like SAML 2.0, JWT, WsFed
Open Source, or Low Cost
Extensible (lower priority)
Any suggestions/recommendations or comments based on the above requirements?
If you're using IdentityServer then you're doing single sign-on. This means your app can be any tech as long as you have a library that can handle whatever protocol your IdP supports. IdentityServer v2 supports WS-Fed primarily for browser-based applications. IdentityServer v3 will first be focused on OIDC (OpenID Connect) but will eventually also support WS-Fed.
MembershipReboot is an identity management library. This means it stores things like passwords and other identity data for your users. It can be used by both IdentityServer v2 and v3.
Most, if not all, of the things you list can be achieved with either platform. Some will require custom coding on your part.
IdentityServer v3 will be in alpha very soon.
We are running a Saas ASP.NET 3.5 Web application using Forms authentication on a IIS 7.5 public server with protected content for thousands of users. We also have some subapplications running ASP.NET MVC 2.
Usernames and passwords are stored in our database and every user has roles and groups attached, with privileges and access rights defined.
Now we have been asked to also facilitate for simple SSO login via Active Directory so that users do not have to enter username and passwords twice to login. These users will originate from different networks and domains.
No user "sync" should take place from our servers to LDAP serves. We are not sure that any communication with LDAP is needed since all users will be created in our system and maintained there. Forms authentication will be used for most of our users.
From here on we are unsure which is the best path to choose. For our scenario what would be the "best practice" way to proceed?
The simple answer is SAML. It is considered the "best practice" and many large SAAS providers support it.
SAML protocol defines the single sign on flow between multiple systems. It establishes trust between systems using certificates. Your application accepts an assertion containing attributes (user id, name, email address, etc.) from other systems. Your app will map the user into your user store.
In .NET world there are several options. You can find a library that implements SAML (ComponentSpace has one) and hook it into ASP.NET authentication. You can create your own using Windows Identify Framework (WIF). Here's the boatload of WIF videos http://www.cloudidentity.com/blog/2010/06/23/ALL-WILL-BE-REVEALED-7-HOURS-RECORDINGS-FROM-THE-WIF-WORKSHOPS/. You can try IdentityServer http://thinktecture.github.io/
Depending on how secure your app must be, you can opt for a simple option of passing user id from trusted networks using a simplified method. I've seen apps that allow user id to be sent via URL parameter or form field. Of course, this is horribly insecure, and you are taking on more risk, because the trust between two networks is not cryptographically enforced. You can mitigate it somewhat by checking referrer string or IP address (if you can isolate IP range of a corporate network for example). But you are still open to spoofing because any user can impersonate others by simply replacing user id within HTTP request.
It probably doesn't answer your question fully, but hopefully points you in the right direction.
I recommend looking into ADFS 2.0 it is very powerful in terms of claims mapping and works with AD: http://msdn.microsoft.com/en-us/magazine/ee335705.aspx
What you would make is a token consuming portion of your app that would receive and parse the final claims returned to your web server after the authentication loop.
I have a fairly complex business application written in ASP.NET that is deployed on a hosted server. The site uses Forms Authentication, and there are about a dozen different roles defined. Employees and customers are both users of the application.
Now I have the requirement to develop a Windows Mobile client for the application that allows a very specialized set of tasks to be performed from a device, as opposed to a browser on a laptop. The client wants to increase productivity with this measure. Only employees will use this application.
I feel that it would make sense to re-use the security infrastructure that is already in place. The client does not need offline capability.
My thought is to deploy a set of web services to a folder of the existing site that only the new role "web service" has access to, and to use Forms Authentication (from a Windows Mobile 5/.Net 3.5 client).
I did see this question and I am aware of the limitations that Forms Authentication poses. Since security is not my primary motivator (I use SSL and can restrict access by IP address), but rather using existing user accounts and roles, my decision tree is somewhat different as well.
Can I do this, is it a good idea, and are there any code examples/references that you can point me to?
I ended up with a combination of things. First, forms authentication does not really work in this scenario, because of the redirects that you get when a users is not logged in or the credentials are incorrect.
Because I want to use the user accounts from the web app, I worked around this by just calling Membership.ValidateUser prior to processing each service call on the server.
A user is prompted for an id and password when logging on to the client. I store both values encrypted in the proxy class and pass them transparently with each call using a host header, so that the application does not have to bother with this once the user is logged in, i.e. the credentials were validated once by calling the Login() service method (which only calls Membership.ValidateUser).
I use the CryptoApi on both the server and the client side.
I understand that host headers are somewhat outdated for security applications, but since I use strong encryption AND SSL, it is perfectly adequate.