Authcode for Alexa BDD Tests using LWA - amazon-web-services

During Accountlinking, Alexa server initiates a Acceptgrant API with its Authcode so that it can be exchanged to Access Token. I want to test my API which accepts the Authcode
(postman or BDD Tests). How can we generate this ? It would be really helpful for automated tests.
I have tried LWA with AWS JS SDK. We need to whitelist the server in security profile. This basically opens a browser instance and appends a Authcode to the redirect_uri. Is there any other way than this? I read about CLI where we can get accesstoken but not authcode.
Also when we create a skill it generates a ClientId. Are there any security profiles for this ClientId ? How can I whitelist my server for this ClientId ? I didnt find a way to link this client ID to security profile.
Some more info:
I will elaborate a bit more. Basically Alexa sends a AcceptGrant directive during account linking when user enables the skill from alexa UI. AcceptGrant consists of Authcode so that User/bussiness(smart device manufacturer cloud) can get accesstoken using LWA. So now the bussiness has API exposed which accepts a Authcode. Now i am trying to test this API. Currently i dont find a way to generate this token.
If i generate authcode with LWA flow , this requires a redirect_uri. But if i use the code which is sent by Alexa (during accountlinking flow) , it doesn't require redirect_uri. From this page
https://developer.amazon.com/docs/login-with-amazon/authorization-code-grant.html#access-token-request
if i use AWS JS SDK it doesnt require a redirect_uri for access_token request. When i tried AWS JS to generate authcode, i get an secuirty error asking user to whitelist the domain. And i dont find a way to whitelist the client_id of Alexa to a security profile.

In skill linking, linking out from a skill to a 3p server, Alexa handles the auth code exchange and retrieves the access token for you. The auth code is never exposed to the skill because you don't need it.
It's only good once. After that, you use the refresh token returned when the auth code was used.
Maybe if you describe the use case you're trying to accomplish and why you believe you need the code, it'll be possible to give you more useful help.

Related

Authentication (AWS Cognito) for an microservice architecture with an angular frontend

I am in the process of building an microservice architecture with an angular frontend as ui component. Each microservice uses flask-restx and pycognito to secure its routes. The frontend uses aws-amplify to authenticate users. Each microservice expects a valid token for the secured routes, which is validated in the respective backend. In the aws user pool we created multiple app clients. The goal is to authenticate once against the webapp and use the token to access all microservice backend. I already tried to find the correct solution in the aws documentation but had no luck until now. Maybe somebody could give me a hint what is the best practice solution to get this done right.
Keep it simple and stupid (KISS).
I cannot see any use-case of multiple app clients.
Please follow the steps below at microservices end:
Cognito uses asymmetric keys to generate jwt token.
So, get the public key from Cognito by this code link.
Decode that jwt token by public key link.
Authentication will be done by above step. if invalid token is passed in request header jwt.decode function will raise exception link.
Decoded payload contains sub and store that sub in distributed db (dynamodb, SQL)
One can store custom attributes and assign Cognito user to group. This will help to authorize the individual users on the microservice side.
I hope that gives you a hint to go ahead.

How to confirm about NO JWT-auth connection for gateway connection of Cloud IoT Core

