MSAL SignUp not returning access token for local accounts - xamarin

I've followed the tutorial code linked here:
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/authentication/azure-ad-b2c
But when signing up (which isn't covered in detail in above link), the AuthenticationResult returns a null access_token. Is there perhaps a b2C setting that I'm missing?

You need to represent a resource to obtain an access token for using app registrations
https://learn.microsoft.com/en-us/azure/active-directory-b2c/tutorial-desktop-app-webapi?tabs=app-reg-ga
You need to ask for a scope in the MSAL code to get an access token for a specific resource:
https://github.com/Azure-Samples/active-directory-b2c-xamarin-native/blob/master/README.md

Related

Error 400: invalid_scope Some requested scopes cannot be shown: [https://www.googleapis.com/auth/homegraph]

So I'm trying to use the Home Graph API by calling the API endpoint
https://homegraph.googleapis.com/v1/devices:requestSync
It is a HTTP POST request and it needs an ACCESS_TOKEN and service account key.
Getting the service account key is easily done as per Google's documentation. The issue is getting the ACCESS_TOKEN.
As per this documentation by Google, I need to get ACCESS_TOKEN created using the following scope of permissions
https://www.googleapis.com/auth/homegraph
I opened OAuth 2.0 Playground to request a developer temporary ACCESS_TOKEN for testing. I wrote all the necessary urls and in scope I wrote this-
scope is written to be authorized
Now after this, I am navigated to my Authorization URL (ie, Google's sign in page). I login with email id and password.
If credentials are correct and scope mentioned is valid then I should have been redirected to OAuth playground page with authorization code which I would have exchanged for access token and refresh token.
But, what actually happens is after I enter my credentials, I get following error and I am never redirected to Oauth Playground page-
Authorization Error
Error 400: invalid_scope
Some requested scopes cannot be shown: [https://www.googleapis.com/auth/homegraph]
Request Details
access_type=offline
o2v=2
response_type=code
redirect_uri=https://developers.google.com/oauthplayground
prompt=consent
client_id=xxxxxxxxx.apps.googleusercontent.com
scope=https://www.googleapis.com/auth/homegraph**
I searched a lot online too, but couldn't find the actual reason.
So due to this issue with scope, I am not able to get ACCESS_TOKEN.
I have followed Google's documentation and the scope was mentioned there.
This is the pic from oauth 2.0 playground settings- OAuth 2.0 configuration
The issue is that you, a user, should not be getting and sending an access token. The service account should be getting and sending an access token. This is to make sure your service is authorized to talk to the Home Graph API.
You indicated you logged into the OAuth playground with "userid and password". But service accounts don't have passwords.
If you are using one of Google's libraries, it will take care of getting the access token for you, and this is the easiest way to do so. If you are just testing and need an access token, you can use something like oauth2l to get the access token based on the service account credentials.
I had implemented the REST approach to call HomeGraph Report State as below.
We need to follow the below steps:
Create a service account for your project and safely store the json file
Using the service account JSON, get the access token from Google
Using Oauth 2.0 token as Bearer authorization, invoke Report State API
Step 1:
This is straightforward. Please follow the steps in the below link
https://developers.google.com/assistant/smarthome/develop/report-state#expandable-1
Step 2:
Refer below code to get the Access token using service account json
GoogleCredentials credentials = GoogleCredentials
.fromStream(Helper.class.getClassLoader().getResourceAsStream("smart-home-key.json"))
.createScoped("https://www.googleapis.com/auth/homegraph");
credentials.refreshIfExpired();
AccessToken token = credentials.getAccessToken();
return token.getTokenValue();
Step 3:
Invoke Report State API
curl -X POST -H "Authorization: Bearer [[Access token from Step 2]]"
-H "Content-Type: application/json"
-d #request-body.json
"https://homegraph.googleapis.com/v1/devices:reportStateAndNotification"
Reference Links :
https://developers.google.com/assistant/smarthome/develop/report-state#http-post
https://cloud.google.com/endpoints/docs/openapi/service-account-authentication
https://developers.google.com/identity/protocols/oauth2/service-account#httprest_1
https://developers.google.com/assistant/smarthome/develop/report-state#expandable-1

Spring security oauth2 login with google

I want to create a login with google option and give authorities to the user depending on the user info returned. I've successfully done what I want for login with github following this tutorial:
https://www.baeldung.com/spring-security-oauth-principal-authorities-extractor
which basically uses #EnableOAuth2Sso annotation and the following properties
security.oauth2.client.client-id
security.oauth2.client.client-secret
security.oauth2.client.access-token-uri
security.oauth2.client.user-authorization-uri
security.oauth2.client.scope
security.oauth2.resource.user-info-uri
I can't do the same for google, so the problem should be in application.properties. I register my app with google, download the json that is given to me along with id & secret, but there seems to be missing the uri for security.oauth2.resource.user-info-uri property. I've searched online for that uri and tried to run the app with some values but with no success. Am I right that I need this property and how do I find it?
You need to request this information during authorization via scopes. This information is returned in the Identity Token and not the Access Token. If you requested the identity information you can also call the Google OAuth endpoint with the Access Token which returns the Identity Token.

What to return after login via API?

I'm creating an API server which will be consumed by a mobile app that I will work on later. I have yet to see any reference of API best practices related to user flow and returned data even after searching for several hours.
My question is whether the login response of an API should return the a personal access token with the refresh token along with the user info? Or should I just return the token and make another API call for getting the user info.
I could just do what I have in mind but I'm trying to learn the best practices so that I don't have to adjust a lot of things later.
I need suggestions as well as good references related to my question.
Thank you.
It depends on what you are using for your authentication. If you are using libraries like Laravel Passport or JWT, you can have the token endpoint which returns the access token, refresh token, validity period and the token type (Bearer). You can then have an authenticated endpoint which will be used to get a user's profile based of the token passed in the request header.
However, if you go through the documentation for those libraries, in most there is an allowance to manually generate a token. You can use this in a custom endpoint that will return the token as well as the user profile Passport Manually Generate Token.
If you are using JWT, you can also embed a few user properties in the token itself. The client can the get the profile info from the JWT itself without having to make a round trip to the server. Passport ADD Profile to JWT
If you have a custom way in which you are handling authentication, you can pass the token as well as the user profile in the same response.
In the end, it's up to you to decide what suits you best.
Have you looked at OpenID Connect? It's another layer on top of OAuth 2.0 and provides user authentication (OAuth 2.0 does not cover authentication, it just assumes it happens) and ways to find information about the current user.
It has the concept of an ID_token, in addition to the OAuth access token, and also provides a /userinfo endpoint to retrieve information about the user.
You could put user information in your access token, but security best practice is to NOT allow your access token to be accessible from JavaScript (i.e. use HTTP_ONLY cookies to store your access token).

YouTube API - How to create a permanent access token?

I am using the access token to play my private videos in my android app and for that, I am created an access token.
But It says,
The OAuth Playground will automatically revoke refresh tokens after 24h. You can avoid this by specifying your own application OAuth credentials using the Configuration panel
I tried to add my own client secrets and ID and after creating a new token, it still displays the same NOTE.
How can I create a permanent access token that will not expire?
I tried to change available parameters like Access Type Online, Offline, and still shows same NOTE.
Google apis generally do not let you get a permanent access token
Access tokens have limited lifetimes. If your application needs access to a Google API beyond the lifetime of a single access token, it can obtain a refresh token. A refresh token allows your application to obtain new access tokens.
Generate an offline refresh token to use and get a short lived access token
This is part of the Oauth2 standard

Alexa skill account linking with Google APIs credentials, problem refreshing token

I'm having some problems with the Alexa account linking authorization.
These are the steps I followed:
I got the credentials (client id, client secret...) from the Google Cloud Console
Setup on the Alexa Developer Console, using 'Auth Code Grant' as authorization grant type
Activated the skill on my Alexa application and successfully logged in with my Google account
Now I got the access token in the request, in handler_input.request_envelope.context.system.user.access_token
The problem is that the access token expires after one hour and Alexa does not manage the refreshment of the token.
What should I do to avoid having to ask my users to login every time after one hour? Should I use Implicit grant as authorization type? Should I get a refresh token somehow?
Additional info: it's a custom skill that connects to an AWS Lambda using Python3
While #pinoyyid's answer was correct, it didn't provide a solution so I'm posting one for future reference.
The problem was indeed that Amazon servers did not receive a refresh token from Google, thus making it impossible to refresh the access token after its expiration time of one hour.
Following this link and other Amazon forum posts, I got to a working solution.
Amazon Alexa developer console 'Account Linking' configuration:
Authorization grant type: Auth Code Grant
Authorization URI: https://accounts.google.com/o/oauth2/v2/auth?access_type=offline (even though the one from the google credentials was not v2, it shouldn't make a difference)
The access type is very important because, as documentation goes:
Set the [access_type] value to offline if your application needs to refresh access tokens when the user is not present at the browser. [...] This value instructs the Google authorization server to return a refresh token and an access token the first time that your application exchanges an authorization code for tokens.
Access Token URI: https://accounts.google.com/o/oauth2/token
Client ID & Secret: downloaded on Google Cloud Platform
Client Authentication Scheme: HTTP Basic
Domain List: google.com and googleapis.com
Default access Token Expiration Time: left empty
Now, after doing this and saving the configuration, be aware that you might not notice the change, as, from here:
When Alexa uses the refresh token to retrieve a new access token for an existing user, Alexa uses the access token URI that was configured at the time the user linked their account. Therefore, if you change the access token URI later, users who linked their accounts before continue to use the old URI for retrieving updated tokens. The users must unlink and re-link accounts to switch to the new access token URI.
So, in order to complete the procedure:
Deactivate your skill
Go to the Google third party applications that have access to your data and remove your Google Project associated
Reactivate your skill and login again (if done correctly it should ask you the permissions for the scope you specified in the Alexa developer console again
Done! after one hour you should re-try and it should have a renewed access token
Additional Info
I found that many suggested to retrieve the refresh token, I don't believe this is possible because, even if Google sends it, it's Amazon that stores it and uses it to refresh the access token.
EDIT:
This works fine for developing and testing but I discovered here that for publication purposes you must own the landing page that you redirect your users to. For me it was just necessary to create a simple HTML page hosted in a public S3 bucket that would redirect the request to the Authorization URI I wrote before, while the Access Token URI must remain the Google one.
Have you read https://developer.amazon.com/docs/account-linking/configure-authorization-code-grant.html ?
My guess is that the Refresh Token is missing because you have already auithorised the app. The RT is only issued once. Try going into https://myaccount.google.com/permissions?utm_source=google-account&utm_medium=web to revoke the permission and try again.

Resources