Kerberos delegation across 2 untrusted domains using WCF - wcf

I have an application in domain A and would like it to use domain B credentials to access domain B content. These domains have no trust. Is it possible to challenge a user in domain A, and get them to input credentials for domain B? Then use these credentials to authenticate in domain B. Meaning we bypass domain A's Kerberos Distribution Center (KDC).
I have no problem getting this to work inside a single domain, meaning impersonating the challenged user and maintaining an impersonation level of delegation. However, MS documentation says that the application in domain A will use its KDC to issue a ticket (or fail to issue the ticket) and this will cause my service in domain B to drop to NTLM.
Is it possible to force my service in domain A to use domain B's KDS? I could be way off base here.
The architecture is Microsoft WCF services.
Thanks,
Kevin

The quick answer is NO you cannot pass credentials across domains without the 2 domains having some level of trust.
However, I got around this by using asp.net forms authentication. When the users credentials from domain A fail I effectively get them to input the credentials from domain B and redirect them to an "Authentication" MVC controller that scrapes the user identity and then encrypts it in a Asp.Net forms authentication cookie. This is returned in the response header. All subsequent requests are made with this cookie and I check for the the authenticated user in the session cookie. Not as elegant as delegation but it works.

Related

Custom OIDC login page - host on identity server or client application server?

Most IDAM servers (Identity Server 4, Gluu, Cloud services) provide a way to host a login UI on the actually identity server. This login page can be customized so that it can be branded like your website. This works well for security flows so when you reach an authorization end-point you are redirected to your identityserver/login page.
But can you host the login page on the client application instead?
And if so:
Is this advisable?
Is this more/less secure than hosting the login UI on the Identity Server?
Would this break security flow standards like OIDC / Auth 2.0 authorization code flow?
Would this simply call an API to authenticate against? e.g. one that is hosted on the identity
server. Some appear to support this, but this seems a bit old / insecure compared to existing security flows.
Thanks.
Not really: the point of (federated) Single Sign On (SSO) is that one can use a single credential to login across different domains without divulging that credential to every domain/application.
Users use those credentials in one place against one server only to a trusted party aka. the Identity Provider. The Identity Provider then creates a derived token that is consumed by the 3rd-party application because the latter trusts the former to do so.
In case all applications belong to the same domain as the Identity Provider, the argument above no longer holds, but not using SSO would still mean that you'd have to login to each application separately, one by one.

ADFS authorisation but only local sign on

We do not have ADSF at present, so I cannot test this, but I would like to know if it is possible to authenticate onto a separate domain, when only signing on locally (but using domain credentials).
EG
I have a laptop that is part of a domain (WORK-DOMAIN). The plan is to use ADSF to authenticate and make use of some resources on a separate, currently untrusted domain (RESOURCE-DOMAIN).
My question is, if I'm working from home, I am logged in with my domain credentials, but I am not on the network (I don't VPN on to the network). Will ADSF accept me as being authenticated on the domain, even if I'm not currently on the network?
I hope this makes sense... Thanks in advance.
adfs supports several authentication methods. You could use forms based auth to pass your username and password when at home to adfs. When on corporate network you'd use windows integrated authentication. The key thing is to ensure adfs service account has the ability to validate credential of user. This is where your domain setup and trusts matter. As an example if adfs servers and service account were all in user domain then this is simply and works.
You need an ADFS per domain. So you would have ADFS-WORK-DOMAIN and ADFS-RESOURCE-DOMAIN.
You are not part of the RESOURCE-DOMAIN so when you navigate to it, you will have to use Forms Based Authentication and use the credentials on that domain's DC.
If you federate the two ADFS and you are at work, then you will be able to access RESOURCE-DOMAIN via WIA using your WORK-DOMAIN credentials. This is because the two ADFS trust each other.

Single sign-on flow using JWT for cross domain authentication

