I'm new to WIF - sorry in advance if my questions seems to be very basic...
I have a 1 WebSite lets say localhost that require username/password authentication. Access to //localhost/ForSecuredClientsOnly should require only client certificate to access the site.
AFAIK client certificates authenticaion is handled by IIS, how should I handle this problem if I want to use STS?
My ideas:
Use 1 STS, set IIS to Accept certificate (not to require) and read certificate in STS and figure out whether user can access the resource.
I was reading through http://msdn.microsoft.com/en-us/library/ff359105(v=PandP.10).aspx and
http://blogs.msdn.com/b/eugeniop/archive/2010/04/03/wif-and-mvc-how-it-works.aspx but when I'm already logged in to //localhost and try to access //localhost/ForSecuredClientsOnly STS thinks that I'm a valid user.
I'm returning new Redirect result from ForSecuredClientsOnly (path from SignInRequestMessage, since user does not belongs to group X) but the realm is always: //localhost/ (probably it's expected behaviour and reason why user is authenticated ...)
Use 2 STSs and move //localhost/ForSecuredClientsOnly to //securedClients.localhost. I don't really like idea of having 2 STSs though
Have 1 STS and create to websites pointing to the same STS. I hope that then in STS I'll see that sign-in request is going from different realm and then perform either username/password of client certificate authentication? I would also prefer not to use that option since it's not ideal if I need to create new website per section of the site that requires different authentication.
Questions:
I would like to make idea number 1 working but how can I pass different realm depending on site subsection, I see that I can set HomeRealm property on SignInRequestMessage but how can I later read it in STS? (User.Identity.IsAuthenticated is always true in STS if I already logged in to //localhost).
Should I be using HomeRealm at all to distinguish between site sections?
If you have ideas what's the best approach to read and validate client certificate in STS please let me know. Currently I'm thinking that I should check whether certificate Thumbnail is one of the certificates that I'm allowing - store collection on client certificate Thumbnails in database?
I appreciate all your input.
I think it will be worth looking at the Starter STS community project at Codeplex.
Related
I want to create a web page, that will serve to authenticate users based on credentials I give them (user1, pswd1 etc).
Only after a user authenticated, he should have access to a few other web sites,
on different folders of the web server, but which have no server side code(otherwise it would be simple.)
The user should be allowed access to the other sites, e.g. based on his IP,
for 24 hours or another period, or while he has the authentication site open on his browser.
The purpose if that the user will not have to enter credentials on each site,
and will enter his credentials only once, or once a day.
Restrictions:
I don't want to modify the target web site javascript code at all, e.g. to query a web service.
The user should be granted access using any browser,
so I assume I cannot use cookies.
If I would develop such a mechanism on Apache,I could, for example, have the authentication site PHP code add a line "Allow from ip" to the htaccess file of each target web folder, whenever a user authenticated successfully.
The issue is that I don't want to develop it as I am sure a solution already exists, and also I need a similar mechanism for both Apache and node.js (although i can live with two different solutions)
What information does the user have to identify themselves? How do you guarantee the user is who they say they are?
The whole point of authentication is to establish the user is who they say they are and that may create a session so that users need not reauthenticate.
If you want the user to authenticate in a single location and then reuse that "session" or set of credentials elsewhere, what you are looking for is single-sign-on / identity federation.
For instance, take airbnb.com. I do not need to authenticate there. All I have to do is authenticate with a third-party e.g. Google or Facebook. As a matter of fact, SO works in the same way.
One of the standards behind this technique is called Open ID Connect. Look into that. If you are willing to dish out money, you can look into commercial solutions e.g. Ping Identity. There is an open source implementation provided by Mitre / the MIT. It's available here.
In fact it occurs to me I can use simple routing.
In the top level folder have php code that does the authentication.
If the user is authenticated, route/redirect to the requested target site,
based on the requested url.
The url should be for example http://mysite/site1, where the authentication code is in the folder mysite, and site1 is not directly accessible.
Perhaps I can use something like php-express to reuse the same php code on node.js.
I currently have a MVC4 home-grown secure token service (STS) that communicates with our own authentication database. All is working just fine with this setup. As a new feature I need to add the ability for single sign on (SSO) through ADFS2 for those users that are on the domain (bypasses the current un/pw screen, and they're just 'in'). To be clear there really are 3 different login possibilities that need to be handled: domain user (SSO), domain credentials (domain user not on domain entering their domain un/pw), and the original un/pw auth from database. Knowing what I know about adding web.config settings to the relying application to wire up the STS, how would I wire up both wsFederation passive redirect options (current redirect to STS for un/pw, and the ADFS option)? Is this something that would have to be handled in code, through an overloaded class such as WSFederationAuthenticationModule? What would be the best way to handle what I want? Any code examples? Thanks for your time!
You just have your login screen on your custom STS and two additional buttons, "login with ADFS" or "login as domain user". Both buttons are redirects to two other STSes your STS is federated with (your STS plays then role of either an Identity Providing STS or a Relying STS).
That is not very complicated. What you need is to create two SignInRequestMessages and using their WriteQueryString build two urls to two different STSes. Another way would be to use the WSFederationAuthenticationModule::CreateSignInRequest method.
http://msdn.microsoft.com/en-us/library/system.identitymodel.services.signinrequestmessage(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/system.identitymodel.services.wsfederationauthenticationmodule.createsigninrequest(v=vs.110).aspx
Consuming responses is tricker as you need a single uri (or two different uris) that play an endpoint roles. In the uri you need a token receiver and try to create a token out of the SAML sent by the provider.
If you peek at the source of a community replacement of the wif:FederatedPassiveSignIn method I wrote once, you will get the idea
http://code.google.com/p/net45federatedpassivesignin/source/browse/trunk/+net45federatedpassivesignin+--username+wzychla#gmail.com/Community.IdentityModel.Web/Controls/CommunityFederatedPassiveSignIn.cs?spec=svn6&r=6
(at least half of the code is responsible for the WebForms user control infrastructure but the other half is what you are looking for)
Unfortunately also, such custom mixed scenario is not easily handled with just the configuration of federation modules.
I'm trying to figure out how a site that accepts OpenID logins couldn't be hacked by a simple hosts file update to point to a bogus OpenID provider.
Lets say for instance I want to hack into Joe Smith's account and for this example, lets pretend his OpenID provider is http://jsmith.myopenid.com. What would prevent me from creating an entry in my hosts file, pointing jsmith.myopenid.com to an IP that I control. I would then fake the authentication and return a response saying that the user successfully logged in.
I know there would be an SSL mismatch warning in the browser, but since it's my browser I could easily ignore it. How does the requesting website know that the response it receives is actually from the site that was requested?
This seems like a basic attack, and I'm sure the people behind have included a solution for this, I just must not be searching on the correct terms to find the answer.
The relying party contacts the OpenID provider directly, either before authentication (to establish a shared secret key used to put an HMAC on the OpenID provider's response) or after authentication (to ask it to confirm the response actually came from the OpenID provider).
For your attack to work, you would also need to be able to control DNS lookups of the relying party, not just your own.
Looking for a pointer in the right direction ...
Is there a mechanism which allows you to configure SharePoint in such a way that:
if a user has been successfully authenticated within a SharePoint site that there is some kind of "authentication token" what can be passed or is available to 3rd party sites
or a way for 3rd party sites to "recognize" that the user is currently authenticated within a sharepoint environment
all 3rd party apps can be modified to accommodate whatever needs to be done
but the constraint is: SharePoint may or may not be a hosted (by a separate service provider) and how the original authentication took place is irrelevant i.e. just need to know they authenticated ok, not how
EDIT
scenario to help clarify:
authenticated SP users require access to a 3rd party service provider for additional content. a "link" on their SP site redirects through to the 3rd party. the 3rd party needs to recognize the referrer (based on a collection of evidence supplied by the request) so that it need not challenge for a secondary authentication process.
one of the 3rd parties is me. the SP instances are many and varied and would be any one of my clients (which i don't offer support to, just provide a content service to).
so the attempt is to solve more of a general "community/ecosystem" problem.
Going on the small amount of information available here.... You are probably going to use Windows Authentication (via Active Directory) or Forms based authentication.
If you are using AD within your organization and the other server you are authenticating to is using the same AD, it's a no brainer. If it's AD based but both servers are using different domains, it's much more complex. One option would be to setup a trusted share between the ADs.
If you are using Forms Based authentication it becomes a bit more of an issue. If both servers are using the same FBA, you could create the authentication cookie in SharePoint and then add the cookie as a header to a Request object and then redirect to the server.
If they are different authentication methods totally, you need to determine if your security requirements will allow users to authenticate via some URL based mechanism (like querystrings) and then develop the logic on your SP box to create the URL to authentication.
Your requirements are a little vuage but this should point you in the right direction.
Plan authentication methods (SharePoint Server 2010)
Specifically Claims based authentication.
I'm guessing that by "3rd party sites" you mean sites that aren't hosted in your domain. If that's the case, then the servers won't be able to use your AD authentication (unless you share them, which probably isn't worth it).
I would suggest modifying the way users are authenticated on the 3rd party servers, as you have control over how you send your users over there. You could easily encrypt their usernames/emails/unique IDs and a timestamp (to make sure they can't bookmark that link) in a query string.
The information is then decrypted on the 3rd party server. Invalid information and they are redirected to your login page. Valid information and the 3rd knows that they were authenticated in your sharepoint app.
Your question is very confusing.
SharePoint may or may not be a hosted
What do you mean by that?
Are you invoking a 3rd party web app from a SharePoint page? You can get the current user using SPWeb.CurrentUser property and make use of it.
I have a main website running on AppEngine. It's on a subdomain like main.example.com. This main application is a content portal for our customers. It offers an Ajax application built on YUI. Customers can upload data to it. Users authenticate using Federated Login.
The Ajax application on it allows users to process the data previously uploaded. To do it it should use an webservice running on other subdomain like service.example.com. The webservice does not run on AppEngine but on our services - it's CPU heavy and built on other set of technologies. It would need to download the data on main application - but the downloading service - like everything on the main application - is behind the authentication wall.
I could programatically always allow the service to download wharever it wishes but I think this can turn into a major security problem.
How can I reuse the OpenID authentication "token" to allow it (the service) to appears to the main application as the authenticated user so it can download data? Or If I can do this what would be the best way to accomplish what I intend to do?
You can't really reuse the authentication token. What you should use is something akin to OAuth, though since you control both ends you can make it somewhat simpler:
Generate a shared secret, accessible by both main.example.com and service.example.com
When a user accesses service.example.com for the first time (no authentication cookie), redirect them to main.example.com/auth?continue=original_url (where original_url is the URL they attempted to access)
When you receive a request to main.example.com/auth, first log the user in the regular way (if they're not already). Then, take their user ID or other relevant credentials, and generate an HMAC from them, using the shared secret you established in step 1. Redirect the user to service.example.com/finish_auth, passing the computed HMAC, the authentication details such as user ID, and any parameters you were passed in such as the continue URL.
When you receive a request to service.example.com/finish_auth, compute the HMAC as above, and check it matches the passed in one. If it does, you know the request is a legitimate one. Set an authentication cookie on service.example.com containing any relevant details, and redirect the user back to their original URL.
This sounds complicated, but it's fairly straightforward in implementation. This is a standard way to 'pass' credentials between mutually trusting systems, and it's not unlike what a lot of SSO systems use.