1

I have a HTTP "rest" web service API that I am creating for accessing user data.

The web service integrates with a XACML policy decision point. The policy decision point determines if the request is authorized as a function of the user and the data being accessed. Generally, the response is "permit" (action is allowed) or "deny" (action is not allowed).

If permit, then the call continues and data is returned. If deny, then the call is aborted and an HTTP 403 (forbidden) is returned.

However, certain policies have "obligations" to indicate that the action is conditionally allowed with further action. The analogy that I generally use is the "this credit card transaction may be allowed, but the clerk needs to view the customer's ID, and then make this call again asserting that the ID matches the credit card".

In my web service, I want to prompt the client to take action and include additional information in the request URL to indicate that the obligation was met. I am communicating this information with structured body response understood by the client application.

My question is what is the appropriate HTTP status code to use in the scenario. "403" would not be appropriate (text from HTTP spec Authorization will not help and the request SHOULD NOT be repeated). My best guess would "401" (unauthorized), but I am not sure if this status code is specifically around the use of the authorization header and username/password type of concerns.

1

2 Answers 2

1

Maybe you could use the HTTP status code 303 or 307 to point the user to a temporary redirect location that somehow encodes the extra "obligation"?

Sign up to request clarification or add additional context in comments.

1 Comment

So far, 307 is how I have implemented it. I feel "dirty" with this approach, but it does seem valid.
1

A 401 response seems reasonable to me. The HTTP authentication mechanism is extensible, so you could conceivably create a custom authentication scheme so that you are properly setting the WWW-Authenticate header as required by the RFC. Browsers won't know what to do with your custom scheme, but I assume your clients aren't browsers anyway, if they have to understand what an obligation is.

Example request sequence:

PUT /some/resource/that/has/obligations HTTP/1.1 Content-Type: application/json Authorization: token my-oauth-token 

HTTP/1.1 401 Unauthorized WWW-Authenticate: obligation urn:my-app:my-obligation;param1;param2 

PUT /some/resource/that/has/obligations HTTP/1.1 Content-Type: application/json Authorization: token my-oauth-token Authorization: obligation urn:my-app:my-obligation:result=ok 

HTTP/1.1 201 Created Location: /some/resource/that/has/obligations/1 

Another option would be to return a 202 on the initial post or put, and then confirm it on a later post. This option would require a little more state management server side, since you'd first accept the operation, and then wait for the client to confirm it.

PUT /some/resource/that/has/obligations HTTP/1.1 Content-Type: application/json Authorization: token my-oauth-token 

HTTP/1.1 202 Accepted Location: /some/resource/that/has/obligations/1 X-Obligation: urn:my-app:my-obligation;param1;param2 

POST /some/resource/that/has/obligations/1 HTTP/1.1 Content-Type: application/json Authorization: token my-oauth-token X-Obligation: urn:my-app:my-obligation;result=ok 

HTTP/1.1 200 OK 

One thing to always keep in mind with obligations, though... they're always enforced client-side, so unless the obligation involves hitting another service that your service can double-check against, you never know if the client actually performed the obligation. If you don't control the client, then obligations are really just theatre.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.