There is a lot of information on the web about using JWT (Json Web Token) for authentication. But I still didn't find a clear explanation of what the flow should be when using JWT tokens for a single sign-on solution in a multiple domains environment.
I work for a company which has a lot of sites on different hosts. Let's use example1.com and example2.com. We need a single sign-on solution, which means if a user authenticates on example1.com, we want him to also be authenticated on example2.com, automatically.
Using the OpenId Connect flow, I understand that the user who wants to authenticate on example1.com will first be redirected to the authentication server (or OP : "OpenId Provider"). The user authenticates on that server which then redirects him back to the original example1.com site with a signed JWT token. (I understand there is another flow which returns an intermediate token that itself can be exchanged for the real JWT token later on, but I don't think this is required for us)...
So now the user is back on example1.com and is authenticated! He can make requests, passing the JWT token in a Authentication header and the server is able to verify the signed JWT and therefore is able to identify the user. Nice!
First question :
How should the JWT token be stored on the client? There is, again, a lot of information about this, and people seem to agree that using Web Storage is the way to go rather than good old cookies. We want the JWT to be persistent between browser restarts so let's use Local Storage, not Session Storage...
Now the user can restart his browser and he will still be authenticated on example1.com, as long as the JWT token is not expired!
Also, if example1.com needs to make an Ajax request to another of our domains, I understand configuring CORS would allow that. But our main use case is not cross-domain requests, it's having a single sign-on solution!
Therefore, the main question :
Now, what should the flow be, if the user goes to example2.com and we want him to be authenticated, using the JWT token he already has? Local Storage doesn't seem to allow cross-domain access so at this point the browser can't read the JWT token to make requests to example2.com!
Should :
The user be redirected to the authentication server again? When the user authenticated for example1.com, the
authentication server may have set a cookie on the user so this new authentication request for example2.com could use that cookie to see that the user is already authenticated and immediately redirects him back to
example2.com with the same JWT token?
Or can the browser, on example2.com, access the JWT token without having to go to the authentication server again? I see there are cross-storage solutions, but are those widely used? Are they the suggested solution to a cross domain SSO environment?
We don't want anything fancy, we would be happy with the mostly used solution!
Redirecting the user to the central authentication service when the user is not logged in to request credentials and issue a new authentication token is the common scenario in Single Sign On systems using well-known protocols like oauth2 or OpenId Connect
However when this schema is used across domains the main drawback is that the user is going to be redirected and authenticated each time he navigates to other domain due to same-origin policy: the access token can not be shared between domains (example2.com can not access data of example1.com), so the target domain will treat user as unauthenticated, redirecting him to the central SSO service.
To prevent the authentication service from re-requesting credentials, it is common to have a session cookie (not an access token), but there is a tecnique to share data across domains using browser localStorage/cookies and a iframe pointing to an intermediate domain sso.example.com
To authenticate the user in example1.com, redirect him to the authentication server in sso.example.com, issue a JWT after authenticating and store it in the localStorage of this domain. After this, redirect user to the origin domain example1.com
Create an iframe in example2.com pointing to sso.example.com. The iframe in sso.example.com reads the JWT token and sends a message to the parent page
The parent page receives the message and gets the attached token continuing with the SSO flow
There is no problem with same-origin policy because sso.example.com has access to its localStorage and the communication between iframe and the parent page is allowed if origin and target domains recognize each other (see http://blog.teamtreehouse.com/cross-domain-messaging-with-postmessage)
To simplify development, we have released recently a cross domain SSO with JWT at https://github.com/Aralink/ssojwt
This method is perfectly compatible with SSO flows. It is just a way to share the authentication token without redirections and avoid unnecessary log-ins when the domains are federated
The user should be redirected to the authentication server again and get a new token (JWT), one that is specifically targeted for example2.com. This is how OpenID Connect and any other cross-domain federated SSO protocol works.
Not sure if this answers you question, but if your main goal is single sign-on, I think a simple reverse proxy would solve your problem (at least the cross-domain storage one).
So
example1.com
example2.com
would become something like
example.com/example1
example.com/example2
(And from a user side, this is usually cleaner)
If that is not an option, you might have to set up so that when a user authenticates in 1 domain, it uses AJAX/hidden iframes to create an authentication with the other domains as well (sending a 1 time token via url if you must).
and if THAT'S not an option, you might have to resort to username+pin, as browsers are getting stricter about cross-domain interaction.

Unable to setup ADFS on different domain and mvc app with window auth on different domain

My MVC 4 application (https://testapp.com) with WIF and windows authentication is on Domain A and my ADFS and users are on domain B.
Requirement: Users in Domain B will browse my application https://testapp.com which is hosted in Domain A and my application should use their local windows user creds and redirect to the ADFS in Domain B.
I believe I dont require a AD cross Domain trust between A and B and that is what ADFS and SAML authentication is meant for.
I dont see such much materials for reference in such scenarios also. Kindly help understand how to configure such an MVC application in Domain A.
You need to establish a trust between your MVC4 application and your ADFS. In ADFS lingo this is called "Relying Party". You will need to have an endpoint in your application that accepts a HTTP POST message and processes the payload generated by ADFS.
I had to recreate these a long time ago but you can spare the pain. There are more options available -
http://saml2.codeplex.com/ (open source)
http://www.componentspace.com/Products/SMLv20.aspx
Configuring ADFS can be tricky but there are lot of guides out there.

Best way for a remote web app to authenticate users in my current web app?

So a bit of background, I'm working on an existing web application which has a set of users, who are able to log in via a traditional login screen with a user name and password, etc.
Recently we've managed to score a client (who have their own Intranet site), who are wanting to be able to have their users log into their Intranet site, and then have their users click a link on their Intranet which redirects to our application and logs them into it automatically.
I've had two suggestions on how to implement this so far:
Create a URL which takes 2 parameters (which are "username" and "password") and have the Intranet site pass those parameters to us (our connection is via SSL/TLS so it's all encrypted). This would work fine, but it seems a little "hacky", and also means that the logins and passwords have to be the same on both systems (and having to write some kind of web service which can update the passwords for users - which also seems a bit insecure)
Provide a token to the Intranet, so when the client clicks on a link on the Intranet, it sends the token to us, along with the user name (and no password) which means they're authenticated. Again, this sounds a bit hacky as isn't that essentially the same as providing everyone with the same password to log in?
So to summarise, I'm after the following things:
A way for the users who are already authenticated on the Intranet to log into our system without too much messing around, and without using an external system to authenticate, i.e. LDAP / Kerberos
Something which isn't too specific to this client, and can easily be implemented by other Intranets to log in
Both of your suggested options are insecure, even if you use SSL. Never pass credentials on a URL, put them in the HTTP request by using POST.
There is a standard called SAML and this can be used to solve your problem. The challenge is choosing which version to implement. I would choose SAML 2.0.
Google Apps implements a flavor of SAML 2.0 and allow you to authenticate using your intranet credentials. In the case of your application, you would be the service provider and your client would be the identity provider. As long as you implement the standard correctly you should be able to support any new client (identity provider). Here is a list of SAML implementations you might want to take a look at. If you need the client to pass over information in addition to the authentication information then SAML can facilitate this with metadata.
You will still need to implement SSL to encrypt network traffic.
I hate to answer my own question, but I hate even more a question with no answer. In the end we went with a very similar implementation of SalesForce's delegated authentication SSO implementation.
http://wiki.developerforce.com/page/How_to_Implement_Single_Sign-On_with_Force.com
Essentially the solution has a trusted site, known as the delegated authentication authority, who has a list of users who are logged into the company intranet.
When the user logs into the company intranet, and they click a link to our application, the company intranet will pass the user name and a generated token (which expires after a set amount of time) to our application.
Our application will then check if the user name is on our site, and if so, send the username / token (along with the source IP and a few other parameters) to the delegated authentication authority. If all those items match on the delegated authentication authority, it returns true and the user can log in. If it returns false the user is denied access.
We've found this system to work quite well, and even implemented a couple of extra security features like SSL, client side certificates, VPN tunnel, and even restricting the IP addresses which can access the site and the delegated authentication authority.
I know it's bad form to answer your own question but I hope this helps someone else who might be having the same problem ...