Which HTTP status code is appropriate for this situation? - http

Let's say we have an API where users belong to specific tenants. If a user tries to retrieve data for a tenant they do not belong to, is it more appropriate/secure to throw a 403 or 404 error?
From one perspective, 403 makes sense as that user does not have access to the tenant. However, from another perspective, a 404 makes sense because we're not exposing that the tenant they are requesting exists.
Which approach would be considered better? My gut says 404

You should not expose any info across tenants. From one tenant's perspective a resource does not exist if it belongs to another tenant - they should not be able to differentiate. In other words, the error response should be the same for a truly non-existent resource, for one that is assigned to a different tenant (non-existent for the current client), and if the tenant id is part of the request, then existing and non-existing tenant ids should also yield the same if the client is not authorized to them.
I understand this is somewhat against the purpose of 403, and there can be easy theoretical counter-arguments which can also be very valid from other perspectives, but not leaking any info is the most secure option.

Related

Oauth2 - Requesting access to a specific subset of resources

I am developing an Restful API for client applications which will reach to the resources on the server after the resource owner gives necessary permissions. For achieving this, I am planning to use Spring Oauth2. Currently, I am asking for an auth. code to the auth. server and using it to get a token for reaching the resources of the resource owner. For instance:
1- The client application asks for the scope 'readPhotos' which is mapped to: /api/v1/photos
2- The resource owner enters his credentials on the page that the authorization server shows.
3- Authorization server asks the resource owner if he wants to grant access for his photos.
4- Resource owner approves and authorization code is passed to the client application.
5- After retrieving the code, the client app passes it to the auth. server for the token.
6- Token is received and the client can reach the photos.
However, I want to let the client to specify the subset of resources it wants to ask permission for. For example, lets say the resource owner has "photo1", "photo2", "photo3", "photo4" in the resource server. What is the correct way to make the client application to ask authorization for a subset of resources, such as files "photo1, photo3" but not the whole collection. How to make scope definitions? As the resources will vary for each user (the photo ids will be different for each user), it is not possible to define each resource with a single scope statically using ResourceServerConfigurerAdapter of Spring Oauth2. Currently I am using the following configuration for photo permissions. However, as I mentioned this scope definition is too generic and gives permission for the whole set.
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
http.requestMatchers().antMatchers(HttpMethod.GET, "/api/v1/photos").access(" #oauth2.clientHasRole('ROLE_CLIENT') and #oauth2.hasScope('readPhotos')")
The access token has scopes and it has an audience (generally speaking). Those are your variables. You would probably have to use scopes that correspond to the resources (but I supppose audience is sort of relevant as well). The tough part is validating the scopes (or audiences) in the Auth server. Really, I wouldn't expect an auth server to be able to know anything about the available resources, so you pretty much have to grant any scope that a client requests, which may defeat the object. So I think the bottom line is you need to ask yourself if the token is really the right place to put that information, unless your example wasn't really realistic, and the real use case is more interesting.
Or you could put the onus of validating the scopes on the user (he has to approve access to individual photos). That works, I guess, for a grant with approvals (e.g. auth code).

What's the right HTTP Status code for a blocked, abusive user?

I am building an app in which users might be blocked for using offensive language. When a user is blocked, his or her app can not access some API calls.
What should be the right HTTP status code when a blocked user tried access these API parts? Error 403 seems like a good choice, but I wonder if there's anything more specific.
Just for completeness ....
The answer to the question is that there is no other code that is (clearly) more appropriate than 403. As Wikipedia says:
"HTTP 403 is returned when the client is not permitted access to the resource despite providing authentication - either because authentication failed, or for some reason besides authentication, such as insufficient permissions of the authenticated account. This other reason needs to be acted upon before re-requesting access to the resource."
That is a good fit to the scenario you describe.
The other thing is that since you have blocked the users, you probably don't care what they think about the "correctness" of the status code. Nobody else will care one way or the other.
Ultimately it is your choice.

How to determine which IdP to redirect from a SP?

