I have an asp.net mvc 3 web app that needs to support SSO from multiple STSs based on the subdomain the user requests.
So requests for https://weylandyutani.mydomain.com should trust the Weyland-Yutani STS and https://tyrell.mycomain.com should trust the Tyrell STS.
Most WIF resources talk about enabling STSes in the application's web config. Is there an accepted way to do this dynamically without reinventing the wheel?
In scenarios like this, you would typically use an intermediate STS (referred to an "RP-STS" or "Federation Provider" that will handle all trust relationships for you. That is: your app trusts the RP-STS, then the RP-STS would trust Weyland-Yutani, Tyrell, etc.
Adding an RP-STS simplifies things quite a bit, especially if each of the identity STSs send you claims that are all different from what you require in your app. For example: Tyrell might send you "name", "lastname" and "e-mail". Weyland might send "Username", "e-mail". The RP-STS would normalize the claims set to whatever your app needs.
The way you hint the RP-STS where to redirect the user is through the whr parameter (which stands for "Home Realm"). Your app would look at the request URL and then append the whr parameter before redirecting to the RP-STS.
All the above is extensively documented in the "Federation with Multiple Partners" chapter of this book.
If you don't want to build/acquire and deploy your own RP-STS (depending on the deployment model of your app, you could use ADFS v2.0 for example), you could use Access Control Service from Windows Azure.
This other chapter explains how it would work.
Related
We have 2 web applications in production since several years. They are currently only accessible from the intranet of the company. Future changes in the company's organization require to make these applications accessible from the internet. It is planned to use Okta to reinforce security. I don't know nothing about Okta yet. As far as possible, the changes should have as little impact as possible.
Current situation:
Web App 1:
ASP.NET MVC solution secured with userid/password ASP.NET Membership with forms authentication. Userid is an internal user code like ADE465 for example.
Web App 2:
ASP.NET MVC solution secured with userid/password authentication through IdentityServer2 (Thinktecture). Userid is firstname dot lastname like john.doe for example.
All web apps are hosted on IIS on an Azure virtual machine named (let's say) FABVM03.
For the future Okta integration: no need to have SSO (Single Sign On). Would it be possible to simply secure with Okta everything accessed on the server FABVM03? Or everything accessed from a specific URL ?
For example, if someone tries to access https://example.com/webapp1/login.html Okta should comes up and ask for authentication (Okta verify) and if successful allow the user to access the requested url. In fact, the 'already in place' login/password should then be asked as it is already the case. I agree the user would have to enter credentials 2 times: first for Okta verify, next for login the specific web application. But that's okay. As you will have understood, no code modification in the web apps would be necessary in this scenario.
My question is to know if something like that is possible with Okta. If not what is the less impacting possible solution with Okta ?
Okta is not to enforce your policies (PEP), it's mainly SSO and Access Management solution.
Okta has a component, called OAG (Okta Access Gateway), which can be used to reverse-proxy your on-prem applications (which will work in your situation too, as your VPC is effectively equal to "on-prem in a cloud"). Which can do something like you want (protect your application and ask for authentication/authorization), but it's an additional package on top of basic Okta costs.
What you may need is a level of protection added on Azure Network layer, not sure if there is something like that though. I've seen some modules for nginx, capable of intercepting traffic and redirecting it to Okta, if not accompanied with a token. So try to dig into these 2 directions...
You need some proxy-based solution to talk to Okta and enforce the protection for your applications. There are open source tools:
https://github.com/vouch/vouch-proxy
https://github.com/oauth2-proxy/oauth2-proxy
https://github.com/buzzfeed/sso
Or you can checkout some commercial tools:
https://www.okta.com/products/access-gateway/
https://www.datawiza.com/platform/
I am working on an asp.net mvc-4 web application and I have started implementing some web services which provides statistical information about my site. But to make sure that only authorized and authenticated consumers can call and consume the web services I am thinking of defining a master login username and password for each consumer, and when a consumer sends a web service request he should include these master login username and password (stored as a hash value ) in the web service calls.
For example the web service link to call specific web service from my web site will look as follow:-
/web/json/statistic/getsummaryinfo/areacode?j_username=masterusername&hash=D012B772672A55A0B561EAA53CA7734E
So my question is whether the approach I am following will provide a secure solution to my web services and to the consumers? OR my approach have security holes I am unaware of ?
:::EDITED::
I am using the WebAPI controllers to implement the web services inside my asp.net mvc-4.**
Best Regards
There are a few ways to make sure things are secure.
http://techcrunch.com/2012/11/08/soa-softwares-api-management-platform-and-how-it-compares-to-its-sexy-counterparts/ This article just came out today highlighting some API tools. I'm not sure how big you are or are planning to be, but if you're looking for scale, these tools seem to be pretty popular (note: I haven't had a large scale API project myself, so I haven't used these).
You can use something like ServiceStack to build your API layer. It has authorization and authentication built in with a boatload of authentication providers. It scales well and, after a call to authenticate, is session-based so you don't have to authenticate each call.
You can use "signed" requests. Signed requests often look something like: "take all the parameters for the request as a querystring, append a 'secret consumer key' to the end of the request', and then sign the request by appending the md5 hash of the results (without the secret key!!) to the request." This is a safe way of doing things because even if the request is made client-side (AJAX) it is generated server-side using a secret key. So you can ensure that things weren't tampered with.
You can go the oauth/token route (which often still uses method #3 above).
You can go with a simple API key that can be revoked (again, fotne used with method #3). bit.ly uses this method I think.
Option #2 is my favorite. I like ServiceStack. But to be honest the learning curve for your first project can be a little steep.
A master username and hashed password feels weak to me, so I'd strongly consider at least looking around at how others are doing it.
HTH
I do not consider your way to be safe. If I could listen on the wire and cache the request I will have the login an the password to the service. There even does not matter if the password is hashed or not. I like the point 3. in Eli Gassert's answer. It sounds very useful and light weight and you are not exposing the password because it is hashed "somewhere" in the request.
I am going to have an ASP.net MVC web site (example.com) and a Web API site (api.example.com) running on the same domain. What is the best and most secure way to use Forms Authentication to allow a user to log in to the MVC site, and have that login accepted by the [Authorize] filter in the API site? Additionally, there is the possibility that both sites will be hosted on multiple servers (each of which might have its own subdomain), so a solution that would allow for a single sign on approach to work among all of the servers in the cluster would be preferred.
Take a look at this link http://www.codeproject.com/Articles/27576/Single-Sign-on-in-ASP-NET-and-Other-Platforms this covers the answer in detail.
You will need to ensure all machines and separate applications on the site share a common (but unique to production) machine key to allow the authentication cookies to be trusted by all the machines/applications.
If you are simply using virtual directories under the same sub domain then simply harmonising the web.conig Forms Auth settings and machine keys should get you up and running very quickly.
If you want this to work between a second level domain then you need to change the "Domain" setting on the Form's Auth cookie. See the article for details.
Like SO, I am gonna depend on many Open ID providers to provide user authentication and I will use my own authorization methods. but I'm still in development phase, and don't want to work with real OpenID providers currently, what approach can I use to test my users and their activities in the website (w/o TDD), to emulate real users but not really use Open ID providers.
No need to make auto-transfer of users into real OpenID servers (when moving to production mode) since the current users are just for testing purposes and Unit-test code.
I guess, I need a User Service layer which provides a higly abstracted way to deal with users, so that the move to the real Open ID providers can be smooth in the future and doesn't affect the logic of my already written code.
Using C#.Net 4, ASP.Net MVC 3, Ninject
DotNetOpenAuth provides both server and client portions of OpenID and can be used to run your own OpenID provider for local testing.
Give your site members their own OpenIDs with the provider support included in this library.
Sample relying party and provider web sites show you just how to do it.
I simply register my test id as user with various organisations. I don't see anything wrong with that. I get to see the various responses and their differences.
I found it terribly easy to code for openid consumer. Just need to understand the sequence of responses. Draw the UML sequence diagram to aid your understanding before you start coding. No need to fake openId. Otherwise, whip up an openid server yourself.
Your services shouldn't depend on OpenID. Just have OpenID plug into an authentication module to provide a local user principal. In development, you can have the auth module return a fake user principal with the permissions you desire.
In a beta environment you could turn on OpenID and use test accounts from any OpenID provider. Having to log in during the development phase will just slow down all the developers. Any authentication bug or internet outage will kill everyone's productivity.
Are there any decent examples of the following available:
Looking through the WIF SDK, there are examples of using WIF in conjunction with ASP.NET using the WSFederationAuthenticationModule (FAM) to redirect to an ASP.NET site thin skin on top of a Security Token Service (STS) that user uses to authenticate (via supplying a username and password).
If I understand WIF and claims-based access correctly, I would like my application to provide its own login screen where users provide their username and password and let this delegate to an STS for authentication, sending the login details to an endpoint via a security standard (WS-*), and expecting a SAML token to be returned. Ideally, the SessionAuthenticationModule would work as per the examples using FAM in conjunction with SessionAuthenticationModule i.e. be responsible for reconstructing the IClaimsPrincipal from the session security chunked cookie and redirecting to my application login page when the security session expires.
Is what I describe possible using FAM and SessionAuthenticationModule with appropriate web.config settings, or do I need to think about writing a HttpModule myself to handle this? Alternatively, is redirecting to a thin web site STS where users log in the de facto approach in a passive requestor scenario?
An example of WIF + MVC is available in this chapter of the "Claims Identity Guide":
http://msdn.microsoft.com/en-us/library/ff359105.aspx
I do suggest reading the first couple chapters to understand all underlying principles. This blog post covers the specifics of MVC + WIF:
Link
Controlling the login experience is perfectly fine. You should just deploy your own STS (in your domain, with your look & feel, etc). Your apps would simply rely on it for AuthN (that's why a app is usually called a "relying party").
The advantage of the architecture is that authN is delegated to 1 component (the STS) and not spread out throughout many apps. But the other (huge) advantage is that you can enable more sophisticated scenarios very easily. For example you can now federate with other organization's identity providers.
Hope it helps
Eugenio
#RisingStar:
The token (containing the claims) can be optionally encrypted (otherwise they will be in clear text). That's why SSL is always recommended for interactions between the browser and the STS.
Notice that even though they are in clear text, tampering is not possible because the token is digitally signed.
That's an interesting question you've asked. I know that for whatever reason, Microsoft put out this "Windows Identity Foundation" framework without much documentation. I know this because I've been tasked with figuring out how to use it with a new project and integrating it with existing infrastructure. I've been searching the web for months looking for good information.
I've taken a somewhat different angle to solving the problem you describe.
I took an existing log-on application and integrated Microsoft's WIF plumbing into it. By that, I mean that I have an application where a user logs in. The log-on application submits the credentials supplied by the user to another server which returns the users identity (or indicates log-on failure).
Looking at some of Microsoft's examples, I see that they do the following:
Construct a SignInRequestMessage from a querystring (generated by a relying party application), construct a security token service from a custom class, and finally call FederatedSecurityTokenServiceOperations.ProcessSignInresponse with the current httpcontext.response. Unfortunately, I can't really explain it well here; you really need to look at the code samples.
Some of my code is very similar to the code sample. Where you're going to be interested in implementing a lot of your own logic is in the GetOutputClaimsIdentity. This is the function that constructs the claims-identity that describes the logged-in user.
Now, here's what I think you're really interested in knowing. This is what Microsoft doesn't tell you in their documentation, AFAIK.
Once the user logs in, they are redirected back to the relying party application. Regardless of how the log-on application works, the WIF classes will send a response to the user's browser that contains a "hidden" HTML input that contains the token signing certificate and the user's claims. (The claims will be in clear text). At the end of this response is a redirect to your relying-party website. I only know about this action because I captured it with "Fiddler"
Once back at the relying party web site, the WIF classes will handle the response (before any of your code is run). The certificate will be validated. By default, if you've set up your relying party web site with FedUtil.exe (by clicking "Add STS Reference in your relying party application from Visual Studio), Microsoft's class will verify the certificate thumbprint.
Finally, the WIF framework sets cookies in the user's browser (In my experience, the cookie names start out with "FedAuth") that contain the users claims. The cookies are not human readable.
Once that happens, you may optionally perform operations on the user's claims within the relying party website using the ClaimsAuthenticationClass. This is where your code is running again.
I know this is different from what you describe, but I have this setup working. I hope this helps!
ps. Please check out the other questions I've asked about Windows Identity Foundation.
UPDATE: To answer question in comment below:
One thing that I left out is that redirection to the STS log-on application happens by way of a redirect with a query-string containing the URL of the application the user is logging in to. This redirect happens automatically the first time a user tries to access a page that requires authentication. Alternatively, I believe that you could do the redirect manually with the WSFederationAuthentication module.
I've never tried to do this, but if you want to use a log-on page within the application itself, I believe the framework should allow you to use the following:
1) Encapsulate your STS code within a library.
2) Reference the library from your application.
3) Create a log-on page within your application. Make sure that such page does not require authentication.
4) Set the issuer property of the wsFederation element within the Microsoft.IdentityModel section of your web.config to the login page.
What you want to do is an active signin. WIF includes WSTrustChannel(Factory) which allows you to communicate directly with the STS and obtain a security token. If you want your login form to work this way, you can follow the "WSTrustChannel" sample from the WIF 4.0 SDK. Once you have obtained the token, the following code will take that token and call the WIF handler to create a session token and set the appropriate cookie:
public void EstablishAuthSession(GenericXmlSecurityToken genericToken)
{
var handlers = FederatedAuthentication.ServiceConfiguration.SecurityTokenHandlers;
var token = handlers.ReadToken(new XmlTextReader(
new StringReader(genericToken.TokenXml.OuterXml)));
var identity = handlers.ValidateToken(token).First();
// create session token
var sessionToken = new SessionSecurityToken(
ClaimsPrincipal.CreateFromIdentity(identity));
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken);
}
Once you have done this, your site ought to behave the same as if passive signing had occurred.
You could use the FederatedPassiveSignIn Control.
Setting your cookie like this:
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken);
Doens't work for SSO to other domains.
To cookie should be set by the STS not at the RP.