Getting nest pin without a UI - nest-api

I have a web client that talks to a .NET webservice for data and control of various household systems. I want to expose nest thermostat control in the web client via the .NET webservice. I understand the typical auth process requires "users" to authenticate a client using the provided "works with nest" page to get a code and then use that code to get a token. In my case the .NET webservice is the client and there is no user or UI to allow a user to "accept" and thus I need a way to get the auth token (or pin) without pushing a webpage in front of a user? Is this possible? thanks
UPDATE:
I manually went through the process of generating a token and discovered the expires number to be rather large (10 years). Given that is there any reason I can't just use that token in my .NET app with all future rest calls?

The token will only allow you to access the approving account, so if this application is for your personal use, then yeah, just hard code the token.
If you .NET service can handle an oAuth callback (A little confused about how you would have a webservice that can't serve HTML) then you can enter the callback URI into your client settings on developer.nest.com and the PIN will be returned directly to the service for you. The callback URI must start with https:// or http://localhost though.

Just a note, if you're using a web service, specifically a SOAP service, then XML will be returned on the callback, not HTML. In the case of the nest API, JSON is returned.
In the case of oAuth, it's done on the lower level protocol of http using headers, URIs and the like. Here is the link to the standard:
https://www.rfc-editor.org/rfc/rfc5849

Related

How to let frontend know your server has successfully retrieved an access token

I've been studying the OAuth 2.0 authorization code flow and am trying to write a React application with an Express backend that displays what a user would see on their own Instagram profile. I'm trying to do so with minimal external libraries (i.e. not using passport-js) and without bringing a database into the mix.
This is my flow as of now:
Resource owner clicks an <a> tag on the React application (port 3000) which redirects them to the /auth/instagram endpoint of my Express server (port 8000)
res.redirect(AUTHORIZATON_URL) sends them to Instagram's authorization server
Resource owner consents and the authorization code is sent back to the predefined redirect-url /auth/instagram/callback with the authorization code set as a query parameter
I strip the authorization code off the url and make a POST request to https://api.instagram.com/oauth/access_token to grab the access token
Now that I have the access token, how do I reach out to the React frontend to let them know that everything worked and that the user was successfully authenticated?
From what I've read, this is where the idea of sessions and cookies come into play, but I haven't had luck finding documentation on how to achieve what I want without bringing in third party libraries.
In the end, I would like for my app to support multiple users viewing their profiles simultaneously. Since I imagine passing the access token to the frontend defeats the purpose of securely retrieving it on the backend, I'm guessing I will somehow need to pass a session id between the frontend and backend that is somehow linked to an access token.
Any ideas as to what my next steps should be are greatly appreciated, as well as any articles or documentation you see fit. Thanks!
Since you're doing the OAuth authentication on the server side, you have to pass some parameter to the redirect_uri, identifying the user session (see: Adding a query parameter to the Instagram auth redirect_uri doesn't work? );
When the redirect uri is called from the authority server, you will know which user was authorized. To notify the browser there are two options: 1) Notify the client using web sockets; 2) Pull the state from the client using a timer triggered function;

Sharepoint REST API from native client without user

