Shiro/Stormpath via REST - shiro

I'm new to Shiro. We are attempting to use Shiro with Stormpath. I've been trying to dissect the examples to come up with a solution to what I want to do, but I'm unsuccessful so far.
For now, I'm simply trying to create REST services to do what I want, and I'll tie a real client in later. This is what I'm trying to achieve as my first step:
I want to have a client hit a REST endpoint (login) on my server. My server would authenticate, and return a JWT to the client. This JWT would then be used to access secured endpoints on my server. (I have written Java code that can successfully authenticate against Stormpath).
My problem is the JWT. I expected that a JWT would be created for me, or at least easily accessible. I can't find a way to get one. I have seen sample code on how to build one, but that doesn't seem like the way I would expect to acquire one.
I have run through several examples, but most seem to deal with JSP interfaces, and I can't seem to make the leap to what I'm trying to do.
Is this approach reasonable? Any guidance is appreciated.
Edit 1
I now have a Java client that can authenticate using the Shiro servlet and retrieve a JWT. I have this running as a deployed application (war) in GlassFish. My next step is to use that JWT to authenticate against a different application that has my REST endpoints. This REST application doesn't need to know anything about how to authenticate - I just want to pass the JWT along in the call to a given REST endpoint and use Shiro (via annotations) to control access to the endpoint (if that is indeed possible). All of the examples I can find seem to be "all-in-one" examples (bundling JSP with Shiro/Stormpath configurations, etc). I'm trying to determine the minimum working configuration for securing REST endpoints and I'm having difficulty determining which pieces of the configuration I need.
Edit 2
I am using the Stormpath-Shiro-Servlet (as stolen from the Shiro Servlet example) as my authentication back-end. Using my Java client, I am sending a login request to the servlet, and I am indeed getting back a JWT. However, I am not able to successfully use the JWT to access my other rest resources. My rest calls result in this error:
org.apache.shiro.authz.UnauthenticatedException: This subject is anonymous - it does not have any identifying principals and authorization operations require an identity to check against. A Subject instance will acquire these identifying principals automatically after a successful login is performed be executing org.apache.shiro.subject.Subject.login(AuthenticationToken) or when 'Remember Me' functionality is enabled by the SecurityManager. This exception can also occur when a previously logged-in Subject has logged out which makes it anonymous again. Because an identity is currently not known due to any of these conditions, authorization is denied.
First, I don't understand why the servlet 'login' doesn't actually log me in and give me non-anonymous principle? Second, I am attempting to do everything on a separate client, so I don't have access to Subject.login (is this a correct assumption?).

Take a look at this example from github/stormpath-shiro
The JWT creation is managed for you by the Stormpath API. If you start up one of the examples, (the servlet one above, or the spring-boot-web example), after login, you will have a JWT cookie. There is background info in this blog post.
I'm working on releasing strompath-shiro now, but figured I'd include these link here so you can start looking.

Related

How to protect an API endpoint for reporting client-side JS errors against spam (if even necessary)?