I have problems about JWT authentication. Using devices can't use JWT for specification of devices.
And then, I can connect to gateway on Google Console(Test environment) and use sample code of Google.
*cloudiot_mqtt_example.py
*gateway_demo.py
However, I don't know how to confirm NO JWT-auth.
I checked Stackdriver logging but I can't get logs for solving problem.
I can checked to send publishing data via gateway to devices and Cloud Pub/Sub. However, I need to know other method because using test environment can connect JWT and NO JWT.
I debugged source code above URL. This code is definitely via get_client.
def get_client(
~
client.username_pw_set(
username='unused',
password= create_jwt (
project_id, private_key_file, algorithm))
This create_jwt make token.
I think this source programs are using JWT authentication. Would you like to tell me how to check JWT authentication?
I wouldn't recommend connecting without a JWT , but you can check the JWT by printing it out and going to JWT.io and see if it matches your project specifications.
If you can't connect using a JWT then you might be providing the wrong setup information or your private key is wrong so the authentication of the JWT is wrong.

How to implement OAuth when the resource and auth servers are same

I have a Django Rest API with JWT authentication which is the backend for a Angular frontend. There are many clients who use the service with our frontend. Now some enterprise clients wanted to integrate the APIs from their system's backend. I don't want to remove JWT from current APIs. I am planning to create new APIs in the same backend with OAuth token for those users.
I wonder what is the best way to implement OAuth for this scenario.
I am thinking Client Credentials grant type is the best way.
Question1: Am I right that client credentials is the right approach ?
For those enterprise users, it is sufficient they get just access token through the UI interface so that they can access all our APIs.
But here the problem is one additional step of getting the Client ID and Client Secret first and using that to get Access Token.
Question 2: What is the use of client ID and client secret ?
Question3: Should my backend hide the process of generating Client ID and Client secret and just give Access token (or) give them Client ID and Client Secret and ask then to generate access token ?
Question 4: If I am giving them Access Token without client id and secret, is that fine to have infinite expiry time? and
TLDR; How to implement OAuth when the resource server and auth servers are same ?
There are 4 grant types in oAuth2 which is meant for different scenarios.
client credential : the consumer (app) make calls to back-end using the bearer token created using apikey(or clientId) and secret only. Mostly used for anonymous calls where generic information is retrieved.
Resource owner password credential (ROPC) : the consumer (app) make calls using the bearer token created using apikey, secret, username and password. Mostly used when you(your authorization server) already know the users(user database is handled in your own system).
Authorization code : the consumer (app) make calls using the bearer token created using an authorization code. The authorization code is provided by a 3rd party (which actually has/manages the logged in user data) and the created authorization code linked to the logged in user. Google and Facebook log in for various sites is a typical example. Facebook/Google gives an authorization code for those websites and they exchange that code for a token.
Implicit grant : Mix of password credential and authorization code. Instead of authorization code, you get a bearer token from the 3rd party authorization server.
Question1: Am I right that client credentials is the right approach ?
I think you can use CC if there is no user level logics in your backend. If userlevel involved, may be ROPC is a better choice
Question 2: What is the use of client ID and client secret ?
Client ID and Client Secret is very similar to username and password in an application level, which is used to obtain bearer token.
Question3: Should my backend hide the process of generating Client ID and Client secret and just give Access token (or) give them Client ID and Client Secret and ask then to generate access token ?
If you are implementing oAuth2, your consumer should create the access token. But looking at your use case, may be even a simple hash of userId+timestamp is sufficient. ;)
Question1: Am I right that client credentials is the right approach ?
Yes. Providing the new APIs do not need to be called in the context of an end user.
Question 2: What is the use of client ID and client secret ?
The client ID allows the auth server to identify the application
requesting the token (it's often carried through to the access token
too, allowing the API to identify the calling application).
The client Secret means the auth server can trust that the client is
genuinely who he says he is as only he should have the private client
secret for his public client ID.
It's effectively a username and password in this scenario.
Question3: Should my backend hide the process of generating Client ID
and Client secret and just give Access token (or) give them Client ID
and Client Secret and ask then to generate access token ?
Your Auth server should issue the client credentials to the application once and the application should provide those credentials every time they wish to obtain a token via the client credentials grant type.
authorization code grant, or implicit grant might be more suitable for this scenario. The first one allows you to add an authentication step before the tokens are returned to the users (might be useful if you want to integrate your JWT authentication to this as well) and the second one is mainly used for single-page applications, and does not include an intermediate authentication step. This one would be useful if you want to improve efficiency.
client_id and client_secret are given to you when you register a client application in your identity provider(authorization server). This client application does not mean an application or an API belonging to your clients, but your own application to which you plan to incorporate OAuth(and OIDC). These two parameters are useful when making the requests to authorization in order to obtain tokens. The server uses those values to determine whether the request is made by a valid application. Only you have access to those values as you will be the one who's registering the application with the server.
I think this question is answered in the previous section.
I think it would be better if you go through this before doing any implementation. It provides most of the basic knowledge you should have before implementing an OAuth system. I hope this answer was useful to you.