I understand how to access the Sharepoint REST API using interactive authentication, i.e. having a user at the computer type a username/password into a webapp. Is there a way to let a commandline app access the API? e.g. connect and query a Sharepoint list without user intervention?
I've registered a native client in the tenant and have an AppId (no app secret) but all API calls return 401 Unauthorized. I've also tried accessing via the Graph API but get 403 Forbidden. These are both using the access_token from the initial client_credentials flow of a tenant registered web app, which I would expected to have worked.
It doesn't appear to be possible to get an access_token using only an AppId as the flow requires a client secret.
This says:
This type of permission requires administrator consent and is also not
available for native client applications
which doesn't appear to make sense as it requires administrator permissions for something that can't be done. If native clients can't access APIs it's not clear what they're for. Perhaps the above refers to web apps rather than native clients, i.e. an Admin can allow a web app to connect using an access_token without a user context.
Regarding getting the token from SharePoint (using the SharePoint REST API) please see my answer to this post: https://stackoverflow.com/a/52582017/6445723
The mechanism is basically the same, you do the POST request described there from your application and get the answer in the FormDigestValue property. Use this value henceforth in ALL your API calls by placing it into the X-RequestDigest HTTP header.
AFAIK there is no difference in authentication mechanisms for native clients or other web applications. Some libraries like the SharePoint PnPJS can abstract out the REST call above, but they do pretty much the same thing.
You need to enable Basic Authentication credentials are sent in clear text in Authentication Providers. Goto Central Admin>> Security>>Security Authentication providers>> In Right side dropdown select the Application and click on default
Tick Basic Authentication in Claims Authentication Types

WEB API authentication from different platforms

I need to create API application which will be accessed from different platforms (WEB, WPF, Mobile). The API will be hosted on Azure and client will be different websites and desktop/mobile applications. API need to know username to return user-specific information
I have some problems with authentication right now. I used idea from this thread how to do forms authentication to API, but there is a problem there, I have to authenticate each request to API, because the cookie which I created in previous request is not stored to next request.
I am thinking about creating some custom solution there: when login request to API sent with username/password return some kind of token which i will store on client and will pass with each request. In that case I can override AuthorizeAttribute and validate the token.
but I don't believe then I should create custom solution and prefer to find a way to use something Microsoft did for me.
What will be the best way to authenticate to WEB API from different platforms?
In case if I will return token, what is the best way to create it, encode it, expire it...?
There is nothing available out of box currently, to the best of my knowledge. With OWIN, there are things coming up. You can take a look at Katana source code (Microsoft.Owin.Security). For JSON Web Token, Microsoft has the JSON web token handler. More info here. The JSON Web Token Handler can both create and validate JWT. You can use the same library to issue and validate JWT respectively from the token issuer and your web API. Creating all these infrastructure is not easy. Thinktecture identity server and identity model can make these tasks easier for you. Both are open source and you can take a look at the source code in github. Check out this and this. Another good resource is Dominick's blog.

Self Hosted Web API Authentication

I have a self hosted Web API running, which using DotNetOpenAuth to issue authorization tokens. Basically, the project consists of 2 ApiController endpoints (Authorize and Token). I would like to force the client to have to log in to a form, prior to being able to call either endpoint. (Forms Authentication I guess). However, doesn't seem like it works for self hosted Web API projects, so, I am trying to implement something myself.
As of now, when the user calls the Authorize web get method, I render the login page and force them to login. However, I would like to have a mechanism in place so that once the user logs in, I can send a cookie response. I understand that if you write the cookie in the response, the browser will automatically send any relevant cookies upon subsequent requests.
However, my test client uses a HttpWebRequest to call my web api. Do I have to build the mechanism to save the response cookie to a file on the hard disk, and then, read it back, and associate with the HttpWebRequest on subsequent requests? Or , is there something built into the framework which I can leverage (just like how a browser would automatically take care of this for me).
I figured that once I could figure this part out, I could just extend the AuthorizationFilterAttribute, and use that to check the validity of the incoming cookie.
Thanks. Any help or suggestion is appreciated!

How do I secure REST API calls?

