How to determine which IdP to redirect from a SP? - asp.net

I'm building SP initiated single sign-on, and I wondered what the best practice was for determining which identity provider to redirect a user to.
Here are the options I've come up with:
/SSO/Logon/Acme, where Acme is a name of a known IdP.
We know the endpoint url for this provider, and redirect the user. The downside, is that an anonymous user can detect what IdPs we support by guessing names and checking for a redirect.
/SSO/Logon/1, where 1 is the id of an identity provider.
Same problem.
/SSO/Logon?endpointUrl=http://idp.acme.com
We blindly redirect an AuthnRequest to any endpoint, and unauthorized endpoints will be rejected when they respond
/SSO/Logon/ABCDEFG where ABCDEFG is a cryptographically secure random string
We lookup the endpoint url associated with this key, and know where to redirect. Similar to first two options, but not guessable
This must be a solved problem. What's the best way to handle this?

Related

Anti-forgery token on each request from angular app

I have a website which supposed to be very secure as most of the activities are financial transactions. This site has a lot of security mechanism and I doubt one of that is not sufficient.
This web application is based on AngularJS 1.4 and ASP.NET MVC 4. After logging into the system using angular, I am calling a controller action to set Anti-forgery token. The all subsequent request has the same token and server validates the same on each request.
Now the problem.
Since we are not changing the token on each request, a logged in user can use the token from the request by merely looking in Fiddler or Chrome Network tab and try to request resources modifying the request.
Is it required to reset the token on each request? Will it help to prevent this kind of attacks?
The token is not meant to prevent the authorized user from crafting requests manually. The token ensures that someone else other than they user, cannot use a csrf request to forge a request from the user.
You can reuse the same token because if implemented properly, a potential CSRF attacker should not be able to read the value. This relies on the same origin policy of the browser to ensure the third party site cannot read or submit the same value.
If you had any kind of hole though, such as a json GET that returned a token(best practice is JSON returning data should still be submitted with a post) then the token could be compromised.
https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks
Authorization
In regards to potentially fraudulent requests from the authenticated user
You need server side checks that ensure that he is only posting edits to accounts for which he has the authority to edit. For example, if I own account A, and I want to send money to account B, then the server side check will ensure that I own account A, and thus have authority to send its funds elsewhere. If I hand crafted a request to send funds from B to A, the server side check should see that I am not the owner of B by looking at the database relations of the account and owner. This is known as authorization. Authorization ensures that a user has the authority to perform an action. This is usually dictated by business rules that defines the relationships between tables that say who has access to what.
Authentication
The only other issue is ensuring that I am who I say I am, since if I just posted a user ID in the request, I could easily change that in the browser.
When the user proves he is who he says he is, usually by providing userid/password, then we generate an authentication token. In ASP.NET this token is cryptographically secure such that only the server has the necessary key information to generate and validate the token. Usually this token is persisted as a cookie.
The combination of authentication and authorization ensures we know who the user is, and on each request use our business rules defining authorization to check that the action is valid. It doesn't matter that he can hand craft invalid requests, as the requests will fail server side authorization.
Imagine this simplified server side code:
public void TransferFunds(TransferFundsRequest request)
{
var account = Database.GetAccount(request.SourceAccountId);
if(account.OwnerUserId != session.UserId)
{
throw UnauthorizedException("This user is not the owner of the source account in the transfer funds request.");
}
// continue with logic to transfer funds
}
CSRF
Cross site request forgery is an entirely different issue. This is when somehow another site loaded in the authorized user's browser tries to send a request from the user's browser. A malicious third party site that I visit uses javascript or other methods to cause my browser to make a TransferFunds request, from account A to account C. Now if I am owner of account A, from the perspective of the server that is a valid request. CSRF tokens ensure that we can detect that the user did not send the request from a form that our server generated, but instead some third party site's form or URL.
For example, if all the parameters of the request can be coded in a query string, I could craft a URL for the TransferFunds request and email it to the Account A owner and try to trick them into clicking the link. If the user happens to be logged into the site, then our server believes the user sent the request. However, if we include the anti-CSRF token when generating HTML input forms, then the absence of the token proves to us that the request came from a form or URL crafted by a third party.

