I tried to do SSO with web services with jasig CAS.
I did the security for web application using spring filters, but I don't know how to do it with web services on the server side.
We do this with a combination of the rest client (https://wiki.jasig.org/display/CASUM/RESTful+API) and the CasLoginModule (https://wiki.jasig.org/display/CASC/CASLoginModule+for+JAAS+applications) through JAAS (https://wiki.jasig.org/display/CASUM/JAAS) . It works like this:
The client sends down a username and password to your web service who authenticates and validates this against the CAS server. After this, the CASLoginModule caches the resulting service ticket so that future requests that can provide a service ticket don't need to contact CAS again.
This is quite a long way out of the "normal" usage of CAS because essentially it makes the service ticket a long lived item. Normally the ST should last long enough for the resulting service to validate the client. In my case I figured that it doesn't matter too much because all of our communication is on the server-side behind a firewall but this may be different for you.
Related
I am trying to implement CAS validation on a Webserver that receives restful requests I only care if the ticket is valid then I can continue doing the operation. So web app A provides the client with content, the client will then do a post to restful webserver B. Webserver B will validate their ticket, and proceed.
I will only have access to the endpoints of the CAS server, no helper classes, dlls etc.
Here is the ticket provided, I'm positive it is correct. I pulled it from the web app that has the user logged in.
ST-3285-1AijQkayTlcWSXQIVHUP-svvautht01.domain.org
the service that was requested was http://localhost:15559/WebApp/Main
Here is the endpoint I am calling.
https://svvautht01.domain.org:8443/cas/serviceValidate?ticket=ST-3285-1AijQkayTlcWSXQIVHUP-svvautht01.domain.org&service=http%3a%2f%2flocalhost%3a15559%2fWebApp%2fMain
I have tried the service with unencoded URL and both return the response below.
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationFailure code='INVALID_TICKET'>
Ticket 'ST-3285-1AijQkayTlcWSXQIVHUP-svvautht01.domain.org' not recognized
</cas:authenticationFailure>
</cas:serviceResponse>
I don't understand what I could be doing incorrectly. I can physically see that this is the correct ticket!
This is the Apereo jasig CAS found here wiki jasig
CAS Service Tickets by default have a lifetime of 10 seconds , after this time CAS itself will validate the user and any further validation requests for the same ST will show invalid ticket error
Is it possible to block connections to a web service (server) from outside its domain?
For example consider a web app that fetches data from Twitter's API using Twitter's "application only auth". The web app's client uses AJAX to call it's own server, which in turn calls Twitter's API with Twitter's token.
While the token is never exposed to the client side code is there anything to stop an outside server side app from calling the web app's server using the URLs used by the client and for example exhausting the Twitter tokens rate limits?
Is it possible to block connections to a web service (server) from outside its domain?
Certainly. Set your web server's access control lists to drop connections from outside of your IP range. Alternately, install a firewall. That's very straightforward, but I suspect you mean something else by "outside its domain?"
From your description, you seem to be really asking whether you verify that you're only talking to your own client application. As a general rule, no. You can authenticate users. That's easy. If the user isn't logged in and authorized to use your service, you don't forward requests to Twitter. But you can't authenticate applications.
If you're going to accept any user who shows up, you can't stop them from using whatever client they want. There is no way to ensure that it is your unmodified client if you've allowed it to be run on their machine. They can always modify it, and they can always send you arbitrary traffic from other programs and you can't tell the difference. On the network, bytes are bytes.
It's not all hopeless; there are things you can do. See https://stackoverflow.com/a/9183066/97337 for another version of this question, and links to several other versions of the question. (They're not exactly duplicates in how they're asked, but they all wind up being basically the same answer.)
You should secure your web service with user and password security or certificate security. The basic idea is that the web service client must authenticate in order to call your web service.
Here are some technics (there are others or variations):
1) HTTP basic authentication and HTTPS
2) Mutual SSL authentication - Also called two-way authentication, is a process in which both entities authenticate with each other. The server presents a certificate to the client and the client present a certificate to the server.
3) With SOAP web services you can use WS-Security standard.
4) OAuth framework
5) With Rest services you can use options 1), 2), 4). Or implement one by your own. This are good recomendations.
As you can see, there are a lot of ways to secure a web service.
I am developing several Web Services that will be accessed by a mobile application. I have several requirements:
Each user will need to sign in with their own User ID and Password (the same User ID and Password they use to sign into the website).
Every Web Service request will need to be authenticated to ensure that the request is coming from the mobile app(s).
Every Web Service request will need to authenticate the user, since there is user-specific fucntionality built in, and access will need to be blocked if the user's account is disabled.
Let's assume that OAuth is not an option.
In order to ensure that Web Service requests are coming only from the mobile app(s), I am planning to use HTTP Basic Authentication in IIS (the mobile app(s) will need to have a User Account setup in Windows Server and the mobile app will need to store the User Name & Password and pass these in the header).
Next is the User Authentication for each Web Service request. Would it be suitable to encrypt the User ID, Password, and some shared secret key (a "pepper", of sort) with AES-256, pass that encrypted string as a parameter with each request (over HTTPS, of course), and then decrypt and parse it on the server to authenticate? This is the existing plan, but something just doesnt seem right about it - like it's not "secure enough".
What else can I do to properly authenticate users for Web Service requests?
I recently went through this problem and asked opinions from a group of senior people about how they solve the problem. Opinions were varied, but one consistent feeling is that your level of security depends on the use case of your application. Are you doing online banking or storing medical records? Then your security needs may be quite high. Social networking? Maybe not so much.
Basic Authentication is generally fine when encrypted over SSL, ColdFusion works well with it. If you use Basic Auth, make sure to encrypt your traffic with 1024-bit keys or better. Don't authenticate every request with username/password - that's unnecessary. Authenticate the first request, set a session token, and rely on the session token for your identification of users.
Set a polling mechanism from the client to the server to keep the session alive - set the session timeout to 30 minutes and the polling frequency at 25 minutes, for example. Otherwise you may need to re-authenticate expired sessions. Again, how you approach this part of the solution depends on your paranoia level, which depends on what kind of data/app you are dealing with.
Cookies, and therefore sessions, should work fine in iOS apps. If you use sessions to verify identity after authentication, make sure your session cookies are memory-only (set at the server level).
Check the SSL implementation of your server against the Qualysis SSL Test:
https://www.ssllabs.com/ssltest/
The report will give you a surprising amount of detail about the strength of your SSL implementation.
Lastly, consider implementing two-factor authentication to combat password theft.
If you ignore the SSL advice and plan on encrypting your password and communicating over an insecure channel, look at the Kerberos protocol for a well-known example of how to authenticate securely:
http://en.wikipedia.org/wiki/Kerberos_%28protocol%29
Yes, you can use Basic Authentication but that means the client will need to store the username/password in plain text, and also send them over in plain text. Sending part is sort of fine if it's under HTTPS, but storing username/password in plain text may not be a good idea, unless you're using some secure key store.
Let's assume you have decided that Basic Authentication is the way to go, and you want to make use of the official CF way of supporting that, then you can use CFLOGIN.name & CFLOGIN.password. You may also check out Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion. In the remote cfc side, always validate the username/password, or return some sort of token and asks the client to use that token going forward. The token can be cfid+cftoken if you like, or even roll your own that never expires. If you use cfid+cftoken, and send them over as cookie or in body along with your web service call, I believe you can resume the session if you so choose.
I am implementing a Java EE based Hospital Management System that has a web service and two clients are to be connected to it, a Java Swing App and a JSP-based web project. The web service is to be implemented using Stateless EJBs.
Please suggest a way of implementing authentication and login for both clients (Users are taken from database-DB2)
NB: This has to be submitted as a project so server(Websphere) based authentication should be avoided as much as possible. Could not find any resource corresponding to this scenario..
I suppose that users will authenticate to both applications with username (and password). If you don't need user authorization on the service side, you can just create username/password combination for each client and store it in web service configuration file. In that case i would suggest message level security for clients.
http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=%2Fcom.ibm.websphere.express.doc%2Finfo%2Fexp%2Fae%2Ftwbs_securews.html
In case you need user authorization on service side, you can still rely upon message level security but proceed users credentials instead.
Here are also some examples which might be helpful:
http://www.mkyong.com/webservices/jax-ws/application-authentication-with-jax-ws/
http://www.ibm.com/developerworks/websphere/tutorials/0905_griffith/section7.html
To casify web service I am planning to follow the following:
I have a application that requests for a web service, the web service will only server the client if the application passes a valid ticket string.
The Java application sends a username/password combination to the CAS server using restful API.
The CAS server replies with a ticket on successful authentication.
The application sends the ticket my web service and ask for some data for some data.
The web service receives the ticket and sends the ticket to the CAS server to validate it.
If the CAS server returns a username/ or any kind of message that confirms the validity of the ticket, the web service replies back to the application a response to fulfill the application request.
The CAS server is returning the ticket to the application,the application posts the ticket string to web service, the web server accepts the ticket string. Now how do I send the ticket to CAS server for validation? Any ideas? Also is there any better way to casify the Web service?
I tried to draw what I want to archive:
Since this is a java based application you can use the filters that are available with CAS to do the validation & authentication.