Securing REST web service in GlassFish - web-services

everyone.
I have a problem securing my REST web service. It's part of Java EE web application. To secure the pages I used login-config tag and set up "FORM" authentication. Now I don't know how to secure web services, because "FORM" is not appropriate for it and I can't have two login-config tags for app. I considered splitting into 2 apps, but don't think it's a good idea. Any suggestions?

This has info on how to create secured web services using NetBeans: http://netbeans.org/kb/docs/websvc/wsit.html
Many web service providers use an api key to authenticate access to the service. You may want to consider doing something similar for your service.

It is pretty common for the REST API to have a separate subpath - that way you can specify the auth constraint just to the URL's specific to your application and for the URI's corresponding to your REST API implement authentication using jersey OAuth filter or something else.
In case your app is all written in Jersey and you would like to expose exactly the same URI's for REST clients as well as browser (and differentiate just based on the requested media type), you can have a "login" URL (for displaying a login page) and only that you could protect using FORM authentication. Then again you would add Jersey OAuth filter (or other auth filter) which would not kick in unless there is OAuth header in the request, and another filter where you would check if ContainerRequest.getUserPrincipal() is null. If it is null, you could return Response.seeOther(UriBuilder.fromPath("/login").queryParam("redirect", request.getAbsolutePath()).build()).build() - that will redirect to the login (for oauth this would not kick in, since either the oauth request would succeed, or the previous filter would fail and return Unauthorized or Bad Request status codes). In the login resource you can use the redirect query parameter to redirect back to the original page once successfully logged in.

Related

Accept only authentificated requests to backend

I have this question. I am quite new in this area.
I have web app.
This consist of services deployed on Docker engine.
The main services/containers are:
Frontend : React on Nginx web server
Backend (API) : Django, DRF on gunicorn on Nginx
For frontend I use Auth0 provider. It works as expected. If user is not authenticated/authorized it is redirected to login page.
Now I want also to "secure" my backend that it only would accept authenticated connections from frontend.
For backend (Django) I also have CORS enabled (django-cors-headers package), but I still can connect from my browser my-site/api/ and get the response.
Does anybody know which strategy should I use.
Should I somehow secure it using JWT tokens. Somehow pass it to backend in my request?
There is various ways of authorizing API calls from your front-end applications to execute actions on your back-end. These will tend to vary in a few aspects:
Complexity
Needing to know who sent the request
Access surfaces
Duration of access
Roles
and so on...
In this case if you have authenticated users on your front-end using AuthO then a JWT could make sense since using this method you can encode specific user data that will allow you to make the decision on your backend as to if that user should have access to that action at that time.
Here is an article explaining a few popular methods of authentication

Bypass OAuth validation when the request is a query

I have a web service which is validated by OAuth (Authorization code).
I am using Oracle IDM stack (OAM /Oath service , OES etc).
The issue is - I want to have OAUth validation only when a webService API is processed at the backend, but not when a client is just browsing a WSDL or XSD.
In my current implementation, I am using filter in the web.xml and I have added web service name ( which is web service Servlet) URL in the filters. The url to browse the service and execute the service, will have same name except the ?WSDL at the end of the URL, in case of WSDL/XSD query.
So, the problem is when I query WSDL, then also it goes goes via OAuth validation, which I don't want!
I tried to add logic to determine if the http query string is ?WSDL then by pass OAUTH validation, but it does not work because clients like SOAP UI and others can actually use ?WSDL in the URL, to even execute the web service API, which sort of fails the whole validation purpose.
Has anyone come across similar issue? how to resolve this issue ?

ServiceStack Auth API from PHP website

