REST API user management URIs - rest

I am writing REST APIs in a MEAN application for user management. Although I normally follow best practices for REST APIs, I do have a security concern about exposing too much detail for user accounts API in the URI.
I would prefer not to include the username or account ID as part of the URI when trying to access a specific user account resource:
/api/accounts/:id or /api/accounts/:username
The one alternate approach I have come across is the use of "me" instead of the resource id:
/api/accounts/me
Most of the use cases I have seen only use GET, but I would like to use this for PUT/POST operations as well:
PUT /api/accounts/me/password
{"oldPassword":"xxx", "newPassword":"yyy"}
Do you think this is a good way? Any other ideas?

Related

Standard REST API Design Convention

Speaking of strict REST API design conventions, can a single resource correspond to multiple routes.
For example, I have the routes:
http://www.example.com/registrations
http://www.example.com/confirmations
http://www.example.com/unlocks
All these endpoints make use of the user resource to register a new user, confirm a user using confirmation token, and unlock a user using unlock token.
Is this correct REST design?
Well it's not wrong, but on top of that you're also probably going to have a /user endpoint, so there might be better ways of scaling this.
For example, the unlock might simply be a PUT on said /user, with a
{
"state": "unlocked" //active, whatever
}
I don't know the full extent of your API, but you can play with either http verbs like I did above, or POSTing different payloads to the same endpoint (for example having a confirmationToken as a property in the body for Registration, and reusing that endpoint, too).

Custom authentication for REST client

We are looking to take an approach where there are service accounts in MarkLogic, but not accounts for all actual users. We would use a custom authentication token, JSWT in this case, and then via xdmp:login, elevate the calling user to the appropriate roles.
This is all fine if we create a custom HTTP server with our own rewriter to our modules. If we want to leverage the already built out REST API, is the only option to essentially create a wrapper around each of the XQuery modules that get dispatched to from the REST rewriter, in order to call the xdmp:login flow prior to fulfilling the rest of the REST api workflow? I did not see any way with the enhanced HTTP rewriter configuration to run arbitrary XQuery code before the dispatch flow.
Is this a feasible idea, or just a bad idea?
Best practice with the REST API is to use a middle tier. Exposing the REST API directly to your end users is analogous to doing so with an ODBC connection -- something you generally wouldn't do.
My suggestion is to set up a middle tier and use that gather credentials, then login as needed.
You can modify the out-of-the-box REST API endpoints to perform an xdmp:login, but of course that creates complexity when performing an upgrade, and when deploying an app. That's really a worst-case scenario.
Are you able to map all of your users to a much smaller set of ML users, perhaps on the order of dozens? Then a middle tier can do something similar to xdmp:login - it can look at the user's profile and determine which ML user to connect to ML with. That's not quite as flexible as xdmp:login, which lets you pick any roles you want without creating a user as a holder for them, but it may do the trick.

RESTFul API endpoint design with filtering and authorization

I am designing a REST API with consumers that have different permissions. I understand that a representation of a resource should not change according to user. Therefore I am trying to determine which is the best approach:
GET - list collection of all documents - admin only.:
/api/documents
GET - list collection of all documents - any user with access to document 123
/api/documents/123
For normal users therefore should the endpoints be
list all documents for user 12
/api/user/12/documents
document 123 assuming user 12 has access
/api/documents/123
OR... should the end points be as below and a query string filter used:
/api/documents?user=12
/api/documents/123
In this case you can get away with just two endpoints (and one header!). Make sure the API for /documents is returning the Vary: Authorization header. Then you can use
GET /api/documents // return all docs the logged-in user can see
GET /api/documents?userId=bob // return all of bob's docs that the logged-in user can see
GET /api/documents/123 // return doc 123 if the logged-in user can see it
It is not entirely unreasonable to nest the user a la GET /api/users/bob/documents. I find it to be harder for end users to learn APIs with a large number of endpoints, and I feel that the nested approach tends to create many endpoints. It's conceptually easier to go to /documents and see what you can filter on, rather than look at each endpoint and see what filters it has.
I would keep business logic and authorization logic entirely separate. If you want to retrieve document XYZ, you wouldn't pass the user id as an HTTP parameter.
You suggested /api/documents?user=12 but in fact it should just be /api/documents. The user information should come from the authentication layer.
Similarly authorization should be entirely separate. The reasons for that are:
separation of concern
ability to update authorization logic independently of of business logic
avoid impact on API design
The API should only reflect those business objects you care about e.g. documents in this case (possibly also users should you wish to display a user profile...).
To handle authentication, use the container's standard techniques (e.g. HTTP Basic authentication) or use advanced authentication techniques (OAuth..) via a dedicated framework.
To handle authorization, use a filter, an interceptor. In the Java world (where JAX-RS implements REST), have a look at the Jersey interceptors and filters. You then want the interceptor (or policy enforcement point - PEP) to query an external authorization service (or policy decision point).
Have a further look at ABAC, the attribute-based access control model, and XACML, the eXtensible Access Control Markup Language which explain how to control access to your REST APIs without mixing business logic and authorization logic.

