How to verify realUserStatus value in Sign In With Apple - ios

When signing in using Sign in with Apple for the first time, it returns a value realUserStatus as a part of ASAuthorizationAppleIDCredential in the iOS client. This value indicates whether Apple is confident that the user is real, or not (e.g. it's a script)
My question is how can I verify the value of realUserStatus in my backend authentication system?
Because the realUserStatus is returned to iOS client, and the client should tell my server whether it is a bot or not! How can I know if it's not just a script and telling the server that it is real?
Edit (additional clarification):
In Apple’s docs it says “ You can skip any additional fraud verification checks or CAPTCHAs that your app normally uses.” but when we use CAPTCHAs, the provider can verify the response, something either Apple doesn’t do, or I can’t find anywhere how to do it!

I just finished a call with an Apple engineer on WWDC online lab.
So from the iOS 14, the realUserIndicator is included in the identity token, and can be verified with the server.
For iOS 13 they don't have a solution.

This flag serves as a basic first validation, meant to be used by your frontend. The identification servers will return this value only when the user first uses Sign in with Apple in your app.
If you want to verify the user on the backend, you should use the user identity token (JWT). You get it from Apple's servers when the user signs in (read here: https://developer.apple.com/documentation/signinwithapplerestapi/authenticating_users_with_sign_in_with_apple).
If you want to verify the user on the upcoming sessions, as an existing user (without the user having to sign in every time), you should develop a system of your own, for creating, saving, and validating a token. Another option is to use Firebase auth framework, which supports apple sign-in.

if you send the fetched user’s information to app server(your backend) you can verify user by the identity token with a rest service.
Apple document says:
After your app receives the user information, you can verify their associated identity token with the server to confirm that the token is not expired and ensure it has not been tampered with or replayed to your app. For information about retrieving the identity token, see Authenticating Users with Sign in with Apple.
https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/verifying_a_user

Related

Revoke id token Google oauth2 java

I want to revoke the session of a user logged in to my app with google authentication.
I retrieved the informations for this user available on this image. Among them we find his token, useful for the revoke.
According to the documentation provided by Google there is a REST call to answer my problem.
https://developers.google.com/identity/protocols/oauth2/web-server#tokenrevoke
However I get this error every time :
The requested URL /revoke?token=eyJhbGciOiJSUzI1NiIsImt..........
was not found on this server. That’s all we know.
Maybe the token which is not valid but I don't understand why in this case.
I think we need to start with being clear as to what it is you are trying to do.
If you are trying to log the user out of their google account the anwser is you cant. Google does not allow third party apps to log users out of their accoutns.
If you are trying to log the user just out of your app itself. Then assuming you have a web app just delete the session or the cookie depending upon how your system is running.
If it is an installed app again just delete the stored tokens which you either have stored in a var you are passing around or in your database.
If you want to completely have the users consent to your using their Google data removed then you would use the revoke command. Revoke world require that you send a valid access token. This will remove all consent that the user has granted your application to access their data. Revoke is not preformed on an Id token.
However by looking at your image I can see that you have an id token, which implies to me that you are using Google signin which is not Oauth2. Revoke is intended for use with Oauth2. Try sending the one that say authToken that might work. If not I think you should just remove the session cookies.
POST request works, GET request return the known error

Bot framework doesn't return JWT

I'm building an app for Microsoft Teams which requires the user to sign-in inside a bot dialog or message extension. The overall sign-in process works fine. I'm retrieving the token via BotFrameworkAdapter.getUserToken() and if no token is available, the user will be prompted to login based on BotFrameworkAdapter.getSignInLink().
Usually, the token is a JWT. This allows me to decode the claims and verify that it contains all scopes that are currently necessary to use the app. If I'm adding a Graph API permission in the future (e.g. for a new feature), I can therefore prompt the user to sign-in again so that the app doesn't break for users who are already signed in with lesser permissions.
Since recently, tokens are increasingly not issued as plain JWT. Rather, they look similar to an example from the Graph API documentation:
EwAoA8l6BAAU7p9QDpi/D7xJLwsTgCg3TskyTaQAAXu71AU9f4aS4rOK5xoO/SU5HZKSXtCsDe0Pj7uSc5Ug008qTI+a9M1tBeKoTs7tHzhJNSKgk7pm5e8d3oGWXX5shyOG3cKSqgfwuNDnmmPDNDivwmi9kmKqWIC9OQRf8InpYXH7NdUYNwN+jljffvNTewdZz42VPrvqoMH7hSxiG7A1h8leOv4F3Ek/oeJX6U8nnL9nJ5pHLVuPWD0aNnTPTJD8Y4oQTp5zLhDIIfaJCaGcQperULVF7K6yX8MhHxIBwek418rKIp11om0SWBXOYSGOM0rNNN59qNiKwLNK+MPUf7ObcRBN5I5vg8jB7IMoz66jrNmT2uiWCyI8MmYDZgAACPoaZ9REyqke+AE1/x1ZX0w7OamUexKF8YGZiw+cDpT/BP1GsONnwI4a8M7HsBtDgZPRd6/Hfqlq3HE2xLuhYX8bAc1MUr0gP9KuH6HDQNlIV4KaRZWxyRo1wmKHOF5G5wTHrtxg8tnXylMc1PKOtaXIU4JJZ1l4x/7FwhPmg9M86PBPWr5zwUj2CVXC7wWlL/6M89Mlh8yXESMO3AIuAmEMKjqauPrgi9hAdI2oqnLZWCRL9gcHBida1y0DTXQhcwMv1ORrk65VFHtVgYAegrxu3NDoJiDyVaPZxDwTYRGjPII3va8GALAMVy5xou2ikzRvJjW7Gm3XoaqJCTCExN4m5i/Dqc81Gr4uT7OaeypYTUjnwCh7aMhsOTDJehefzjXhlkn//2eik+NivKx/BTJBEdT6MR97Wh/ns/VcK7QTmbjwbU2cwLngT7Ylq+uzhx54R9JMaSLhnw+/nIrcVkG77Hi3neShKeZmnl5DC9PuwIbtNvVge3Q+V0ws2zsL3z7ndz4tTMYFdvR/XbrnbEErTDLWrV6Lc3JHQMs0bYUyTBg5dThwCiuZ1evaT6BlMMLuSCVxdBGzXTBcvGwihFzZbyNoX+52DS5x+RbIEvd6KWOpQ6Ni+1GAawHDdNUiQTQFXRxLSHfc9fh7hE4qcD7PqHGsykYj7A0XqHCjbKKgWSkcAg==
Although this looks like Base64-encoded data and it even says jwt above the snippet in the documentation, this is clearly not a plain JWT. Honestly, I'm not quite sure what it is, however, I assume it is a JWS or a JWT encoded with a nonce.
I'm thinking that I should probably treat this token as opaque, however, because the sign-in (and sign-in link generation) is hidden behind the bot framework I don't see another opportunity for adding permissions to an already deployed application, i.a. verifying that an access token provides the required permissions. Since my app also acts on behalf of the user at a later point in time, it's also not viable to prompt for sign-in after I'm receiving a 403er response from the Graph API.
Is there a way to decode these kinds of tokens or instead make sure that my app will only receive decodable JWTs?
If not, is there an alternative for verifying access token permissions (scopes)?

While submitting app in App Store, how to provide credentials when its Mobile OTP based login?

Currently, I'm trying to upload an app to the App Store but since my application is OTP-based login, even if I provide my number it'll send the OTP to my number. I'm also using JWT tokens for every logged-in user. Internally every API call is using JWT Auth, So demo creds will be too much of a workaround
I've sent the test credentials as my number and some random OTP and also I provided the details in the notes section but my app got rejected mentioning credentials are not valid. Any workaround for this?

Spotify iOS SDK Refresh Tokens

Evening all!
Quick question for all of those who are familiar with the Spotify iOS SDK .
(Please note: For those who don't, please don't provide any assistance because it is a procedural question rather than a programatic question).
So, I have successfully authenticated and received a session token (and accompanying Refresh_Token on the server). My understanding is that the Refresh_Token is not passed back to the iOS app and should be stored on the server to be used when the original session has expired and you need to renew without user interaction.
My question is how are people storing the Refresh_Token? Surely you would need to store it alongside the user's Spotify username (which is never disclosed to the tokenswap server?!). How would I go about getting the username?
I've played around to see what gets passed to the Token Swap server, when you first request a session, it passes Code and returns Session, Bearer, Expires and Refresh Token. When you ask for a renew, it passes the Spotify username only. So I don't have anything which is kept the same across both requests to use as a unique identifier of which user is making the request.
Hopefully, that can be understood! Please don't hesitate to ask for clarification!!
Thanks!
The Spotify iOS SDK ships with a token swap server that stores refresh tokens by username for you. Open it up and you'll have en example on how to do exactly what you want to do:
https://github.com/spotify/ios-sdk/blob/master/Demo%20Projects/spotify_token_swap.rb
Basically, have your token swap server do a request to the /me endpoint to get the username.

Design for Facebook authentication in an iOS app that also accesses a secured web service

Goal:
Allow a user to authentication with Facebook into an iOS application which requires access to a protected web service that I'm running.
Assumptions:
There is a native authentication (and registration) system in place for those users that opt not to use Facebook for sign in.
Details:
Assume we want to offer the option for a user to sign in with Facebook without creating a separate account/credential for our system.
Because we support our own native auth mechanism (username and password) we have our own user IDs and issue an authentication token that is used for subsequent interactions after the initial credential validation.
I'm surprised that Facebook doesn't have best practices for this in their developer documentation. All the existing documentation is either assuming you are building FB auth into a website, or a standalone mobile app with no service that requires authentication.
Here's my initial thoughts on how this would be designed but want validation on whether it's correct.
Client pops the Facebook iOS Login
UI User signs in with Facebook credentials and gets access token
iOS App passes access token to our server
Our server talks to FB graph API using access token to (a) validate the token and (b) get the FB user ID for that access token.
e.g. Our server would call https://graph.facebook.com/me/?access_token=XYZ which would return profile info in a JSON object
Assuming it's valid, our server extracts the User ID from the JSON object and checks whether the user already has an account. If so, we issue our own auth ticket to client to use for that session. If user doesn't have an account, we create a new one with the Facebook User ID, assign our own unique UserID and issue our auth ticket.
Client then passes auth ticket back on subsequent interactions that need authentication.
This seems like the right approach to me but not sure if I'm missing something insanely basic and going down the wrong (complicated) path.
I just dealt with this myself, and here's the part that bit me:
In your step 5... It's possible for a user to register for an account with you entirely separate from their Facebook ID, right? Then some other time they log in with Facebook.... And you just created them a second account and lost their first one.
There needs to be a way to be logged in to your web service, then log in to facebook, and capture the association between the facebook ID and the local account.
Apart from that, your plan sounds solid.
Update: Facebook has added a doc outlining such a scenario HERE
Use https to transmit the auth token to your server, as stated by Facebook
Sharing of Access Tokens
Our Data Policies explicitly prohibit any sharing of an Access Token
for your app with any other app. However, we do allow developers to
share Tokens between a native implementation and a server
implementation of the same App (ie. using the same App ID) as long as
the transfer takes place using HTTPS.
One problem I can see with this strategy, is that somebody can give you an access token obtained for a different facebook app. As far as I know, there's no way to verify that the access token is for your application, so you'll just go on and use it.
It doesn't sound very harmful, though. Generally people/apps try to protect the access tokens, rather than sharing them.
One possible exploit of this would be, for somebody to create their own site or mobile app, obtain access tokens for their users and try to authenticate them, using your API. If this succeeds (the user is has a facebook account in your site), the malicious site will be able to use your API impersonating the user.
It's a bit of a long shot, but I think it could work.
Edit: It looks like there is a way to validate the access token after all. See the answer by #Daaniel on question Get application id from user access token (or verify the source application for a token).
your solution totally works.
Maybe an alternative: why not just get the email on the client from the initial social service request and send to your web service? The web service could just store the email, and maybe a social_provider as well. I understand that your web service will not be able to validate where the email came from, but isn't there a high-trust relationship between your web service and your client? If there is, seems like you can depend on the email coming from the right place. Someone please let me know what obvious thing I'm missing that makes the email-based approach silly...

Resources