OpenAM, OpenId, REST API, In-House applications: how do I connect them all?

I'm having trouble tying all of this together. Partially due to lack of understanding, and partially because I've not use OpenAM before.
I'm trying to implement Single Sign-on. Here are the players.
OpenAm. https://www.forgerock.com/en-us/products/access-management/
A 3rd party proprietary app that can use it's own username/password database, or authenticate against an SAML or OpenId provider.
Several In-house applications written in either angularjs or .net webforms.
An in-house REST API written in nodejs.
I need to be able to have a user sign-on/register in openam, and then they don't sign-in to any of the other applications. We see this all over the web, so the use-case is pretty normal, but I've never actually implemented it myself before.
See what I'm trying to do using the image below for starters.
Here's what I'm stuggling with:
For SSO purposes, OpenAM seems to store the authenticated user information in a cookie. How does my Proprietary app pick up this cookie and use it if it can only authenticate via openid or saml? It can't use the openam API by going through the /json/* endpoints.
With the in-house apps, I'm assuming I can just pass the cookie along and the appropriate parties can validate the cookie's session info or token and that's that. Is this correct, or am I looking at this wrong?
Can I have the user login to the OpenAm login page, and then use the /oauth2/* endpoints to validate the user's requests? I could see this working better, but am unsure if this is how it's supposed to happen.
Basically, I feel like I've scrambled my brain this last week trying to sort this out. I need some help to get some direction here. As I said above, a good portion of this is new. I've done front-end->rest api->database using a token, but this SSO scenario has given me a real headache.
Any help would be appreciated.
It sounds to me that you miss the "redirection" aspect of SAML SSO. I'll try to explain how it works in a nutshell:
Step 1:
When a user sends a request to one of your in house applications (call it the Service Provider, SP, from here), the SP detects that this is an unauthenticated request and redirects the browser to the OpenAM server (call it the Identity Provider, IdP, from here).
Step 2:
The IdP analyses the redirection request and expects to find a "SAML authnResponse", this is encoded XML metadata added in the redirection request by the SP. It finds out that your SP wants to authenticate a user. The IdP will respond to the request by showing a login page. Here the user can authenticate to the IdP. After the user succesfully authenticated to the IdP, it will redirect him back to the SP adding a "SAML authnResponse" to the request.
Step 3:
The SP will analyse this "SAML authnResponse", which is again just a form of XML metadata. If the validation of the signature is OK,find out which user successfully authenticated, create a session for him and redirect him to the resource he initially tried to access.
Remark 1:
In Step 2, if the user already authenticated to the IdP before, he will have an active session to the IdP. The IdP will not require him to login again but just inmediately redirect him back to the SP with a valid "SAML authnResponse". In this way the user will barely notice all these redirects and it will look like he 'seamlessly' got access to the SP.
Remark 2:
So don't worry to much about cookies, they're used by the IdP to recognize already authenticated user sessions etc. but you should only bother with redirects and analyzing the SAML Responses and Requests. Does this make sense?
Remark 3:
The way how the browser (GET 302 or JS POST) of the user will be redirected depends on your chosen "SAML Profile".

Implementing a Symfony2 single-sign-on

I have a basic understanding of the security concept in Symfony2. Now I'm trying to implement a single-sign-on feature for a multi-domain website.
The SSO concept itself is rather straightforward:
Domain A is the cookie domain; people can log in on this domain
When logging in on domain B, the user is redirected to domain A, where a One-time password is requested. The user needs a session on domain A to get this password.
After obtaining the OTP, the user is returned to domain B, which will match the OTP to the session on domain A.
If matched, a session will be created for domain B. The session will be validated against the session on domain A for each subsequent request from this point on.
Implementing the firewall/authentication for domain A can be done as you normally would. In my understanding, I need to:
Set up a firewall for domain B
Create a listener for this firewall, that somehow redirects the user to domain A (more specific: an uri that requests an OTP)
Create an authentication provider that handles a OTP and creates a session for domain B
Create another listener that checks the session validity against the session on domain A
However I could really use some tips on how to do this in a bundle. If anyone can help me out here, that'd be great.
Also, I'm not yet sure how to implement the OTP, or how to compare the two sessions, and make sure they both are valid. That will come later, I need to get this workflow working first.
In order to get multidomain SSO you can implement a SAML solution. Take a look on simplesamlphp software and in this extension for symfony1 https://github.com/chtitux/sfSAMLPlugin
To resolve the OTP issue you can use for example LinOTP2 witch is compatible with simplesamlphp: https://github.com/lsexperts/simplesamlphp-linotp

SAML: Communication between Service Providers?

I've been tasked with writing a SP (Service Provider) for SAML v2.0 in ASP.NET, and I wonder the following;
If a user logs in on the main SP for a service (where my SP becomes accessible for a user as an anchor/link, unless previously bookmarked), and then requests access to my SP, how should I handle their login?
They will have logged in and become authorized by the IdP on the main SP, but how will that SP tell my SP that the user is logged in?
Will I have to send a new authorization request to the IdP to determine whether the user is logged in or should it be passed on as post data/redirect with a query string from the SP?
I've read the technical overview as well as the basics, but they don't cover this part.
I will contact the main SP and ask how to proceed, but I wanted to cover my bases first and see if there's a standard way on how to deal with this situation.
The easiest thing to do is to have the "main SP" construct the link so that IDP-Init SSO is initiated for users to log into your application. So the user would show up with a new Assertion from the IDP (customer) to your SP.
You could also have them directly link to your site to invoke SP-Init SSO for the given Identity Provider/Customer.
Either way you choose to do this will require you to handle multiple use cases and options for SAML 2.0. You can have this up and running in short order if you want to check out the SaaS Partner Program offered by Ping Identity. www.pingidentity.com
Let me know if you'd like more info on what we've seen other
In order to do SP-initiated SSO, you either need for there to be only one identity provider that you might need to send authentication requests to, or you need some means of determining the proper identity provider for a particular user -- either the user needs to provide some IdP-identifying info (such as StackOverflow does when you want to log in using your Google or other ID) or there may be something embedded in the URL. (For the app I work on, different clients have their own site domains, so IdPs get mapped to those.)
So, yes, if you're going to go the SP-initiated route, you will need to make an authentication request to the IdP to determine who the user is, and you will want to use RelayState to get them back to the originally requested page. If they're already authenticated at the IdP, then most likely this exchange will happen without requiring any input from the user.

Secure login with additional context information passed through (which also needs to be secure)

My web application will be launched through existing thick client applications. When launched, an HTTP POST request will be generated including information like the userID and additional context information (basically stuff like the target user's name, birthday, etc.).
My plan for authentication is for there to be a look-up table in the database. If the username is already there, automatically login the user, but if there is no entry in the database, redirect the user to an initial login page which will be used to create that database entry.
My question is how to secure this against MITM and other security holes. How can the request generated through the thick client be on an SSL connection? Doesn't an SSL connection have to be authenticated with the username (and password) first? And if so, will the additional context information be publicly exposed until the user is logged in?
Sorry if this is a basic security 101 question. References on where to read up on security basics would also be greatly appreciated.
No, SSL does not require any username or password to work. SSL only encrypts the data between the client and the server. You could serve an entirely anonymously accessed site via SSL. Most of the time, people equate SSL and logins because you want to encrypt your login credentials and any of the information accessed using those credentials.
If you want to use your method, simply post the User ID and other information to your SSL site. The post and any response will be encrypted. If using a web page, it would look something like this.
<form method="POST" action="https://mysite.com/login">
Generating from an application, just use the https:// when creating your URL to post to.
Regarding any other security concerns, we do not have enough information to speak about the overall security of your planned deployment, but the above should take care of your initial questions about SSL and encryption.

Resources