I'm building SP initiated single sign-on, and I wondered what the best practice was for determining which identity provider to redirect a user to.
Here are the options I've come up with:
/SSO/Logon/Acme, where Acme is a name of a known IdP.
We know the endpoint url for this provider, and redirect the user. The downside, is that an anonymous user can detect what IdPs we support by guessing names and checking for a redirect.
/SSO/Logon/1, where 1 is the id of an identity provider.
Same problem.
/SSO/Logon?endpointUrl=http://idp.acme.com
We blindly redirect an AuthnRequest to any endpoint, and unauthorized endpoints will be rejected when they respond
/SSO/Logon/ABCDEFG where ABCDEFG is a cryptographically secure random string
We lookup the endpoint url associated with this key, and know where to redirect. Similar to first two options, but not guessable
This must be a solved problem. What's the best way to handle this?

Asp.NET WebAPI custom authorization

I want to create a authorization mechanism for an application based on WebAPI and AngularJs.
I've seen some articles, which use BasicHttpAuthentication, but i really don't like the whole idea of sending username, and password on every request. The more it doesn't fit for me is because i want to use OpenId authentication, where you don't have username/password pair.
I'm thinking about a solution, but I don't really know how to implement it. The concept is that user is authenticated as in an usual Web application - posts a form with user / password or selects an OpenId provider. If the user is authenticated succesfully, it is placed in a static object, which stores the User object for a certain ammount of time. Next a usertoken is generated and passed to the Client Application. The client passes the token on each request to the server, if the user exists in the above mentioned static object with the appropriate authentication token it is authorized to get the data.
Firstly - Do you think this is a good approach to the problem?
Secondly - How should I pass the authentication token, WITHOUT using cookies? I guess it should sit in the request headers, like in BasicHttpAuthentication but, I really dont' know how to handle it.
BasicHttpAuthentication
I'm with you on feeling dirty about caching the username and password on the client and forever transferring it with every request. Another aspect of Basic authentication that might work against you is the lack of sign-off. Other than changing the password, you can't "invalidate" a basic authentication session. Tokens on the other hand, will typically offer an expiration date, and if you want server-side invalidation you can check the issue date and say "any tokens older than issue date xyz are invalid".
Server State
You mention "If the user is authenticated successfully, it is placed in a static object". But this is independent of the token? This sounds like you're wanting to implement server state management of authentication sessions, but this isn't strictly necessary. The token itself should be sufficient for user authentication, managing server state is another potential obstacle. Server state can become difficult to manage when you factor app-pool recycles or web-farm environments (what if you want two services to share the same authentication token, but not require communication with a central "authentication server" for storing the state / session?)
Passing Authentication Token
Headers is definitely a good place for it. Really, where else is there? Cookies, Headers, Message. Other than a browser client, cookies don't make a lot of sense, and including it in the message can muddy your message formatting a bit, so headers is the only remaining option that makes much sense in my view.
Client Implementation
You've not specified, but I suspect you're interested in calling the service from .NET? In which case System.Net.Http.HttpClient could be your friend. In particular, the DefaultRequestHeaders collection. You can use this to add a custom header to store your authentication token.
Server Implementation
When researching ASP.NET authentication recently, I learned a lot about customisation by examining the Mixed Authentication Disposition ASP.NET Module (MADAM). I wasn't interested in using MADAM as-is, but learning about it from that article and examining the source code gave me a lot of ideas of how I could insert my own authentication module into the web stack.

Looking for authentication/impersonation strategies for a RESTful API

I've got a requirement to allow impersonation ("act as") in my API. So a user with the appropriate permission can exercise the API as another user. I'm wondering if there are some specific strategies employed in this space?
I can create an endpoint to begin and end the impersonation. Beginning the impersonation might involve getting a user and their permissions and loading them into memory for the current request, easy enough. What about subsequent requests? Is it bad practice to add an HTTP header indicating a "Impersonated-User"? If that header exists, use it to do auth on subsequent requests? What about using a cookie with that UserId? Or additional information?
Is there added benefit (assuming a .NET impl) to assigning the impersonated users to the Thread.CurrentPrincipal? The current permission and role implementation is custom, essentially using a bit array (although this is on the table for change in the future).
HTTP doesn't include any native support for delegate credentials / impersonation, so a combination of HTTP Basic Authentication with a custom header indicating which other user the client is trying to act as would be fine.
I would avoid polluting your API with the idea of "beginning and ending the impersonation", however. That implies stateful session knowledge that must be maintained between API calls, and it will make it more difficult to manage on the server side.
I would just have the client pass all the required information (their creds and the impersonation principal) with each call, and validate them each time against the resource being invoked.

Resources