My company is re-writing its e-commerce site as a single page application using the new Web API / SPA features in MVC 4. We're not sure about the best way how to handle authentication.
Specific questions:
How do we handle both encrypted and non-encrypted communication? Clearly, we need to use HTTPS for the login, account, and checkout AJAX, but we'd like to use HTTP for browsing the catalog in order to avoid expensive SSL handshakes that would slow the whole site down. Is this even possible for a SPA, or are we stuck with HTTPS for everything?
What sort of authentication should we use? Primarily our site will be accessed from a web browser, so cookies may be fine. But down the road, we may want to make a custom iPhone app. Is Basic Authentication, OpenId, or OAUTH preferable? If so, why?
If we go with Forms Auth and cookies, will the redirect issue be fixed for the release of MVC 4, or do I have to use the haack?
If we go with Basic Authentication, how do you do persistent sessions, so that users don't have to log in every time they go to the page again.
Which authentication methods are well supported by ASP.NET MVC 4. It'd be ideal not to have to write a lot of specialized code.
Thanks in advance
1. How do we handle both encrypted and non-encrypted communication? Are we stuck with one protocol, https, with a spa?
You are not stuck with one protocol. With a spa you can use ajax to communicate over http or https, whichever one you choose at any given time. I would use https for anytime your are sending sensitive information like a persons name or their birthdate or login credentials.
Once a user logins to your site over https then your server can set a forms authentication cookie for that user. This cookie should be an encrypted value that ties their session to the server. You must be aware that if the rest of your site is using http then you have the risk of this cookie being passed over the wire in plain text. Even though the contents of the cookie can be encrypted, using an encryption algorithm of your choosing, a malicious person can steal this cookie and jack your user's session.
This might not be a big deal to you though if they are only allowed to browse the site and create a shopping cart. Once the user is ready to checkout then you should re-authenticate the user, over https, as a sort of double check to make sure they are not a malicious user. Amazon does this.
2. What sort of authentication should we use?
Well, that's all a matter of what features do you want your site to have.
OAuth is for exposing webservices which you can allow other sites to call with delegated access. What this means is that if you have a user who wants another site (site x) to be able to access features on your site for their profile. The site x can redirect the user to an oauth endpoint on your site which will authenticate the user. Your oauth endpoint will ask the user if its okay that certain features are shared with site x and if the user agrees a token will be generated. The user passes this token to site x where site x will make server to server calls to your site. Site x will present the token in the calls so the calls to your services will be a delegated access call. OAuth is a way of provisioning other sites to make delegated access to your services. I hope i was able to explain that clearly.. I'm not always good at this.
OpenID is not a very secure way of handling authentication its more of a convenience so that users don't have to be hassled with registering an account with your site. Because OpenID is completely open you are trusting another provider to validate your users. If the third party provider's user store is compromised then your users are compromised also. It's an example of a voucher system where you are basically saying I will trust who you say you are, if you can have an OpenID provider vouch for you.
Another solution is WS-Federation. WS-Federation is if you have multiple sites and you want to have 1 authentication provider that you trust. This authentication provider can be yours and basically all your sites say if you want access to my site then you have to first be authenticated with my authentication provider. This authentication provider can live on a seperate domain and can choose any authentication mechanism it chooses. You are trusting that this auth provider will do its best job to manage your users accounts.
WS-Federation can be overkill though if you only want authentication on your site and don't have multiple sites. In that case I would just recommend doing Forms Authentication and this should be simple enough to do. There are lots of examples of how to do this and microsoft provides many solutions for how to do this. You should look into creating a custom membership provider.
Once a user has been authenticated with your site you should create a forms authentication cookie. This cookie ties the user to their session on the server. This applies to all the scenarios listed above. MVC 4 supports all the scenarios listed above also.
Thanks, and feel free to ask more questions if I wasn't clear enough.
** EDIT 12/1/2017 **
Coming back to this question years later I have learned that relying on cookies for REST based APIs is not a good idea. You don't want to create a session on your web application because it makes your app harder to scale. So, if you need authentication then use HTTPS with some form of authentication (BASIC, DIGEST, Token Based, etc..). So, your SPA client appl will set the Authorization header on every http request and then your web server app will re-authenticate every request.
The main downside of using ASP.NET's form based security is that it assumes you're want a 401 web page when your authentication fails (useless when you're doing an AJAX call) and it's really designed around doing redirects which kind breaks the whole SPA pattern. You can hack around it but it's not designed for the purpose you're using it.
This toolkit may provide an alternative to ASP.NET'as form model.
Not yet sure how mature it is ...
http://www.fluentsecurity.net
Feedback welcome.
I just started working with webapi myself so don't consider my answer authorative. I'm not a security expert though I should be. I ran into the same questions as you did and found, as you did, that there is no authorative answer though - within mvc webapi at any rate. Looking at other webapi specs may give you some inspiration.
The simplest way I came across was of course using SSL. That let's you get away with sending credentials in clear text in the header. Doesn't break rest.
My api will employ SSL all the way but I wanted to double up anyway. So I'm sending an encrypted key in the querystring for all my requests. Pretty much the way cookieless authentication works for a non api asp site, but mvc doesn't play with it so I've rolled my own solution.
On a mobile site, the user would log in, be redirected, to the app with the encrypted key encoded into the js. So he'll initially have a cookiebased auth for the site, and be responsible for it's protection, password saving etc.
Another api consumer would get a more permanent "secret" from a dev site yet to be made and use that to check out a key.
Normally mvc authentication is stateless, meaning the ticket is never invalidated server side. If you controll the client you can just ignore invalidate cookie requests if the server logs you out, and just keep on reusing the ticket. Eventuelly you might want to keep track of your tickets server side, but it's not stateless, doubt if it's restfull, and by consequence scalability taket a hit. But authentication is pretty important so...
Related
I am building a system with an ASP.NET Core web app (incidentally, in Blazor), which let's call "Site", and some domain web services (which might someday be used by other sites), one of which let's call "CustomerService".
Following various guides and articles on how to set up authentication with Open ID Connect and Azure Active Directory for this system, I see the following possible different approaches to authentication and authorization, especially with regard to AJAX requests:
Site-only auth, passthrough: Service trusts the site; site authenticates user.
Service-only auth, passthrough: Service authenticates user; site passes through all AJAX requests.
Service-only auth, CORS Service provides site client data via CORS, with authentication; site doesn't handle AJAX requests at all.
Service and site auth, passthrough: Service and site both authenticate user; site passes through some AJAX requests.
These all seem to have significant practical problems. Is there a fifth approach, or a variation I should be considering?
Here's my elaboration of these approaches.
(1) Service trusts the site; site authenticates user:
(1a) Set up Site.Server to use Open ID Connect for users to authenticate, implement all necessary authorization on Site.Server, pass through web API calls to CustomerService, and set up CustomerService to trust requests that come from Site.Server. This looks like a bad idea because then any user can spoof Site.Server and have full access to operations that should be secured on CustomerService. Also, CustomerService would not be able to enforce authorization; we'd be trusting Site.Server to get it right, which seems suboptimal.
(1b) Same as (1a), but Site.Server would know a secret API key that would be passed to CustomerService, either in headers or the API call's querystring or body. This doesn't seem so great because the API key would never change and then could be discovered and spoofed by any user. Still, this could work, as the API key could stay secret, and we could use our secret server for both sides to retrieve it. But still CustomerService would not be able to enforce authorization; we'd be trusting Site.Server to get it right, which seems suboptimal.
(1c) Same as (1b), but we come up with a mechanism for rotating the API key occasionally. This doesn't seem so great because the API key would change and then could be discovered and spoofed by any user. Still, this could work, as the API key could stay secret, and we could use our secret server for both sides to retrieve it. But still CustomerService would not be able to enforce authorization; we'd be trusting Site.Server to get it right, which seems suboptimal.
(2) Service authenticates user; site passes through all AJAX requests: Avoid any authentication on Site.Server and instead enforce authorization/authentication on CustomerService only through Open ID Connect+Azure AD. Site.Server would have to pass through requests including headers to CustomerService. This has the benefit of putting the security in the right place, but it seems unworkable, as the user has no way to authenticate on CustomerService since the user isn't using CustomerService directly; their AJAX requests still go to Site.Server.
(3) Service provides site client data via CORS, with authentication; site doesn't handle AJAX requests at all: Avoid any authentication on Site.Server and instead use CORS to allow the user's browser to connect directly to CustomerService, requiring authentication only through Open ID Connect+Azure AD. This has the benefit of putting the security in the right place, but how can a user authenticate on a AJAX request without having done so in a human-browsable way first? My AJAX request can't redirect to microsoftonline and prompt the user, can it? Plus CORS seems like a bad idea in general--we want to move away from cross-site anything; to the user, it should appear that Site.Server is serving up both AJAX calls and HTML page requests, right?
(4) Service and site both authenticate user; site passes through some AJAX requests. Put authentication on both Site.Server and CustomerService, with the same app ID, making them appear as one and the same site as far as Azure AD knows. Site.Server could do its own authentication and restrict certain service calls from getting to CustomerService, or it could pass through requests, including headers, to CustomerService, which could then deny or grant access as well. This is what we decided to do, but I question it now, as if I add a
second service, now it has to have again the same app ID to keep this approach.
None of these approaches seem to hit the mark. Am I missing another approach that I should be considering? Or is there a variation I am missing?
Here are my thoughts on what an option 5 is:
WEB UI
Code runs in the browser and interacts with the Authorization Server to authenticate the user. A library such as OIDC Client does the security work for you.
Provides best usability and simplest code. The UI uses access tokens to call cross domain APIs. Renewing tokens is tricky though, and browser security requires some due diligence.
WEB BACK END
Is static content only, deployed around the world close to end users - perhaps via Azure CDN. Must execute zero code. Provides best performance.
WEB UI SAME AS MOBILE UI
Your Web UI in effect operates in an identical manner to a mobile UI and is quite a bit simpler, with less need for cookies + double hops.
ENTRY POINT API
The browser UI interacts with an entry point API tailored to UI consumers. This API validates tokens by downloading Azure AD token signing keys. It is also has first say in authorizing requests.
The entry point API orchestrates calls to Core APIs and Azure APIs such as Graph. The Web UI uses a single token scoped to the entry point API and you can strictly control the UI's privileges. Meanwhile the API can use Azure AD's 'on behalf of' feature to get tokens for downstream APIs so that the UI does not need to deal with this.
DOMAIN APIs
These typically run in a locked down private cloud and are not called directly by the outside world. This allows you closer control over which types of caller can invoke which high privilege operations.
BLOG POSTS OF MINE
My blog's index page has further info on these patterns and the goals behind them. Maybe have a browse of the SPA Goals and API Platform Architecture posts.
There are some working code samples on this page. In my case the hosting uses AWS instead of Azure, though concepts are the same.
I'm having trouble understanding how ASP.NET Core authentication works.
I want to implement JWT access token authentication with refresh tokens. To my knowledge, this is the industry standard for authenticating a client (Mobile app, SPA Web application). For security purposes, I'd prefer to not implement my own authorization logic including JWT generation and refresh token handling. Since ASP.Net does not natively support this, Naturally my choice would be to use IdentityServer4, a large open source library for handling this kind of stuff.
However IdentityServer4 is heavily based on OAuth, and I'm not sure how that works with SPA applications and mobile apps (clients I trust). It requires the client to redirect to some arbitrary webpage to enter their credentials and then redirect back to the app. Gross. I've never seen a major app like Snapchat, Instagram, etc. have this kind of authentication flow where you are directed to some webpage/browser during the login flow. Luckily IdentityServer4 has a little feature to handle username/password authentication for my trusted clients (http://docs.identityserver.io/en/latest/quickstarts/2_resource_owner_passwords.html)
Great, that seems to suit my needs. But... Now I want to add Facebook Authentication. IdentityServer4 allows for External Authentication, however it is still cookie based (to my knowledge). Which requires the Android/iOS/SPA app to redirect to a webpage and then redirect back to the app. Again, this isn't ideal from a user perspective. Facebook provides native mobile SDKs to handle this type of authentication which returns an access token so there is no need to redirect to web pages using cookies.
Now lets say my iOS app uses the Facebook SDK to grab an access token for the user and sends it to the backend. The backend validates the token against the Facebook SDK, and subsequently registers a local user in it's own database.
Now when that same iOS user tries to login to the app, the app will generate a facebook access token for that user from the SDK and send it to the backend. However I'm not sure how to utilize IdentityServer4 to generate a JWT for the user since I need that users' username and password. This is where I'm stuck. I seem to be fighting against the library which makes me believe I am severely misunderstanding something.
TLDR; IdentityServer4 seems to be heavily based on cookies which doesn't really fit nicely into mobile apps/SPA webpages when you are redirected back and forth from authentication webpages. Am I using the wrong tool for the job? What are some alternative solutions?
As a note on big social apps: I think it comes down to who keeps the passwords. Facebook, Instagram, Snapchat, Google act as identity providers to third parties. They themselves require user to register and specify the password which they keep. Therefore they can use any customized approach for handling validation with those passwords. However, if any of them offerred a posibiltty to log-in with the other I.e Instagram were allowing to sign-in with Amazon credentials, then they would need to follow through a standard way like OAuth and redirect to the third party for log-in. Last time I checked Instagram, Facebook and Snapchat only offer to register and no option to sign in with 3rd parties which explains why the don't need redirects.
Now if we establish that a redirect is a necessary evil, then the means to carry over the data accross aren't that numerous. I.e. we either would need to pass data via a query string or use cookies. Am I missing any others?
Both have limitations but since cookies are persisted and browser carries them automatically with each request, they do seem like a better option for the job, especially if multiple redirects are required for an external IdP to track the state of authentication request. The same reason is mentioned here:
http://docs.identityserver.io/en/latest/topics/signin_external_providers.html
It's absolutely the right tool for the job if you want what OpenID Connect and OAuth2 give you. It sounds like you may need convincing though and it may be that your use case doesn't need the full breadth of functionality offered.
If you have multiple client applications and APIs in play then I think using OpenID Connect and IdentityServer4 the right choice at this point in time.
Regarding native apps, you used to word "gross" to describe using the user's default browser to perform the sign in process and it's understandable why you might think that at first but it's not as bad of a UX as you'd think and has plenty of advantages:
The client application is completely decoupled from how authentication is actually done be that federation, social sign in (Facebook in your case), multi-factor, retina scan etc. Your identity server deals with all that complexity and is a single point of management (and failure - so make it highly available!)
Single sign on is possible - if they're already signed into your IDP then they can go straight in (although you have full control of the flow - want them to consent or confirm the sign in request every time - you can do that)
If the user has a password manager set up in their browser then that'll work too
Both iOS and Android offer APIs for doing this stuff and the work well. If you skin your native and web UIs to look similar the flow from a user's PoV is not jarring at all.
You can still use refresh tokens (ultimately secured by the platform) so you don't actually have to do the interactive flow very often anyway.
Some additional reading below. Quite a lot of thinking has gone into this from the industry so it's definitely worth digesting the current best practice.
https://developers.googleblog.com/2016/08/modernizing-oauth-interactions-in-native-apps.html
IETF current best practice: https://www.rfc-editor.org/rfc/rfc8252
Don't make Scott hate you ;) : https://www.scottbrady91.com/OAuth/Why-the-Resource-Owner-Password-Credentials-Grant-Type-is-not-Authentication-nor-Suitable-for-Modern-Applications
For client side SPA browser apps OIDC provides the implicit grant type and uses a silent refresh and IDP session monitoring mechanism to maintain the session. Check out the oidc-client-js library which implements this approach.
Updated based on questions from #user18044 below
If a user is authenticated in two different web applications via 2 different SAML-based identity providers, and one of the applications needs to request data from a web API exposed by the other application, would it be possible to call the web API methods securely by virtue of the user's current authenticated status in both applications without separately securing the API methods via an API level authentication protocol such as OAUTH? Note that both applications are owned and operated by my company and share the same 2nd level domains and user base, even though the identity servers are different (one is legacy).
Some further information: Application A is a portal application that is going to host widgets using data supplied from Application B. Application A will only communicate with application B via a web API exposed by application B. Currently application B does not expose a web API (except internally to the application itself). This is new functionality that will need to be added to application B. Application A will use Okta as its SSO. Our lead architect's proposal is to continue to use a custom legacy IDP server that we developed internally based around using the dk.nita.saml20 DLL. They are both SAML based I believe, but I don't think they could share the same identity token without some retrofitting. But this is hitting the limits of my knowledge on the topic of authentication. :) I think our architect's plan was to have the user authenticate separately using the two different identity providers and then only secure the web API using CORS, his reasoning being that since the user is already known and authenticated to use application B, that there wouldn't be any security implications in allowing application A to call application B's web api methods, as the user should be authenticated in application B. This seems quirky to me, in that I can imagine a lot of browser redirects happening that might not be transparent to the user, but other than that, I'm just trying to figure out where the security holes might lie, because it feels to me that there would be some.
I know that this approach would not be considered a best practice, however with that being said, I really want to understand why not. Are there security implications? Would it even work? And if so, are there any "gotchas" or things to consider during implementation?
To reiterate, our lead architect is proposing this solution, and it is failing my gut check, but I don't know enough on the topic to be able to justify my position or else to feel comfortable enough to accept his. Hoping some security experts out there could enlighten me.
It's hard to answer without knowing more on how your current applications and APIs are secured exactly. Do the web application and its API have the same relying party identifier (i.e. can the same token be used to authenticate against both)?
If both web applications use the WS-Federation protocol to authenticate users, then most likely the SAML token will be stored in cookies that were set when the identity provider posted the token back to the application.
You do not have access to these cookies from JavaScript. If the web API that belongs to application B uses the same cookie based authentication mechanism, you could use this provided you allow for cross origin resource sharing.
If your web API uses something like a bearer token authentication scheme (like OAuth) or has a different relying party id in the STS, this would obviously not work.
I think the reason this fails your gut check is because you are basically accessing the web API in a way a cross-site request forgery attack would do it.
A problem I see with this approach is that if the user is not authenticated with the other web application, then the call to your API will also fail.
I agree with user18044 as far as it being based on a cross-site request forgery attack and the security between applications. Is it true that if User X has access to App A, that they will have access to App B and vice versa? If that is not the case, then each application will need to be authenticated separately...and it won't be a SSO. I found these links that might be helpful in your situation.
https://stackoverflow.com/questions/5583460/how-to-implement-secure-single-sign-on-across-various-web-apps
https://developer.salesforce.com/page/Implementing_Single_Sign-On_Across_Multiple_Organizations
Goal: My server needs to direct non-users to a landing/home page, and logged in users to the actual app. When the app is loaded, it will make authenticated HTTP requests to a RESTful API (via Ajax).
I have a RESTful API that needs authentication. On another server I have my website, which also needs authentication, so I can determine whether to display the landing/home page for non-users or the app for logged in users.
Initially I thought it would be enough to implement HTTP Basic Auth for the RESTful API. However, in order to get authentication running for my website too, I would also need to setup authentication there, which would mean duplicating the low-level code to check the credentials in the database in both the REST API and the website servers.
Alternatively, I wondered if the website could authenticate via the RESTful API. For example, in my request handler for POST /login, I could make a GET request to my API, passing along the user credentials from the request body. If the request returns 200 OK, I could sign the user’s session, thus authenticating them. From there onwards, the Ajax requests to the REST API need to be authenticated with the same credentials, so I could:
set a cookie containing the credentials, thus allowing the JavaScript to retrieve the credentials before doing the request (OK with SSL?)
dump the credentials in the served HTML for the web app thus allowing the JavaScript to retrieve the credentials before doing the request (OK with SSL?)
proxy the API through the web app server, where I could retrieve the credentials from the session and add them to the Authorization header of the proxied request?
Alternatively, I imagine I could just share a session between the two servers, although I’ve heard that’s bad practice for RESTful design.
What would be wrong with doing it like this? Is there a better way to meet my goal?
I recently implemented something similar to this (assuming I understand you correctly), and there seemed to be a few viable options.
Have the server side of your web-app always authenticate with a specific username/password when accessing the REST API, ensuring that your web-app is always trusted and assuming that users are properly logged in on the web-app if a request is authenticated as the app.
Pros: Easy to implement, easy to understand, easy to extend for other applications as well (we had a CLI that accessed the same REST API as well).
Cons: It's impossible for the REST API to know which user is actually accessing it. If a trusted client is compromised the whole system is compromised.
Have the server side of your web-app keep user details in the session and authenticate using the users credentials every time you access the REST API.
Pros: Fairly easy to implement (although some authentication mechanisms make it hard to keep hold of the user password - for good reason). The whole procedure is transparent to the REST API.
Cons: You're now storing (for all intents and purposes in clear-text) the username and password of a user in the session of the web-server - one of the most prime targets for attack in the system.
Create an authentication system on the REST API that authenticates a request with a username/password authorization and returns a token that is valid for a limited time.
Pros: More secure, if your web-app is compromised you're not providing the attacker with your users username/passwords, but instead only allowing them a limited time access.
Cons: Much harder to implement. You might need to deal with token timeouts specifically. For purists it also means that your REST implementation (or at least the authentication system) will be arguably "stateful".
What you should implement would depend on your situation. Personally I'd definitely go with the more secure option (the last one), but due to external constraints we were forced to implement the first option in our specific case (with the promise we'd revisit it and upgrade later - unfortunately later never comes).
I think your approach with using Basic HTTP Authentication in REST service and having your app authenticate with the service is perfectly fine. The only caveat here (which I am sure you are aware of), is that your REST service should run over SSL, as Basic HTTP authentication is not very secure - username and password are just Base64 encoded.
I am currently developing a web application that is right now comprised of a front end which displays and interacts with the data using a REST API we have written. The only thing that will ever use the API is our front end website, and at some point a mobile app that we will develop.
I have done a lot of reading about how OAuth is the ideal mechanism for securing an API and at this point I am starting to have a good understanding of how it works.
My question is -- since I am never granting access to my API to a third-party client, is OAuth really necessary? Is there any reason it is advantageous? Furthermore, because the back end is simply the API, there is no gateway for a user to authenticate from (like if you were writing an app using the Twitter API, when a user authenticates they would be directed to the Twitter page to grant to access then redirected back to the client).
I am not really sure which direction to go in. It seems like there must be some approach halfway between http authentication and OAuth that would be appropriate for this situation but I'm just not getting it.
From my point of view, one of the scenarios that favor OAuth over other options is to work with untrusted clients, no matter if these are developed by you or a third party.
What's an untrusted client? Think from the point of who handles the credentials that grant access to your API.
For example, your web application could interact with your API in two falvors:
Your web app server side talks to your API. Your web app server is a trusted client because the credentials to access your API can only be access by whom have access to the server...You and your team. You could authenticate your web app server with a client_id and a client_secret.
You may want to make calls directly to your API from your Web app client, which runs on the end user's browser using JavaScript. The end user's browser is an untrusted client. If you were to deliver the credentials to your API down to the browser, anyone could check the JavaScript code and steal your credentials.
A third party Native App is also untrusted. A malicious developer that uses your API could save the credentials of and end user of your platform.
Your Native App is a trusted client and could manage the authentication with a simple username , password and a client id identifying your App.
How can OAuth help? OAuth Authorization code and Implicit grants can help you with this issue. These flows only work with clients that support a redirect, like a browser. And let you authenticate an untrusted client and a user against your Authorization Server to gain access to your Resource Server, your API, without exposing the credentials. Take a look at the RFC to see how it is done.
The good thing of OAuth is that it not only supports these redirect based authentication flows, but it also supports client credentials grant and user credentials grant. So an OAuth Authorization Server would cover all cases.
OAuth 2.0 originally seems like a PITA if you think about having to build a lot of it yourself, but most languages have some really solid OAuth 2.0 setups which you can just bolt in with varying amounts of fiddling. If you're using a framework like Laravel or RoR then it's barely any work.
PHP: http://oauth2.thephpleague.com/
Ruby (Rails or Grape): https://github.com/doorkeeper-gem/doorkeeper
If you don't want to redirect users as suggested in your post then ignore other comments and answers that talk about two legged flows. You can use the client_credentials grant type to have apps just provide their client id and secret in return for an access token, which is nice and easy.
I would ask how private are we talking, because if the only systems talking to it are within the backend and have no interaction with the outside world you could probably leave it wide open and just rely on the network to keep it safe (VPN/Firewall).
But if it's private in the sense of "our iPhone app uses it" then you definitely want to go with OAuth 2.0, or something like it.
2 legged OAuth is probably what you want to use. It's basically hashing a shared key, but you have the advantage of not having to write the code yourself.
Here's a related question: Two-legged OAuth - looking for information
You should use Oauth for mobile device to API layer communication.
However, there is no benefit of Oauth in this web UI layer to middle-layer access (machine to machine).
On the other hand there are some potential issues
Managing the access token expiry becomes a pain. Consider that your UI has to cache the access token across multiple nodes in a cluster. Refresh it when expired, and the fact that UI layer is negotiating security with backend will just take extra time once in a while.
In two legged Oauth (OAuth Client Credential as in v2.0) does not support any encryption. So you still need to send key and secret both to the server for getting an access token.
Backend has to implement issuing access token, refresh token, validating access token etc, without any significant benefit