I have been reading about OAuth and it keeps talking about endpoints. What is exactly an endpoint?
Come on guys :) We could do it simpler, by examples:
/this-is-an-endpoint
/another/endpoint
/some/other/endpoint
/login
/accounts
/cart/items
and when put under a domain, it would look like:
https://example.com/this-is-an-endpoint
https://example.com/another/endpoint
https://example.com/some/other/endpoint
https://example.com/login
https://example.com/accounts
https://example.com/cart/items
Can be either http or https, we use https in the example.
Also endpoint can be different for different HTTP methods, for example:
GET /item/{id}
PUT /item/{id}
would be two different endpoints - one for retrieving (as in "cRud" abbreviation), and the other for updating (as in "crUd")
And that's all, really that simple!
All of the answers posted so far are correct, an endpoint is simply one end of a communication channel. In the case of OAuth, there are three endpoints you need to be concerned with:
Temporary Credential Request URI (called the Request Token URL in the OAuth 1.0a community spec). This is a URI that you send a request to in order to obtain an unauthorized Request Token from the server / service provider.
Resource Owner Authorization URI (called the User Authorization URL in the OAuth 1.0a community spec). This is a URI that you direct the user to to authorize a Request Token obtained from the Temporary Credential Request URI.
Token Request URI (called the Access Token URL in the OAuth 1.0a community spec). This is a URI that you send a request to in order to exchange an authorized Request Token for an Access Token which can then be used to obtain access to a Protected Resource.
It's one end of a communication channel, so often this would be represented as the URL of a server or service.
An endpoint is a URL pattern used to communicate with an API.
An endpoint is the 'connection point' of a service, tool, or application accessed over a network. In the world of software, any software application that is running and "listening" for connections uses an endpoint as the "front door." When you want to connect to the application/service/tool to exchange data you connect to its endpoint
Endpoint, in the OpenID authentication lingo, is the URL to which you send (POST) the authentication request.
Excerpts from Google authentication API
To get the Google OpenID endpoint, perform discovery by sending either a GET or HEAD HTTP request to https://www.google.com/accounts/o8/id. When using a GET, we recommend setting the Accept header to "application/xrds+xml". Google returns an XRDS document containing an OpenID provider endpoint URL.The endpoint address is annotated as:
<Service priority="0">
<Type>http://specs.openid.net/auth/2.0/server</Type>
<URI>{Google's login endpoint URI}</URI>
</Service>
Once you've acquired the Google endpoint, you can send authentication requests to it, specifying the appropriate parameters (available at the linked page). You connect to the endpoint by sending a request to the URL or by making an HTTP POST request.
Short answer: "an endpoint is an abstraction that models the end of a message channel through which a system can send or receive messages" (Ibsen, 2010).
Endpoint vs URI (disambiguation)
The endpoint is not the same as a URI. One reason is because a URI can drive to different endpoints like an endpoint to GET, another to POST, and so on. Example:
#GET /api/agents/{agent_id} //Returns data from the agent identified by *agent_id*
#PUT /api/agents/{agent_id} //Update data of the agent identified by *agent_id*
Endpoint vs resource (disambiguation)
The endpoint is not the same as a resource. One reason is because different endpoints can drive to the same resource. Example:
#GET /api/agents/{agent_id} #Produces("application/xml") //Returns data in XML format
#GET /api/agents/{agent_id} #Produces("application/json") //Returns data in JSON format
The term Endpoint was initially used for WCF services. Later even though this word is being used synonymous to API resources, REST recommends to call these URI (URI[s] which understand HTTP verbs and follow REST architecture) as "Resource".
In a nutshell, a Resource or Endpoint is kind of an entry point to a remotely hosted application which lets the users to communicate to it via HTTP protocol.
The endpoint of the term is the URL that is focused on creating a request.
Take a look at the following examples from different points:
/api/groups/6/workings/1
/api/v2/groups/5/workings/2
/api/workings/3
They can clearly access the same source in a given API.
API stands for Application Programming Interface. It is a way for your application to interact with other applications via an endpoint. Conversely, you can build out an API for your application that is available for other developers to utilize/connect to via HTTP methods, which are RESTful. Representational State Transfer (REST):
GET: Retrieve data from an API endpoint.
PUT: Update data via an API - similar to POST but more about updating info.
POST: Send data to an API.
DELETE: Remove data from given API.
PATCH: Update data.
Related
I wrote a sample ballerina code in choreo API to return x-jwt-header header value to the caller.
when I turn off the security for that API, the header value is not there in the request headers. Does it mean the API is unsecured?
I want to crate an unsecured API. I want to know whether the header values will be there or not?
When you disable the security, basically API is exposed without security to the consumers. Hence the API is unsecured. x-jwt-header is used to pass the enduser data to the backend services. If you don't provide an access token when invoking API, then it can't send the enduser information to the backend services. That's why you are getting the response without that header.
In a microservice architecture, an API gateway lays in front of the API. The purpose of this is e.g. changing some request / response parameters, for single entry point or checking authentication etc. Now I would like to protect my API using OAuth2 flows to obtain an access token. The problem is to decide who is the actual OAuth client, I will demonstrate it by using a SPA example:
a) Is it the SPA that started the oauthorize request (to the api gateway) by using the implicit grant. Then, the Api gateway would simply route the request through to the OAuth authorization server, acting as a single entry point, with the /authorize stuff from the implicit flow
b) Is it the API Gateway itself, meaning the SPA sends the username and password of the enduser to the api gateway (of course, here the SPA needs to be trusted with the end users credentials), which then acts on its own as an oauth client using the resource owner password grant
c) dismiss the api gateway at all and create the oauth authorization server "parallel" to the api gateway, meaning you would loose the single entry point etc.
The following picture demonstrate a very abstract architecture, and the question is about the numer "[2]", if this request is initiated by the SPA and passed through by the api gateway, or if the api gateway is intercepting the request and acting on its own as an oauth client?
OAuth with API Gateway
My guess is to always use the best fitting grant type for a specific client, regardless of an API gateway being in between or not. This would mean, that when it comes to OAuth, the API Gateway would simply pass the client authorization request through, whatever grant type it used. Therefore, [2] in the picture would come from the client, and not from the API Gateway acting as the OAuth client. Is this correct? As mentioned, this really gets tricky when it comes to first party apps as you probably could use the password credentials grant, which has huge drawbacks,e.g. no refreshing possible for SPAs.
Please bear in mind that this is a purely opinion based answer, because your question is pretty vague.
I don't like the idea about using the API Gateway as the point which authenticates requests. I think that this defeats the Single Responsibility Principle. The gateways purpose usually is to expose your backend to external clients, perhaps change the contract for some specific clients, etc. But it shouldn't also authenticate calls. Besides it would have to do so based on the data passed to it, which you would have to gather somewhere else anyway.
Another thing which is I think undesirable, is that you're considering using the resource owner password grant for your SPA. This is not the correct use case for this grant flow. You could look into this article, which explains it much better than I could: https://www.scottbrady91.com/OAuth/Why-the-Resource-Owner-Password-Credentials-Grant-Type-is-not-Authentication-nor-Suitable-for-Modern-Applications
I would suggest you use the Implicit grant type and use the api gateway to only route calls to the backend, don't authenticate the calls on that layer.
If you're using a spring cloud api gateway (essentially a zuul proxy), you will have to add proper configuration so that it forwards all security headers and redirects. This example works for me:
server:
use-forward-headers: true
zuul:
addHostHeader: true
routes:
<your oauth server route>:
url: <your oauth server url>
path: <if youve got any prefix>
sensitiveHeaders:
stripPrefix: false
It doesn't matter, what Krzysztof Chris Mejka in previous answer like or dislike. Take a look at BCP - https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps#section-6
Latest recommendation from oauth working group at IETF is to use a kind of Api gateway/reverse proxy, another words - you need to keep tokens out of js entirely.
I'm planning an API and I haven't found any information about where the access token should be placed in the response. I'm interested in the case where I'm providing the access token. What is the best practice to send the token to the clients (from the backend service)?
Should it be sent to clients in the Header or in the Body of the answer?
You should look at examples and see what others do. For example, Facebook, Twitter, Google, Amazon... and all those popular PaaS services exposing a REST API all use OAuth2 as authentication mechanism:
In OAuth2 you'll see the specification requires to send the generated token to the client in the body of a json response: https://www.rfc-editor.org/rfc/rfc6749#section-5 . But you can also see how Google and other vendors extend this mechanism so it can be sent as a callback url param, for example (Check out https://developers.google.com/identity/protocols/OAuth2UserAgent).
Once you get the authorization token you put it on the Authorization: HTTP header you send on your requests for accessing protected resources. They have to support this way of doing it, because it is how the OAuth2 standard specifies it https://www.rfc-editor.org/rfc/rfc6749#section-7
If you want to tinker a little bit more with oauth, check out https://developers.google.com/oauthplayground
(OAuth is pretty much the same thing.)
They usually also extend the Authorization header mechanism to allow the token to be provided as a GET/POST parameter in the url or the body of the response, respectively (For example, Facebook's Graph API also supports passing an access_token= parameter on your HTTP POST request body or GET URI). There is no way to manipulate or even read HTTP headers on a javascript browser application (see the modern fetch API and other proposals on Accessing the web page's HTTP Headers in JavaScript), so providing this functionality makes life easier for many app developers.
Another popular authentication scheme is SOAP authentication. It doesn't support tokens but it supports digest authentication, which is a similar thing. The interesting part of it is that it is not HTTP/Web based (although it is primarily used that way), so you can use it over other application protocols. It's a little more cumbersome, but you can find ready to use implementations for both server and client.
You can also use digest authentication over HTTP without SOAP. It is also based on Authorization: headers and every browser supports it. Check out https://en.wikipedia.org/wiki/Digest_access_authentication to see how the authorization headers are formed in different ways depending on the level of security you want to reach.
Some services, like redmine, allow you to use an API token (API key) instead of a session token. Then you can make basic http auth on your requests like https://whatever:yourapikey#example.com/protectedMethod, although passing of auth data on URLs is currently deprecated in favor of basic auth header, and plain passwords / static API keys should only be sent over secured SSL connections. In this case the client can have the server generate an api key using a web interface or a rest api (so the generated key will be passed as a JSON response). This method may not be such a good idea, though: Check http://talks.codegram.com/http-authentication-methods#/intro if you want to know why, and also this question discussing where to put them: Where should I place API keys in REST API calls?
I have a web api application which implements the Resource Owner Password flow from OAuth specification. Everything works correctly.
Actually I configure everything in my WebApiConfig class by using an Authentication filter like this
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add( new HostAuthenticationFilter( OAuthDefaults.AuthenticationType ) );
As some of my customer asked for a different method of authentication I am evaluating to add a couple of features to my services but stil did not have clear how those features can work together.
In particular I cam across a link which explain in very easy words how to implement a HMAC authentication in web api.
Can I implement this authentication method and let the client to choose which one he want to use? Do they can cohesist together?
Yes, your web api service can send back multiple schemes in the WWW-Authenticate challenge. In your case it can send back 'bearer' and 'hmac' for example.
See also this question for more info on using multiple schemes.
BTW, it's not your web api service that supports Resource Owner Password flow. The client uses this flow to get a token from the authorization server that it can use in a bearer scheme with your service (resource server). HTH.
I want to create a flexible API Rest server. I will allow the clients to authenticate using HTTP or an APIKEY.
My question is: what is the correct way to add the apikey to a GET request? My problem is the apikey pollutes the url.
I imagine something like this : /book/1/apikey/s4cr4t !
In my opinion you should only use the Authorization header. That's what it is there for.
Putting it in the URL is a bad idea because:
a) as you said it pollutes the URL
b) if you decide to go SSL for security then the API will still appear in log files
c) caches will end up creating multiple copies of the same representation, one for each api key.
For more information on creating your own Authorization scheme go here.
Credentials may be passed using the Authorization header:
GET http://domain.com:/book/1
Authorization: apikey="s4cr4t"
It all depends on how far you want to go but the mechanics stays the same:
Context
The goal is to identify the client with some level of security. (Note: Security is another detailed discussion). Remember that one if the “features” of REST is to be stateless: That means no session state on the server except for resources. To keep the client stateless, it needs to supply on each request enough information that the request is independent. It must give the server a way to identify the client such as a username/password, API Key or token.
You have various options to do this so here are some:
Add HTTP headers to identify the client
Here one can use the Authorization header and send it with each request. There are various authentication schemes but stick to the standard ones such as Basic Auth. Here you would probably stick to SSL. The authentication process generates a kind of token if you like.
You can also make use of a cookie. The cookie must contain no information except that it is a “pointer or key” to a stateful session resource on your server (note: session it a resource which is “rest-legal”). You can create this resource by doing a PUT (+info) with response 200 OK or POST (+info) with a response of 201 Created and Location: /sessions/123334. The session can then be validated by the server such as timeout, valid client ip address, api key etc.
With the method above, you can also define a customer header such as Api-Key: XXXX. But then you limit yourself to special client. Set-Cookie are “well known” headers so browser will handle them kind of transparently. The authentication process can then be done by following links and filling in forms (PUT + POST) to authenticate (create session resource).
Encode an identifier in the content
Here you are free to do what you want too. Just add a field/token/id to your content and let the server verify it.
A RESTful API does application flow by resolving links. See also HATEOAS and Fielding's words. This also applies when you have a separate process of logging in to the application.
Do not encode any data in the URIs. (Out of band information)