In the OAuth 1.0 spec it is suggested to respond with the following WWW-Authenticate header:
WWW-Authenticate: OAuth realm="http://server.example.com/"
Is it suitable to add any other informative data to this header? In case a request for a protected resource fails, would it be reasonable to include some information as to why? Such as:
WWW-Authenticate: OAuth realm="http://server.example.com/", access token invalid
Or is this contrary to the purpose of the response header?
Note for anyone just stumbling across this: The OAuth 2.0 bearer token spec adds "error", "error_description", and "error_uri" attributes to the "WWW-Authenticate" header for reporting additional error information, and it specifies when they should and shouldn't be used.
E.g.:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="example",
error="invalid_token",
error_description="The access token expired"
Sounds a little dubious to me. The WWW-Authenticate header is specified by an RFC, which would seem to forbid the example you've given. The OAuth spec says that you can include other WWW-Authenticate fields as defined by the RFC, not that you can just tack arbitrary strings onto the end of it. I would avoid it, unless there is a defined field that you could twist to your purposes.
It's against the spec to do that, and if it wasn't it would probably be something like :
realm="http://server.example.com", oauth_error="access token invalid"
I'd recommend using the response body for things like this, or maybe a X-OAuth-Error header.
Related
I can't read the 'grant_type' parameter using Postman, but I can read it normally and get the return using OkHttp, how can I make Postman work properly.
I am using the Postman configuration from the documentation
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
You shouldn't send grant_type neither in params nor in headers. Those should be sent in body params then only it will work.
Url: https://login.microsoftonline.com/common/oauth2/v2.0/token client_id, scope and redirect_uri params can be sent as query params. where as grant_type, code and client_secret should sent in body params.
please see the postman image sample below .
If you are trying to get the refresh token , you have to add
Content-Type: application/x-www-form-urlencoded in the header,
Hope this resolve your issue , please let us know if you have any query
Thanks
If the answer was helpful , kindly click on upvote mark the answer as verified ,so that it will help others as well .
While designing a GET endpoint I am confused ...
Have designed Open API spec 3.0 for successful response ( 200 ) , invalid request ( missing mandatory stuff ) ( 400 )
Now I am confused about things like : 401 ( Unauthorized ) , 405 ( Method not allowed ) , 415 ( Unsupported Media type )
This API will need an api key to be provided in header and if not provided by user or an invalid api key is provided then they should get a 401
So I think I should be specifying 401 in my response spec .
However when I look at swagger's Pet store ( https://editor.swagger.io/ ) they are not having this response code anywhere ... ?
My API spec ONLY supports GET with Content-type : application/json so I am thinking we dont need 405 ( DELETE / POST / PUT etc ) .
Similarly if consumer sends application/xml or anything other than application/json we are not supporting it so this is why we should not be explicitly defining 415 in the spec ?
A bit confused which is why am looking into some inputs.
Was referring to some pages here and here
I think it is a good idea to document the Response Codes the API might return, it is indeed supported (but optional) by OpenAPI.
The consumers might find useful to know 401 Unauthorized means the JWT token is not supplied or it is expired, or 400 means the payload is incorrect (i.e. missing a specific attribute).
Check this example if you would like to see how Response Codes are documented and displayed by Swagger UI.
However when I look at swagger's Pet store they are not having this response code anywhere ... ?
The Pet Store is really just an example that one can use as a starting point or when you want to feed a tool with a sample spec. It is not meant to be normative. If you look through the sample code, you will even find paths which are RPC style (e.g. here) and other things that are not exactly RESTful.
why we should not be explicitly defining 415 in the spec ?
I think the blogposts that you found are helpful and do not contradict each other. Both of them rightfully recommend you to use the standard http response codes and provide a helpful error body. Some people omit response codes that they think are self-explanatory. But IMO, adding these few lines is totally worth it. If you add them diligently, then you get a key aspect of openapi right: The purpose of openapi is clarity and predictability of the capabilities and behaviour of your API.
So in summary: Yes, think about the responses that you are going to need, and do include these response codes in your api spec.
I have an API that handles almost exclusively application/json in Rails. A few endpoints can handle application/x-www-form-urlencoded for file-uploads.
I want to enforce the content-types: when a client adds anything other than application/json I want to send an 406 - not acccepted error back, in my ApplicationController
before_action :require_content_type_json
def require_content_type_json
return if request.content_type == Mime::JSON.to_s
head status: 406
end
However, RFC 7231 (http) states that:
A sender that generates a message containing a payload body SHOULD
generate a Content-Type header field in that message unless the
intended media type of the enclosed representation is unknown to the
sender. If a Content-Type header field is not present, the recipient
MAY either assume a media type of "application/octet-stream"
([RFC2046], Section 4.5.1) or examine the data to determine its type.
I roughtly interpret that as "when the request comes with a body, the content-type must be provided by the client, else the server should assume "application/octet-stream".
Since I cannot handle octet-stream, I want to return 406 - not accepted too, there. In other words: when there is a body, a header setting the content-type to "application/json" should be present. Always.
So, how do I detect whether a user should have sent a content-type header along? Is it enough to simply check for !request.body.empty?: body is not empty?
Or should I assume that only GET/OPTIONS/HEAD requests have no body and all others do and should require a content-type?
Does Rails have any helpers or classes in place to deal with this?
We're making requests for bearer tokens using client_credentials OAuth 2 grant flow with Apigee. According to the spec:
4.4.2. Access Token Request
The client makes a request to the token endpoint by adding the
following parameters using the "application/x-www-form-urlencoded"
format per Appendix B with a character encoding of UTF-8 in the HTTP
request entity-body:
grant_type
REQUIRED. Value MUST be set to "client_credentials".
If we make a call however we get an error like this:
{"ErrorCode" : "invalid_request", "Error" :"Required param : grant_type"}
It seems that using Apigee we have to send grant_type as a query parameter.
Why is this? We have clients of Apigee that are unable to use OAuth libraries in their language of choice because of the way that Apigee deals with OAuth 2, and it would be good to know if there is by-design or not.
In addition it doesn't seem like it supports grant_type in the post body and sending id and key using basic auth.
Turns out you do not need to send in grant_type as a query parameter. There is a <GrantType> element in your GenerateAccessToken policy that takes in a variable. For instance, I can use the following:
<OAuthV2 name="GenerateAccessToken">
<DisplayName>GenerateAccessToken</DisplayName>
<FaultRules/>
<Properties/>
<!-- This policy generates an OAuth 2.0 access token using the password grant type -->
<Operation>GenerateAccessToken</Operation>
<!-- This is in millseconds -->
<ExpiresIn>1800000</ExpiresIn>
<Attributes/>
<SupportedGrantTypes>
<GrantType>password</GrantType>
</SupportedGrantTypes>
<GenerateResponse enabled="false">
<Format>FORM_PARAM</Format>
</GenerateResponse>
<GrantType>user.grant_type</GrantType>
<UserName>request.header.username</UserName>
<PassWord>request.header.password</PassWord>
</OAuthV2>
In this example, the grant_type is passed in as user.grant_type. But user.grant_type can be anything-- header, query param, form param, or even a hard-coded value. This way, you (the developer) are provided maximum flexibility on how you want to send in the grant_type.
Can you paste the exact API call that you are making (obviously you should obfuscate the key and secret)?
I'd like to understand what you say when you say "Apigee" -- it could mean API BAAS (https://api.usergrid.com) or a proxy that you defined using API services and attached an OAuth 2 policy to, or something else?
I just did a quick test with a simple ASP.NET MVC 3 sample by modifying default LogOn form. According to this article, both hidden field __RequestVerificationToken and cookies __RequestVerificationToken_Lw__ must contain same value that generated by Html.AntiForgeryToken(). But it isn't exactly same when I got them in Fiddle, by the way, looking at MVC 3 source code, method GetAntiForgeryTokenAndSetCookie seemed not use salt value for generating the cookies. Was there any change in MVC 3?
Forgot to say that I could still log on successfully with both normal or Ajax POST request.
Here is raw log from Fiddle:
POST http://localhost:51713/Account/LogOn HTTP/1.1
Referer: http://localhost:51713/Account/LogOn
Content-Length: 256
Origin: http://localhost:51713
X-Requested-With: XMLHttpRequest
Content-Type: application/x-www-form-urlencoded
Cookie: __RequestVerificationToken_Lw__=OIRtVqUvNt/LfDGeoVy3W1VhdKN7MwdbUZmRNScz4NqS4uV0I0vQH2MHg77SsVhcinK5SJi9mVcdBUWk2VMiPTk8EMUN2Zq0X4ucK8XQ3/zr6NoiIvVF73Bq8ahbFaY/IrNrWY7mmzvO9j/XVLNN2lNqgCd6I3UGZAw3/nlOmpA=
__RequestVerificationToken=zeDS%2F8MZE%2BLf%2FrRhevwN51J7bOE3GxlGNLQc8HogwFctF7glU1JboHePTTHa5YFe9%2FD2sY7w167q53gqvcwYZG1iZeecdnO4fdg6URdR4RUR%2BjIgk1apkXoxQ2xg48REfv4N5D4SHKU4MAf30Diy0MVyyF9N2Dl7uUGT6LbKHZU%3D&UserName=Tien&Password=tien&RememberMe=false
what makes you think they should be the same ? :) of course, they must me comparable in some way, but that doesnt mean they must look identical in their serialized form. There is different set of data serialized to cookie (i think only the "salt" and token) and to HTML markup (salt, token, creation time, username).
If you are interested in details, take ILSpy and look for System.Web.Mvc.AntiForgeryDataSerializer, System.Web.Mvc.AntiForgeryData and OnAuthorization method of System.Web.Mvc.ValidateAntiForgeryTokenAttribute
The article you are referencing in your question is simply wrong, because the hidden field anti forgery token will never be the same as anti forgery cookie value.
Added value of my answer is the link to interesting article which describes ASP.NET anti-forgery token internals. It, among others, provides clear steps to decode and decrypt cookie/form token:
BitConverter.ToString(System.Web.Helpers.AntiXsrf.MachineKey45CryptoSystem.Instance.Unprotect(tokenValue))
... and subsequent steps in order to match the cookie and form tokens.