Currently I have got a specific problem finding a solution and I am hoping you are able to provide
some light on the matter.
The Structure of the problem:
The task at hand is to gather a client's login credentials (token) and pass this to the servlet. However I cannot seem to find a good resource to do this. I have researched a wide variety of ways. I.e SPNEGO, WAFFLE etc..., However, these seem to require some sort of active directory by my understanding, I am trying to gather the credentials from the users local machine. A clear explanation or guidance to how I can gather the windows credentials to the servlet for my specific request would be appreciated.
Diagrams are always a better way of explaining so I will provide one if you are still confused:
Windows PC (Client) ------------------------> Java Servlet -------------------------------------> IIS Server
(windows authentication) --------------> (Get Credentials) -------------------- (Check Credentials & Authenticate)
(token) (pass credentials)
Thank you in advanced to anyone who replies, I really appreciate it!.
You are wasting your time. If you only take the credentials from the users local machine then you have no way of knowing if those credentials can be trusted. You might as well just give every user administrative access to your web application.
The reason active directory (or something like it) is required is that it is not under the control of the client and is trusted by the server. For example, when using SPNEGO, the client authenticates itself to the windows domain, the client gets a token from the windows domain that it can only get if it is authenticated, the client passes the token to the server, the server can then validate that token with the Windows domain to confirm that the client is indeed who they claim to be. (Not quite that simple but you get the idea.)
There are other ways to do this - e.g. with PKI - but they all have in common a central, trusted authentication system that the server can use to validate credentials provided by the client.
Related
I have been given an assignment for User registration and login using Spring boot. Front end I have used thymeleaf.I have developed the application in my localhost.
Below are the deliverable
Deliverables
● Source code ---- Done with GitHub
● Public working url of the webapp --- How to do???
● Tests - unit and integration tests. you may also choose to use a ci ---- Done
I would like to know how to create a public working URL for a project developed on localhost.
This process is called deployment. You may use Heroku, just follow the instructions. At the end, you will get an URL like http://my-lovely-app.herokuapp.com/ which is public and working.
Just go to the command line and navigate to your program by typing “cd (the path to your web app)”. Then in the command line type “gcloud app deploy”. Then click on the link to your site.
to answer this question, one needs first to understand an overview of an http(s) request lifecycle:
user enters an URL in his browser: https://some.domain:8080/request/path?param1=value1¶m2=value2
the browser splits the URL into protocol scheme ("https"), server DNS name ("some.domain"), port (8080), request path ("/request/path") and query-string ("param1=value1¶m2=value2"). If a port is omitted, the default port for the given protocol is assumed (80 for HTTP, 443 for HTTPS, etc)
the browser performs a DNS lookup to translate server DNS name to an IP address.
the browser makes a TCP connection to server's IP address (in theory HTTP can also use UDP, but it is rarely used, so we will skip this case)
if HTTPS was used, the browser and the server perform TLS handshake during which, among others, they exchange and verify each other's SSL/TLS certificate chains (usually it's only server presenting its certs and the browser verifying them, but you can also install client certificate and a key in your browser)
the browser sends the HTTP request over TLS (in case of HTTPS) or over bare TCP (in case of HTTP) to the server.
the server running software appropriate to execute your app routes the request to it to obtain a response that it will send back to the browser.
Points 1, 2 and 6 do not require any setup from you side.
For point 3 to work, you need to have a proper DNS record on some public DNS server.
For point 4 to work, your server needs to have a public IP address assigned by an ISP.
For point 5 to work, your server needs to have installed a valid SSL/TLS certificate issued by some certificate authority (you can skip it if you need only HTTP)
For point 7 to work, your server needs to have appropriate software and your app installed similarly as your local dev machine.
There are a lot of services available that provide all 3 or some subset of them for you, some of them even for free up to some capacity.
Let's start with a server and an IP address:
the most hardcore and low-level approach is to buy a public IP from your ISP and host your app on your local machine. this is not recommended however because of availability issues: whenever there is any network or power outage or if you turn off your machine, your app will be down. other solutions provide much better level of service (they have redundant power sources, internet connections and staff making sure that everything works 24/7)
a bit higher level approach is to buy a virtual or dedicated server from some hosting company (search the web for "VPS", "dedicates server" or "VM hosting" to find one in your area. Well know global ones are for example Google Cloud Compute Engine, AWS EC2, M$ Azure, OVH). These companies will provide for you a server with a public IP, full administrative access (via SSH usually) and some guarantees on it's availability (usually ranging from 99% to 99.99% -> the more 9s the more expensive it is). After that you will need to install and configure all necessary software to run your app on such server. These companies often offer DNS entry in their subdomain and an HTTPS ceritficate in a package for a small to even zero fee. Many of them also offer packages containing a separate domain of your choice and sometimes a certificate.
the most high level solution is a cloud app service (like mentioned in the other answer Heroku, AWS Beanstalk, Google App Engine, kubernetes cluster etc). These services will provide a configurable size pool of instances hosting your app with some load balancing in front of them. This will make your app easy to scale and have a very high availability rate. This is the best solution in most cases: just make sure that the given service provider supports technology stack required by your app. Again, companies providing such services often have packages with DNS entries and HTTPS certificates.
If you need to buy a DNS domain separately (you didn't like any of the packages offered by the server provider) just search for "DNS names" or "domain names" and you will find a lot of resellers. These resellers will provide you a console where you can bind IP address of your server to the DNS name.
Finally if you need to obtain SSL/TLS certificate, you can also search for providers on the web or you can use free automatic certs from https://letsencrypt.org/
That's pretty much it.
Our customers connect to our databases exclusively with jdbc thin client calls on the SSL port, authenticating externally with PKI certificates in keystores. I would like to collect some of their client certificate information at logon time, as I would be able to do using OWA_UTIL.GET_CGI_ENV if they were connecting via https.
I've researched this for quite a while now, and I've found something in the SYS_CONTEXT userenv parameters called AUTHENTICATION_DATA that seems promising. However, the documentation states only that for users connecting externally with x503 certificates (do they mean x509v3?), that parameter contains "Data being used to authenticate the login user. For X.503 sessions, returns the context of the certificate in HEX2 format."
That's all Oracle has to say about that. No documentation of "HEX2 format" exists. No explanation anywhere about how to view the authentication data.
Does anyone have any experience using that data or at least reading what it really is?
I came across this online document, and from there there is slide about GWT Offline authentication:
When online, authentication is done by the server.
We should then be able to re-authenticate him/her without the server.
Be careful ! Local storage completely unsecure !
We thus store the user’s password in the browser, salted and
crypted with SHA-3.
Find a Java SHA-3 implementation, copy-paste in the project :
String shaEncoded = SHA3.digest( String clearString );
Offline HTML5 apps with GWT 18
The questions are:
Is it really possible to securely authenticate a GWT application with this approach? If it's SHA-3 encoded would it really make it secure?
When user gets authentiated in the browser, then user uses the offline app, say save stuff, then surely it is just stored in the HTML5 Storage, however with the User info embedded perhaps in anything saved. Thus, when app gets back online, it will sync to the server. How is this secure? Would the server just accept that the thing it is syncing really is from the right user?
There is no special case for offline regarding authentication. It works the same as with online.
You will usually have a Cookie with session information stored in your Client's browser which is used to authenticate the client with the server (when you are making a request).
As long as the session information is persistent on the backend, you can re-authenticate the user.
You must not store the password on the client side. Its is enough to store some session information on the client (either in a Cookie or LocalStorage) and use that to authenticate the user.
Actually you are not storing the password itself in the browser, but its SHA-3 hash.
From a cryptography perspective this approach is very secure as it is not easily possible to retrieve the original password.
Just note:
Your code will be stored on the client side and every source code on the client can be tampered with. So also a malicious user might be able to read and exploit it.
But don't worry, for the ordinary use case of an offline usable application, this is secure enough.
What I would do for long running server sessions:
Generate a random ID on the server side, associate it with the user and store it i.e. in a database.
Set the ID as a cookie on the client and re-authenticate the user whenever he is not logged in and still has this ID in a cookie.
To limit the amount of time you can add a timeout value on the server side after which the ID is discarded.
I'm using spnego http://spnego.sourceforge.net to make a single sign on on my system, the problem is that also typing the right password it will be prompt again and again.
Sometimes if you type it twice you can join the system, sometimes you need to type more than 10 times the same user and password until get access to the system.
After you are logged in to the system, the password can be prompted many times on random time, again and again and again.
Thanks in advance
I've not tried that specific spnego module yet, but I've encountered this issue before.
The issue with SPNEGO and two login prompts is often related to:
The application's login service is configured to allow both negotiate and basic:
WWW-Authenticate: Negotiate
WWW-Authenticate: basic
If Windows Native Authentication is enabled in Internet Explorer, but the Windows client fails to retrieve a Kerberos ticket for the service (for some reason), IE will
Prompt for login, but no matter what you write here it will send an NTMLSSP token using
Authorization: Negotiate
Authentication using the NTMLSSP token will fail and you'll get a secondary login prompt, which will be submitted using Basic
Authorization: Basic
Not sure why authenticating more than two times sometimes will let you in, though..
To investigate the problem further:
Check server log files (set java option -Dsun.security.krb5.debug=true and web.xml spnego.logger.level=1) for clues.
Check that the Windows client is logged on to domain.
Check that Windows Native Authentication is enabled in Internet Explorer.
Check that the website is added to local intranet sites in Internet Explorer (or available without using dot "." in the web site name).
Check that keytab, krb5.conf and login.conf is configured for your app server. (See spnego docs pre_flight and reference_docs)
Check that the principal name used in the keytab is the DNS A record and not a DNS CNAME record for your service.
An excellent tool for debugging web traffic is Fiddler2. Install and see what Internet Explorer responds to the authentication challenges (HTTP 401).
If Internet Explorer indeeds submits an NTMLSSP token, you might also want to use Wireshark and filter "Kerberos" traffic to see if your domain controller responds with a TGS-REP containing a Kerberos ticket for accessing your service.
If you're still out of luck, we'll might be able to help you further if you can make available all or some of
spnego configuration
Server logs (if anything relevant)
Fiddler2 trace
Wireshark trace
Øyvind
I found the problem.
The credentials was valid but it was from another domain ( I changed the domain but did not update the keytab file)
After fix the keytab the system never asked for a password anymore.
Thanks all !
I've got two servers, lets call them server 1 and server 2. There is a web application on server 2, that, lets say, shows posts. This application is available on http://www.2.com/showPosts and everybody can access this page. This application also enables to remotely add posts. To do that you have to go to page http://www.2.com/addPost and fill a form.
What I'd like to do is to restrict access to this second page (/addPost) to only one single machine, that is server 1, so that only I can enter this page and fill this form, and everyone else gets 404. How to accomplish that?
edit:
Thank you for your answers. I've done some more reading based on them and now can make my question a little more precise. What I exactly need to do is to authenticate a client by server, whis is the opposite of one-way ssl authentication, where you authenticate a server by a client. I think that any kind of ip based authentication is way too weak and I need some kind of a certificate.
You could use a .htaccess file in the root directory:
<Directory AddPost>Allow from www.1.com</Directory>
This only lets www.1.com access the page. If AddPost is a file, use <Files AddPost></Files>.
Hope this helps!
Protect your http://www.2.com/addPost with a cerificate only present in the Browser on the one single machine.
ServletRequest#getRemoteAddr() returns you the IP of the client that sent the request. You could filter such requests by matching client's IP. For the other clients you can for example redirect to predefined 404 error page.
You can also restrict the addPost address to localhost-only, and establish an ssh tunnel for update purposes.
I suppose you are using Apache Web Server, then you can configure a virtual host and set an access rule to deny from all, allow from server1. Here the documentation.
If it is a Tomcat server you can define a filter in web.xml that will filter request only from allowed source.