I am developing a web application with Spring Boot and a React.js SPA, but my question is not specific to those libraries/frameworks, as i assume reporting client-side JS errors to the server (for logging and analyzing) must be a common operation for many modern web applications.
So, suppose we have a JS client application that catches an error and a REST endpoint /errors that takes a JSON object holding the relevant information about what happened. The client app sends the data to the server, it gets stored in a database (or whatever) and everyone's happy, right?
Now I am not, really. Because now I have an open (as in allowing unauthenticated create/write operations) API endpoint everyone with just a little knowledge could easily spam.
I might validate the structure of JSON data the endpoint accepts, but that doesn't really solve the problem.
In questions like "Open REST API attached to a database- what stops a bad actor spamming my db?" or "Secure Rest-Service before user authentification", there are suggestions such as:
access quotas (but I don't want to save IPs or anything to identify clients)
Captchas (useless for error reporting, obviously)
e-mail verification (same, just imagine that)
So my questions are:
Is there an elegant, commonly used strategy to secure such an endpoint?
Would a lightweight solution like validating the structure of the data be enough in practice?
Is all this even necessary? After all I won't advertise my error handling API endpoint with a banner in the app...
I’ve seen it done three different ways…
Assuming you are using OAuth 2 to secure your API. Stand up two
error endpoints.
For a logged in user, if an errors occurs you would
hit the /error endpoint, and would authenticate using the existing
user auth token.
For a visitor, you can expose a /clientError (or
named in a way that makes sense to you) endpoint that takes the
client_credentials token for the client app.
Secure the /error endpoint using an api key that would be scope for
access to the error endpoint only.
This key would be specific to the
client and would be pass in the header.
Use a 3rd party tool such as Raygun.io, or any APM tool, such as New Relic.

REST API Security JBoss EAP 6.4

I am coding a webapp (E-commerce) for learning purpose using AngularJS + BootStrap and REST.
I have used Apache Wink for REST WS and and application is deployed on JBoss EAP 6.4. My application is working fine.
I can access the back end data using AJAX and webpages are getting populated properly. The issue is security of REST WAS. If I use REST URL directly on browser, without going through front end, JSON data gets populated and my data is exposed. What design changes should i do ?
Please note that initial operation on the website for e.g. browsing the products, adding them to cart etc are stateless. No user's identity is needed for these operations. I still need to secure my data for these interactions. Please suggest, how can I do it.
Sunil
If you want to lock down the services, you may require some type of authentication (for example user/pass) that returns a security token (over https). Then all subsequent function calls may require the security token to be passed in as a parameter (if the operation is sensitive). The token will require a session timeout.
However, if the data is also publically shown on the site, then there's not really a security risk in itself. IOW, how is this any different than them using the public website to get/update data? The rest services usually shouldn't require any additional level of security beyond what is already used on the website to protect the data.

FOSOAuthServerBundle Create Client

I'm currently trying to setup FOSOAuthServerBundle with my Symfony2 app.
Everything seems to be setup and functional, anyway I'm stuck after the installation.
What is the proper workflow with URLs to get the access_token ?
I tried /oauth/v2/auth, but sounds like I need to define a Client object first.
How to create/generate Client ? Clients are always supposed to be created manually ?
FOSOAuthServerBundle doc is great, but seems to skip all the usage workflow. Am I supposed to check the OAuth2 doc for this ?
Thanks !
In short, yes. You should be using the oAuth2 RFC to determine which workflow you want to use. In regards to client registration the RFC specifically states that the means through which a client registers is beyond the scope of the specification (https://www.rfc-editor.org/rfc/rfc6749#section-2).
With that being said I can give you some insight into how I did this. My application is a mobile phone application that connects to several services running on various servers. I'm also using the Resource Owner Password Credentials Grant.
The way I approached this was: when the application loads, the first thing it does is to check if it has an oAuth2 client id. If it doesn't, then it POSTS to a create client endpoint I've setted up with the meta-data I need. The endpoint validates the POST, creates the client and returns the client information. The application stores the client id and the process doesn't have to be repeated the next time.
Application loads;
Application checks for oAuth2 client id;
If there is one, the process ends;
If there isn't, it posts to http://www.example.com/client;
If we get a 200, store the oAuth2 client id.
I could have also created the oAuth2 client when the user created an account in the application, but I wanted to make the registration process as fast as possible. Creating the client would have added some extra waiting time to the process.
Check this: http://blog.logicexception.com/2012/04/securing-syfmony2-rest-service-wiith.html
It's quite simple to convert to Doctrine, whether you use it.
There's a command-line that does exactly what you need: create a Client!

web.xml, using form and basic authentication simultaneously

I have setup FORM-authentication within web.xml (java-webcontainer) successfully.
I did not find a way to sent the username/password within the get-request of the restful-uri from my client when using FORM-Authentication. So I have to use BASIC-Authentication only for the restful-uri.
So I have this question:
How can I set up both form-based authentication and basic authentication?
Basic authentication should only be enabled for the restful-uri.
I was also facing a similar problem and I realized that if you are using Wildfly then its possible to configure multiple mechanism using web.xml:-
<auth-method>BASIC?silent=true,FORM</auth-method>
Using this silent basic authentication will be tried first, which is basic authentication that only takes effect if an Authorization header is present. If no such header is present then form authentication will be used instead.
Maybe its too late for a reply but I just updated this in case someone finds this useful :P
There were no responses here for a while, so I did a quick servlet refresher myself. Servlet specs indeed allow only one <login-config> element per web application, so there is no way to have an entry point with BASIC authetication for the REST API and another with FORM-based authentication for the UI. The only option is to build them as two independently deployable applications. To avoid code duplication, it might be a good idea just to let the UI application talk to the REST API the same way the third-party clients are supposed to.

maintaining session in REST web service

I have a COTS application(PLM application) which has provided few SOAP APIs to access. Since this SOAP API is highly complex, we are developing a easy to use REST wrapper service. Before invoking any API in my COTS application, authentication API needs to be invoked. In my REST wrapper web service, I have a login resource which invokes COTS SOAP login API. To keep things simple for my API users, I store the logged in user details in user session. In every other REST resoruces, I retrieve the session and check whether session has user details. If yes, I proceed and invoke the SOAP API. if not, I return proper HTTP status code. I use Apache CXF for service and client. I mandate my APIusers to maintain the session in the client like this
WebClient.getConfig(client).getRequestContext().put(Message.MAINTAIN_SESSION,
Boolean.TRUE);
In every REST tutorials, it said REST is stateless. I am doubtful whether what I am doing is correct as per REST standards. Please suggest. Thanks
Basically the idea of REST is a stateless interface. However it is common practice to use some kind of authentication for API calls since most of the time not all resources should be public (e.g. the timeline of a twitter user over the twitter API)
Therefore it is ok if you do some kind of authentication and validate a session on further requests (or maybe authenticate with every single request, e.g. with HTTP Basic Access Authentication) to check if access should be granted.
Not part of this and not the idea of a RESTful API would be to store complex session information that would really make the whole thing stateful. This for example includes storage of information of an older request for processing together with one following later.
client.getRequestContext().put(Message.MAINTAIN_SESSION, Boolean.TRUE)
This code causes cookies to be maintained in that specific client only.
If you want those cookies be available in another client, it needs to be programmed.
And if the second client receives additional cookies and you want those cookies available in the first client too, how is that possible?
I need something like a root client that maintains cookies of all sub clients. All cookies must be shared among all clients. Like a shared cookie repository for all clients. Does anyone know how to achieve this?