KoenZomers / RingApi

Api in .NET 6 to communicate with the Ring Doorbell services
38 stars 18 forks source link

[BUG] Authentication Error #24

Closed brown-matt-att-net closed 3 months ago

brown-matt-att-net commented 1 year ago

I noticed that this is no longer able to authenticate and generating an error: Unhandled exception. KoenZomers.Ring.Api.Exceptions.AuthenticationFailedException: Authentication of the session failed

Digging into this with Postman

URL: https://oauth.ring.com/oauth/token
Method: POST
Body:
grant_type:password
username:{username}
password:{password}
client_id:RingWindows
scope:client

This gets a response of:

{
    "error": "unauthorized_client",
    "error_description": "The client is not authorized to request a token using this method."
}
KoenZomers commented 1 year ago

I've had many reports about this and did some digging this morning. Ring has changed their API implementation to no longer accept a password grant type. They never have documented their API, so all the work came from analyzing network traffic and/or inspecting the code of their apps. I've taken a look at the several other Ring API packages people have created and everyone was using the same API as I'm using here, so they've all stopped working.

Due to the stepped up security in the Ring apps (i.e. certificate pinning) I was unable to investigate how their apps do it themselves at the moment. I've tried this with both the Windows App as well as the Android App. This leaves us unfortunately at the position that at present it will be impossible to fix this until someone figures out a way to learn about how Ring does it themselves nowadays.

If anyone has any ideas how to discover it or has found a code sample where it still works today, I'll be happy to have another look at it.

KoenZomers commented 1 year ago

Did some further digging into the Android code and it looks like PKCE is now required to be used instead of ROPC which was used previously. Need to do some further digging how I would be able to obtain the code challenge in PKCE. If anyone has hints or tips, they're very much welcome.

chrisstuart-cl commented 1 year ago

I can authenticate using https://github.com/dgreif/ring and get a refresh token. I can then use that refresh token in the call to Session.GetSessionByRefreshToken(). That based on using 3FA.

KoenZomers commented 1 year ago

Hmm that's one of the ones I've looked at this morning as well. Interesting. Let me give that another try then.

chrisstuart-cl commented 1 year ago

Unfortunately, once past the authentication stage, it looks like other stuff has changed as for example session.GetRingDevices() returns The JSON value could not be converted to System.Nullable`1[System.Int64]. Path: $.stickup_cams[0].latitude | LineNumber: 0 | BytePositionInLine: 7469

KoenZomers commented 1 year ago

That should be relatively easy to fix though

KoenZomers commented 1 year ago

His TypeScript code works here as well, but I'm also unable to intercept its traffic. As far as I can judge from the TypeScript code I'm consturcting a similar message as he is, yet it still doesn't work for me:

HTTP POST https://oauth.ring.com/oauth/token

Headers: 2fa-support: true 2fa-code: hardware_id: User-Agent: android:com.ringapp Host: oauth.ring.com Content-Length: 111 Content-Type: application/json

Body: { 'client_id': 'ring_official_android', 'scope': 'client', 'grant_type': 'password', 'password': 'xxx', 'username': 'xxx@xxx' }

What am I missing?

chrisstuart-cl commented 1 year ago

I cloned your repo and changed: client_id: "RingWindows" to client_id: "ring_official_android"

Now the tests work.

KoenZomers commented 1 year ago

Woah really, is that all? Did I spend hours on trying to figure it out and its just that? :D Let me give this a try later myself. Thanks very much for sharing!

chrisstuart-cl commented 1 year ago

I don't understand why I can't get a successful response in Postman though. Seemingly with all the same inputs as your tests.

KoenZomers commented 1 year ago

I tried it using Fiddler and also couldn't get it to work and also didn't understand why not. I do remember when I initially wrote this code there was something very little about which the Ring API was very picky about. Can't recall what it was though.

KoenZomers commented 1 year ago

You're right, that's really just it. Works here now as well. I'll release a new version later today with this updated clientid. Much appreciate your help here :)

KoenZomers commented 1 year ago

This issue should now be resolved for the Ring API, RingSnapshotdownload and RingRecordingsdownload projects. If it still doesn't work well for you with the latest version, let me know.

vincentr commented 1 year ago

I've pulled down the latest API and rebuilt. Still getting the following;

Authenticating using refresh token from previous session ERROR: Unhandled exception. System.AggregateException: One or more errors occurred. (Authentication of the session failed) ERROR: ---> KoenZomers.Ring.Api.Exceptions.AuthenticationFailedException: Authentication of the session failed ERROR: at KoenZomers.Ring.Api.HttpUtility.FormPost(Uri url, Dictionary2 formFields, NameValueCollection headerFields) in D:\Git\RingApi\Api\HttpUtility.cs:line 167 ERROR: at KoenZomers.Ring.Api.Session.RefreshSession(String refreshToken) in D:\Git\RingApi\Api\Session.cs:line 249 ERROR: at KoenZomers.Ring.Api.Session.GetSessionByRefreshToken(String refreshToken) in D:\Git\RingApi\Api\Session.cs:line 99 ERROR: --- End of inner exception stack trace --- ERROR: at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) ERROR: at System.Threading.Tasks.Task1.GetResultCore(Boolean waitCompletionNotification) ERROR: at System.Threading.Tasks.Task`1.get_Result() ERROR: at KoenZomers.Ring.RecordingDownload.Program.Main(String[] args) in D:\Downloads\RingRecordingDownload-master\ConsoleAppCore\Program.cs:line 110 ERROR: at KoenZomers.Ring.RecordingDownload.Program.

(String[] args)

--a-- W32i DLL - 0.5.2.0 shp 89,600 07-05-2023 koenzomers.ring.api.dll

If I use -ignorecachedtoken, I get/enter the 2fa code and the authentication works

vincentr commented 1 year ago

UPDATE: I tried again today and it looks like after running with -ignorecachedtoken and entering the 2fa code the app was able to authenticate using the refresh token.

danespinosa commented 3 months ago

Closing since the issue seems resolved