I have a ServiceStack API set up which uses the auth plugin to allow users to register through the api.
The front end UI is a PHP site. So when the user clicks 'log in via twitter' they are redirected to the ServiceStack API and then onto twitter, back to the ServiceStack APIv and then back to the PHP site.
My question is - how can I manage the auth between the PHP site and the ServiceStack API? Would giving the PHP site the auth token be the way forward? I'd want there to be some per request authentication - would I pass on some cookie info from the browser with each request?
[UPDATE]
So - the website is hosted at http://somedomain.com
and the api is hosted at api.subdomain.com
so they can share cookies
from that cookie the website can retrieve the ss-id, ss-pid and the X-UAId
I can see that the [Authenticate] attribute tries to get these values from the request
So... if we provide these values in the request the API should be able to authenticate based on that.
Except it can't
What else do I need to provide to allow this to work? Is this even possible?

Handle Authentication and Authorization in jax-rs webservice with cxf

I have a webapp which has jsps. am not using any struts or mvc framework. We have JAX-RS service build using Apache CXF.
Now i want to do following
Allow user to login with username and password.
For all subsequent calls to webservice, same authentication info should be used.
Logged in user has some details (profile photo, full name), which i want to keep it constant across session.
Also, its role are defined. Based on role(s) only certain jax-rs calls will be allowed.
Roles are also used in JSP to restrict access to functionality.
Web services can be accessed outside so authentication and authorization info should be used.
As far as i understand, We should not use session in jax-rs services. What is the best way to handle above situation ?
The best way depends on how you estimate it.
My way of doing this is to
Run Rest service and JSP on the same instance
Use web.xml and CXF to set up security policy, which allows user/pw authentication and authorization, ROLES binded to both jax-rs urls and JSP urls.
Based on 2, jax-rs services can be called directly outside, but user/pw is required as you specified.
Hope this can help you a bit.
Think cxf security validation as any other http or https validation. you have to intercept the request and pass it to the rest service. You can use any of the tools like siteminder, else can write CXF interceptor to do your own security validation. In the interceptor you can call SSO kind of token generator server in case you have the infrastucture or call the DB if your architecture is built that way. You can use caching to reduce the resource hits and can look at custom or hibernate cache. enabling Https has to be done in server configuration. If you have certificate , you can use the same else you can generate your own using openssl.

How do I implement login in a RESTful web service?