How can I authenticate users via social account from mobile app using retrofit2?

I'm trying to connect my website's API and mobile app. I need to authenticate the user with google account but I don't know how to do it.
I created the backend with Django. And I set the endpoint as rest-auth/google/. On the restframework's page, it requires Access Token and Code but honestly I don't get how I can test if it actually works using actual google account.
I want to test from mobile app but I don't understand how and what I need to POST.
Anyone could give me tips?
I would recommend you to use a ready solution like "django-allauth".
If you want to do authentication yourself you might want to read Google's documentation about the topic:
https://developers.google.com/api-client-library/python/
In nutshell you create API credentials:
https://console.cloud.google.com/apis/credentials
Send a user to a link with specific parameters (api-credentials, scope, redirect link etc). Google client can help you to generate it.
A user will login in his account as he would normally do and will give your app permissions to use his information (or won't). After that he will be redirected to the link you specified with GET request with a code as a parameter (or error).
With help of Google client you can exchange the code on a token and then use that token to get information from his profile.

Generate an OAuth2 token in a view

Let's say I have an AngularJS application that consumes the REST API of a Django application.
The Django application has got a built-in OAuth2 provider that can be called to retrieve an access token and use the protected endpoints of the API. This provider is using django-oauth-toolkit.
Let's assume there is a registered client with "password" grant type, so that the end users only need to provide their credentials in the front-end in order to get an access token from the back-end.
At some point we want to add some support for social networks login and we decide to use python-social-auth (PSA) to that end. Here is the workflow I want to achieve:
The user logs in on Facebook from the front-end (via the Facebook SDK) and we get an access token back from the OAuth2 provider of Facebook.
We send the Facebook token to an endpoint of our REST API. This endpoint uses the Facebook token and django-social-auth to authenticate the user in our Django application (basically matching a Facebook account to a standard account within the app).
If the authentication succeeds, the API endpoint requests an access token from the OAuth2 provider for this newly authenticated user.
The Django access token is sent back to the front-end and can be used to access the REST API in exactly the same way that a regular user (i.e. logged in with his credentials) would do.
Now my problem is: how do I achieve step 3? I first thought I would register a separate OAuth2 client with Client Credentials Grant but then the generated token is not user-specific so it does not make sense. Another option is to use the TokenAuthentication from DRF but that would add too much complexity to my project. I already have an OAuth server and I don't want to set up a second token provider to circumvent my problem, unless this is the only solution.
I think my understanding of PSA and django-oauth-toolkit is not deep enough to find the best way of reaching my goal, but there must be a way. Help!
I managed to get something working using urllib2. I can't speak towards whether or not this is good practice, but I can successfully generate an OAuth2 token within a view.
Normally when I'd generate an access token with cURL, it'd look like this:
curl -X POST -d "grant_type=password&username=<user_name>&password=<password>" -u"<client_id>:<client_secret>" http://localhost:8000/o/token/
So we're tasked with making urllib2 accomplish this. After playing around for some bit, it is fairly straightforward.
import urllib, urlib2, base64, json
# Housekeeping
token_url = 'http://localhost:8000/auth/token/'
data = urllib.urlencode({'grant_type':'password', 'username':<username>, 'password':<password>})
authentication = base64.b64encode('%s:%s' % (<client_id>, <client_secret>))
# Down to Business
request = urllib2.Request(token_url, data)
request.add_header("Authorization", "Basic %s" % authentication)
access_credentials = urllib2.urlopen(request)
json_credentials = json.load(access_credentials)
I reiterate, I do not know if this is in bad practice and I have not looked into whether or not this causes any issues with Django. AFAIK this will do this trick (as it did for me).