I'm working with a client that has a very strange network setup. Basically, they have multiple small segmented networks with their own clusters of servers because of several acquisitions, mergers, etc. It's a nightmare.
I've setup the authorization servers correctly and they're all running the same code but when I try to take my laptop from location to the other, I get logged out and have to log back in again. A lot of the employees travel between sites so getting logged out all the time is causing some grumbles.
The each instance of the APIs and Authorization servers are able to use the same database, but each site has it's own Authorization and Resource server.
What I've noticed is this:
If I stay in one place, my access/refresh token setup works great with no problems
If a travel to another site, the new sites authority server doesn't seem to be able to validate the access token and logs me out
There is one site with a load balancer that will log me out randomly as well as if I'm traveling between sites.
The app is built on .NET Core 2.2 and OpenIDDict 2.0. For budgetary reasons, upgrading either is not an option.
Is there anyway to configure a shared certificate or key so that all of the servers can decode the access tokens? Basically multiple authorization servers able to decode the access tokens generated by any of the other authorization servers?
I was able to figure it out. I had to change this:
services.AddDataProtection()
.PersistKeysToDbContext<DbContext>();
to this:
services.AddDataProtection()
.SetApplicationName("appName")
.ProtectKeysWithCertificate(MyX509Certificate2)
.PersistKeysToDbContext<DbContext>();
Related
I’m building a web application where users can create their own websites. Users have the option to point their own domain names at these sites. A prototype for the application already exists; Apache accepts requests on all hostnames and the actual domain mapping and resolution happen at the application level (a simple database lookup grabs the site that matches the requested hostname).
Where I’m stuck is how users’ SSL certificates might fit into this equation. What steps would I need to take to allow a user to upload their SSL certificate such that the application could successfully handle secure HTTP requests to their hostname? Is this even something the application alone could handle?
I think you cannot handle this in your application alone.
It's a CA problem, except you are an intermediate CA company, or you cannot get the user's domain SSL certificate and sign for user's domain.
The typical user, and IMHO even more the user's who are going to create a web site of this system as opposed to setting up their own WordPress or other site on their own server (or their own paid shared server hosting account), will have absolutely no idea how to setup a proper SSL certificate, so getting it to your securely so that you can install it wouldn't even be an issue because they will never get that far.
However, you should be able to use Let's Encrypt to do exactly what you need. As part of the process of adding a domain, once the domain is pointing to your server (the users will have to figure out how to do that with their domain registrar), you can create a Let's Encrypt certificate and validate it. My favorite web hosting company (I won't name it as that is not relevant - anyone can do this with some effort) provides this capability as part of their Control Panel. They also provide paid certificates with a few of the big issuers, as they have for many years, but for most small sites Let's Encrypt works very well and is totally free. The setup literally takes only a minute. The key is that you have to give the user an IP address or CNAME first so that they can point the domain. Once the domain is resolving to your server, you can get the Let's Encrypt certificate.
How to prevent someone just taking my API keys from the client side javascript code and starting to use my HERE subscription for some other use.
I noticed HERE provide an option to secure the API keys for a certain domain on the applications management page: "Secure app credentials against a specific domain". I have set up this option and also put domain there but I do not see any change on my app behavior.
The application still continue working fine on my PC. Shouldn't the HERE API stop working as web server is running on localhost and not on the defined domain.
My app is running fully on browser, and only static files come from the server (http://localhost:8083/index.html). I am using the HERE javascript API.
I tested also running the app on external cloud service on different domain than localhost. Results are the same. My conclusion is that the setting "Secure app credentials against a specific domain" just has no impact and does not work. Checked also the api response headers and all origins are accepted.
Access-Control-Allow-Origin: *
In your HERE dashboard, you can set the application id and application code to only work on a particular domain or set of domains. If the tokens are fixed to a domain, it won't matter if someone takes your tokens because only the listed domains can use them. If you don't secure the tokens to a domain, then someone will be able to use your tokens if they find them.
Background
I want to create a PHP application that eventually will be installed on a "countless" web servers.
The application is going to access the Google Drive associated with the web server's administrator Google account (it will basically write some files on user's cloud storage). So my PHP app will be authorized by the end-user to use its Google Drive storage. This is done (via the OAuth2 protocol) by connecting the Google OAuth2 service.
So basically I have to create a ClientID/Secret pair (on behalf of my Google Account) that is gonna be used to execute the authorization flow.
Google provides 3 authorization methods:
for web applications (web browsers over network)
for service account (my server to Google server)
for installed application (like Android, IPhone)
(1) is perhaps the best choice EXCEPT that I have to define a REDIRECT_URI where the authorization code will be sent. Because my APP will be installed on a "countless" different servers I don't know in advance the protocol, domain name and the path (also the URI) where the Google's response should be returned. If I would install this application only on 3 servers I could create upfront a ClientID/Secret pair for each of them. It's not the case.
(2) means to deploy my P12 private key with the PHP application and I don't feel comfortable with that!
(3) means to put the end-user to copy/paste an authorization token from a Google web page into my application web interface. I am trying to avoid doing that.
I already made it to work by using the method 1 when I know in advance the REDIRECT_URI. I also embedded the client_id/secret pair in the source code so the whole authorization process is user-friendly. But this is not going to work on a "countless" deployment scenario.
Questions
Which method and how should I use it in order to make the whole process safe for me (as developer) and for the client too (the web server administrator). Note that the authorization process should not involve the end-user to copy paste some codes. I want that step to be transparent/user-friendly for the end-user (no one likes copy-paste when it can be done automatically).
Should I embed my client_id/secret into the application or that's totally wrong? I suppose no end-user wants to go through the creation of its own ClientID in Google Developer Console, right? On the other hand why I would give my client_id/secret to an unknown end-user?
Final thoughts
I could create a proxy application on my (the developer) web server such that my PHP application (which is supposed to be deployed "everywhere") will send the authorization request to my proxy server (which has already its own client_id/secret) which in turn will redirect the call to the Google OAuth service which then REDIRECT_URI back the authorization code to my proxy and finally I will redirect back the response to the original sender (the PHP application). What do you think?
Some useful answers here and here or here.
#Edit: as I've already said earlier a proxy would be a solution. I've made it and it works. The same solutions I've received also from user pinoyyid. Thanks for your answer too.
A proxy is the only real option open to you. You can encode the originator URL in the "state" parameter, so that when the proxy receives the access token, it can call a webhook at the originator.
There are some contradictions in your question...
"The application is going to access the Google Drive associated with the web server's administrator Google account" and "So my PHP app will be authorized by the end-user to use its Google Drive storage." are mutually exclusive.
If the Drive storage belongs to the app, then the user isn't involved in any OAuth dialogue.
Could you edit your question to be clear who is the owner of the Drive storage as it greatly influences the OAuth flows.
Im currently in the process of exposing our internal CRM system to the web so our employees can use it outside out network. The data is being surfaced to our web application via asp.net WebAPI.
We have SSL setup on the website. But am thinking how else I can make sure the WebAPI is secure from malicious use. My ideas are:
Tracking what IP addresses are accessing the WebAPI and only allow addresses that we have validated are from employees. Problem with this having dynamic IP addresses we might be constantly updating a data store of valid IP addresses.
The user has to login to the system. So every request to the webapi will send across their login details which will be validated before the webapi will process any request.
Pass the device ID of the device using the webAPI and validate (pretty much the same as IP Address tracking in idea 1)
Having a unique clientside generated access token which much match up at the server side.
Has anybody got any advice on my security ideas I outlined? Is it to little or is it overkill?
Just want to make sure the data cannot be hacked, because my butt would be on the line if it did.
Thanks in advance
I would actually choose a totally different solution - updating valid dynamic IP's will be hell.
I would:
Create a new Project using the "Intranet Application" instead of using "Internet Application"
Host the application on your local office network
Set up VPN to your Office for your colleagues
Would this solution be possible for you?
Scenario
I have an HTML/javascript website that uses javascriptSOAPClient communicate with an ASP.NET 1.1 web service in order to read/write to a SQL database. (http://www.codeproject.com/KB/ajax/JavaScriptSOAPClient.aspx). The database contains anonymous demographic information--no names, no credit cards, no addresses. Essentially the data collected is for data mining purposes.
The site is live, but we want to introduce a more secure communication between the javascript/ajax client and the wbe service for both this and future projects. Working as contractors in the financial industry, at some point we're going to get nailed with the question: is this website hackable? If we don't have a solution we could be out on our ears.
I am already following best practices such as communicating with the database via command parameters and stored procedures). However, currently anyone could browse to our web service description and figure out how to consume our exposed services.
Questions
With my hybrid solution (i.e. not end-to-end Microsoft) how should I go about authenticating client requests on the web service?
If I start passing a username/password or some other identifiable element into the web service as authentication, should I be concerned about how that key is generated/stored on the client side?
A few suggestions to consider:
List the threats, and compare each to your current setup.
Use SSL / HTTPS. This alleviates a whole class of vulnerabilities.
Use username/password, generated on the server side and sent out of band (in the post or by phone) to the user. (Hope this answers question 2).
Use 2-factor authentication. To do this, you can look at security tokens such as RSA's keyfob-type gizmos or look at Steve Gibson's Perfect Paper Passwords
The easiest solution from a programming standpoint is to use two way HTTPS. That is, the server presents a certificate to the client, and the client presents a certificate to the server. Then only clients with proper certs (issued by you) can connect.
That helps reassure clients that your site is not generally accessible, yet the security is transparent to the application and, once they've signed up and received a cert, to them. The downside is that you have admin overhead in issuing and tracking the user certs -- but that's probably less than you'd have dealing with username/password combos.
There are a few simple options:
SSL + Cookie
If the web app is also ASP.NET and hosted along with your web service, then you should have access to the User/Membership/Session of the web app inside your web service (essentially #1, but you get it without doing any work).
If the web app and web service are not on the same domain, then cookies are out due to cross-domain issues - so you can have the web app embed a GUID into a hidden form field, and use that GUID as a sort of cookie (and it will need to be passed as a parameter on all web service requests).
Can you incorporate a certificate authentication mechanism? So that only clients that have keys you can verify can communicate? That's how the product I work with has its managed devices communicate back to the core.