I'm developing the restful web app that using some popular web framework on the backend, say (rails, sinatra, flask, express.js). Ideally, I want to develop client side with Backbone.js. How do I let only my javascript client side interact with those API calls? I don't want those API calls to be public and be called by curl or simply by entering the link on browser.
As a first principle, if your API is consumed by your JS client, you have to assume, that it is public: A simple JS debugger puts an attacker into a position, where he can send a byte-for-byte identical request from a tool of his choice.
That said, if I read your question correctly, this is not, what you want to avoid: What you really don't want to happen is, that your API is consumed (on a regular basis) without your JS client being involved. Here are some ideas on how to if not enforce, then at least encourage using your client:
I am sure, your API has some sort of authentication field (e.g. Hash computed on the client). If not, take a look at This SO question. Make sure you use a salt (or even API key) that is given to your JS client on a session basis (a.o.t. hardcoded). This way, an unauthorized consumer of your API is forced into much more work.
On loading the JS client, remember some HTTP headers (user agent comes to mind) and the IP address and ask for reauthentication if they change, employing blacklists for the usual suspects. This forces an attacker to do his homework more thoroughly again.
On the server side, remember the last few API calls, and before allowing another one, check if business logic allows for the new one right now: This denies an attacker the ability to concentrate many of his sessions into one session with your server: In combination with the other measures, this will make an abuser easy detectable.
I might not have said that with the necessary clarity: I consider it impossible to make it completely impossible for an abuser to consume your service, but you can make it so hard, it might not be worth the hassle.
You should implement some sort of authentication system. One good way to handle this is to define some expected header variables. For example, you can have an auth/login API call that returns a session token. Subsequent calls to your API will expect a session token to be set in an HTTP header variable with a specific name like 'your-api-token'.
Alternatively many systems create access tokens or keys that are expected (like youtube, facebook or twitter) using some sort of api account system. In those cases, your client would have to store these in some manner in the client.
Then it's simply a matter of adding a check for the session into your REST framework and throwing an exception. If at all possible the status code (to be restful) would be a 401 error.
There's an open standard now called "JSON Web Token",
see https://jwt.io/ & https://en.wikipedia.org/wiki/JSON_Web_Token
JSON Web Token (JWT) is a JSON-based open standard (RFC 7519) for
creating tokens that assert some number of claims. For example, a
server could generate a token that has the claim "logged in as admin"
and provide that to a client. The client could then use that token to
prove that they are logged in as admin. The tokens are signed by the
server's key, so the server is able to verify that the token is
legitimate. The tokens are designed to be compact, URL-safe and usable
especially in web browser single sign-on (SSO) context. JWT claims can
be typically used to pass identity of authenticated users between an
identity provider and a service provider, or any other type of claims
as required by business processes.[1][2] The tokens can also be
authenticated and encrypted.[3][4]
Set a SESSION var on the server when the client first loads your index.html (or backbone.js etc.)
Check this var on the server-side on every API call.
P.S. this is not a "security" solution!!! This is just to ease the load on your server so people don't abuse it or "hotlink" your API from other websites and apps.
Excuse me #MarkAmery and Eugene, but that is incorrect.
Your js+html (client) app running in the browser CAN be set up to exclude unauthorized direct calls to the API as follows:
First step: Set up the API to require authentication. The client must first authenticate itself via the server (or some other security server) for example asking the human user to provide the correct password.
Before authentication the calls to the API are not accepted.
During authentication a "token" is returned.
After authentication only API calls with the authentication "token" will be accepted.
Of course at this stage only authorized users who have the password can access the API, although if they are programmers debugging the app, they can access it directly for testing purposes.
Second step: Now set up an extra security API, that is to be called within a short limit of time after the client js+html app was initially requested from the server. This "callback" will tell the server that the client was downloaded successfully. Restrict your REST API calls to work only if the client was requested recently and successfully.
Now in order to use your API they must first download the client and actually run it in a browser. Only after successfully receiving the callback, and then user entry within a short frame of time, will the API accept calls.
So you do not have to worry that this may be an unauthorized user without credentials.
(The title of the question, 'How do I secure REST API calls', and from most of what you say, that is your major concern, and not the literal question of HOW your API is called, but rather BY WHOM, correct?)
Here's what I do:
Secure the API with an HTTP Header with calls such as X-APITOKEN:
Use session variables in PHP. Have a login system in place and save the user token in session variables.
Call JS code with Ajax to PHP and use the session variable with curl to call the API. That way, if the session variable is not set, it won't call and the PHP code contains the Access Token to the API.

Resources