How to secure Rest Based API?

We intend to develop rest based api. I explored the topic but it seems, you can secure api when your client is an app (So there are many ways, public key - private key etc). What about websites / mobile website, if we are accessing rest based api in website which do not use any login for accessing contents ( login would be optional ) then how could we restrict other people from accessing rest based api ?
Does it make sense using Oauth2.0 ? I don't have clear idea of that.
More clear question could be ,How can we secure get or post request exposed over web for the website which doesn't use any login ?
If it's simple get request or post request , which will return you json data on specific input, now i have mobile website , who will access those data using get request or post request to fetch data. Well, some else can also access it , problem is i am not using Login, user can access data directly. But how can we restrict other people from accessing that data.
What do you think is the difference between securing a website that is not using REST vs one that is using REST API?
OAuth provides authorisation capabilities for your site, in a REST architecture this means a user of the mobile application will have to provide their credentials before being allowed to access the resource. The application can then decide on if that user has access to the requested resource. However you've said your website doesn't need use authorisation.
You can use certificates however good luck managing the certificate for each client. My take on it is for your explanation you don't need to secure your website because you will never be able to manage a trust relationship between the client and the server. There are some options though:
You build your own client application that you ship out to people which can verify itself with the server using a packaged certificate with the client. E.g. iOS has this kind of feature if you build for that device.
You provide a capability to download a certificate that is 'installed' in the browser and used when communicating to your REST API
Use something like a handshaking protocol so when a client wants to make the first request it says; 'hi I'm a client can we chat?' And the server responds with 'yes for the next X minutes we can however make sure you send me this key everytime you tell me something YYYYYY' (you can use something like SecureUDID or equivalent for other devices than iOS).
There are probably others but you get the basic idea. Again in my opinion if your resource doesn't need authorisation then you don't need to secure that REST API. Can I ask what kind of data are you exposing via this REST API or functionality your providing? That might help provide a better answer.
You want authorization: only some agents (mobile clients) and/or users should be allowed to access those APIs.
To solve that problem, you need identification: a way for the server to tell who is who (or what), so the right decision can be made.
There are many different way to provide some form of identification, depending how much you care about security.
The simplest is a user agent string, specific to your mobile clients. But it can be faked easily. Slightly harder to fake are client based 'secrets' - embed some kind of secret or key in your mobile client code. You can make it really complicated and secret, but as ramsinb pointed out, you can't get security this way as it would require you to be able to guarantee that the secret you're shipping with the client (wether it's code, algorithm or any other fancy construct) can't be compromised or reverse engineered. Not happening when you don't control the client.
From there, 3 choices:
Security isn't really required, don't bother
Security isn't really required, but you still want to limit access to your API to either legit users/agents or people ready to invest some time hacking your protection - go with a specific user agent or a client embedded secret - don't invest much into it as it won't block people who really want access to get it anyway
Security IS required - and then I don't think there is a way around authentication, wether it's login/password, user specific (device specific?) keys, OpenID, etc... No matter what, you'll have to add to the user burden to some extent, although you can limit that burden by allowing authentication to persist (cookies, storage....)

Usage of SAML attribute AttributeStatement

in SAML 2.0 you can use the AttributeStatement element to provide any kind of application specific information.
What I was wondering, is it really good design to pass business related information within a SAML assertion? Shouldn't this data be provided in a e.g. separate web services call?
I just want to ask for best practice in this case or any real world experiences.
Regards,
Andreas
It depends a lot on just what information you're conveying. For instance, on the application I work on, we use attributes to indicate what web site features should be shown to the user being logged on. That's clearly an appropriate use. Now, we also allow use of attributes to create a user profile, even though we have a web service that does the same thing (and in fact, the implementation calls the web service behind the scenes). It's not an ideal context for that sort of thing; there's no endpoint to convey the web service response to, or any errors resulting from the attempt. But we get a fair amount of resistance from customers, who don't want to have to call a separate web service before they can make an SSO call. So we've had to compromise. What we've done is require that if a customer wants to use this particular functionality, that they provide an endpoint (either email address or web page) to receive errors from the web service call. And if they're concerned about security of the information being conveyed, they can use standard XML encryption.