I am building a web application with a services layer. The services layer is going to be built using a RESTful design. The thinking is that some time in the future we may build other applications (iPhone, Android, etc.) that use the same services layer as the web application. My question is this - how do I implement login? I think I am having trouble moving from a more traditional verb based design to a resource based design. If I was building this with SOAP I would probably have a method called Login. In REST I should have a resource. I am having difficulty understanding how I should construct my URI for a login. Should it be something like this:
http://myservice/{username}?p={password}
EDIT: The front end web application uses the traditional ASP.NET framework for authentication. However at some point in the authentication process I need to validate the supplied credentials. In a traditional web application I would do a database lookup. But in this scenario I am calling a service instead of doing a database lookup. So I need something in the service that will validate the supplied credentials. And in addition to validating the supplied credentials I probably also need some sort of information about the user after they have successfully authenticated - things like their full name, their ID, etc. I hope this makes the question clearer.
Or am I not thinking about this the right way? I feel like I am having difficulty describing my question correctly.
Corey
As S.Lott pointed out already, we have a two folded things here: Login and authentication
Authentication is out-of-scope here, as this is widely discussed and there is common agreement. However, what do we actually need for a client successfully authenticate itself against a RESTful web service? Right, some kind of token, let's call it access-token.
Client) So, all I need is an access-token, but how to get such RESTfully?
Server) Why not simply creating it?
Client) How comes?
Server) For me an access-token is nothing else than a resource. Thus, I'll create one for you in exchange for your username and password.
Thus, the server could offer the resource URL "/accesstokens", for POSTing the username and password to, returning the link to the newly created resource "/accesstokens/{accesstoken}".
Alternatively, you return a document containing the access-token and a href with the resource's link:
<access-token
id="{access token id goes here; e.g. GUID}"
href="/accesstokens/{id}"
/>
Most probably, you don't actually create the access-token as a subresource and thus, won't include its href in the response.
However, if you do so, the client could generate the link on its behalf or not? No!
Remember, truly RESTful web services link resources together in a way that the client can navigate itself without the need for generating any resource links.
The final question you probably have is if you should POST the username and password as a HTML form or as a document, e.g. XML or JSON - it depends... :-)
You don't "login". You "authenticate". World of difference.
You have lots of authentication alternatives.
HTTP Basic, Digest, NTLM and AWS S3 Authentication
HTTP Basic and Digest authentication. This uses the HTTP_AUTHORIZATION header. This is very nice, very simple. But can lead to a lot of traffic.
Username/Signature authentication. Sometimes called "ID and KEY" authentication. This can use a query string.
?username=this&signature=some-big-hex-digest
This is what places like Amazon use. The username is the "id". The "key" is a digest, similar to the one used for HTTP Digest authentication. Both sides have to agree on the digest to proceed.
Some kind of cookie-based authentication. OpenAM, for example, can be configured as an agent to authenticate and provide a cookie that your RESTful web server can then use. The client would authenticate first, and then provide the cookie with each RESTful request.
Great question, well posed. I really like Patrick's answer. I use something like
-/users/{username}/loginsession
With POST and GET being handled. So I post a new login session with credentials and I can then view the current session as a resource via the GET.
The resource is a login session, and that may have an access token or auth code, expiry, etc.
Oddly enough, my MVC caller must itself present a key/bearer token via a header to prove that it has the right to try and create new login sessions since the MVC site is a client of the API.
Edit
I think some other answers and comments here are solving the issue with an out-of-band shared secret and just authenticating with a header. That's fine in many situations or for service-to-service calls.
The other solution is to flow a token, OAuth or JWT or otherwise, which means the "login" has already taken place by another process, probably a normal login UI in a browser which is based around a form POST.
My answer is for the service that sits behind that UI, assuming you want login and auth and user management placed in a REST service and not in the site MVC code. It IS the user login service.
It also allows other services to "login" and get an expiring token, instead of using a pre-shared key, as well as test scripts in a CLI or Postman.
Since quite a bit has changed since 2011...
If you're open to using a 3rd party tool, and slightly deviating from REST slightly for the web UI, consider http://shiro.apache.org.
Shiro basically gives you a servlet filter purposed for authentication as well as authorization. You can utilize all of the login methods listed by #S.Lott, including a simple form based authentication.
Filter the rest URLs that require authentication, and Shiro will do the rest.
I'm currently using this in my own project and it has worked pretty well for me thus far.
Here's something else people may be interested in.
https://github.com/PE-INTERNATIONAL/shiro-jersey#readme
The first thing to understand about REST is that its a Token based resource access.Unlike traditional ways, access is granted based on token validation. In simple words if you have right token, you can access resources.Now there is lot of whole other stuff for token creation and manipulation.
For your first question, you can design a Restfull API. Credentials(Username and password) will be passed to your service layer.Service layer then validates these credentials and grant a token.Credentials can be either simple username/password or can be SSL certificates. SSL certificates uses the OAUTH protocol and are more secure.
You can design your URI like this-
URI for token request-> http://myservice/some-directory/token?
(You can pass Credentilals in this URI for Token)
To use this token for resource access you can add this [Authorization:Bearer (token)] to your http header.
This token can be utilized by the customer to access different component of your service layer. You can also change the expiry period of this token to prevent misuse.
For your second question one thing you can do is that you grant different token to access different resource components of your service layer. For this you can specify resource parameter in your token, and grand permission based on this field.
You can also follow these links for more information-
http://www.codeproject.com/Articles/687647/Detailed-Tutorial-for-Building-ASP-NET-WebAPI-REST
http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
I have faced the same problem before. Login does not translate nicely to resource based design.
The way I usually handle it is by having Login resource and passing username and password on the parameter string, basically doing
GET on http://myservice/login?u={username}&p={password}
The response is some kind of session or auth string that can then be passed to other APIs for validation.
An alternative to doing GET on the login resource is doing a POST, REST purists will probably not like me now :), and passing in the creds in the body. The response would be the same.