I have a React.js web app that talks to a Golang REST API and I'm using AWS Cognito for authentication. It is all working but I am not confident that it is correct.
The web app provides username/password sign in using the AWS Amplify SDK, which returns an accessToken on successful login. I then set it as a cookie and use that in requests to the REST API.
The REST API authenticates the token using the AWS SDK and allows requests if the accessToken is verified.
I've read that storing the accessToken as a cookie is not safe but I don't know of another way around this offhand. I'm hoping encrypting it with some kind of public/private key approach will be good enough but I'm curious if there are any other obvious improvements that could be made.
Related
I am writing a google drive desktop application and I am using OAuth 2 to get credentials. I can get creds for just reading, but not changing files. As it is a desktop application, there is no site. It is written in https://developers.google.com/identity/protocols/oauth2/native-app, that I need to "supply a local redirect URI to handle responses from Google's authorization server". So, should the client also be a server and listening on some port locally? If I want to have the app verified, I need to provide Authorized domains and other stuff, but it is a desktop application, again. Or maybe there is a way to allow users to use the app, but with a warning on a consent screen for example for development purposes.
Also how to hide the credentials, that I use to get the token? If I publish the app with the credentials, everybody can just steal them and use them
In order to develop a desktop application which will use the Drive API you will have to use credentials of the web app type for which you will later provide the appropriate redirect URI.
By using OAuth 2.0 in your application, you are the only one who has access to the credentials for the application - unless you share them.
According to the Google OAuth 2.0 documentation:
You start by obtaining the OAuth 2.0 client credentials from the Google API Console. Then your client application requests an access token from the Google Authorization Server, extracts a token from the response, and sends the token to the Google API that you want to access.
For the login process, when the users will log-in to your application, they will use their own credentials and then they will have to authorize the application you have built in order to be able to use the Drive API.
Reference
OAuth 2.0 for Mobile & Desktop Apps;
Using OAuth 2.0 to Access Google APIs;
I've created a FeathersJS backend app and a React frontend app. I'm using OAuth2 strategy to authenticate users to my own WordPress site. Everything is working fine. But now I'd like the users to be able to access my FeathersJS backend REST API, but as they authenticate through the WordPress OAuth2 server, thus following all the OAuth2 authentication process through my React frontend app, which would be the correct FeathersJS way to allow the users authenticate to my backend so that they can do REST API calls?
But now I'd like the users to be able to access my FeathersJS backend REST API
To let people access your backend REST API (which I assume is only possible after they authenticate), you need to check whether the access token they have is, in fact, valid with the third party auth provider.
You can directly let them use the back end API. In case the API doesn't find a valid access token with the incoming request, it will redirect it to the login page. After which, now the backend can validate itself with third-party OAuth provider and return the result.
following all the OAuth2 authentication process through my React frontend app
It is recommended to not do all the OAuth check from front-end since this exposes the access-token on the user agent, which might be a serious issue. See this:
https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2#grant-type-implicit
Not sure if that is possible: I would like to switch from server flow to native client flow in order to provide a better authentication experience for my users.
The problem is that Azure AppService requires a "web application" OAUTH setup (contains client ID and a secret), while the native login works with just a client ID and not secret. This means that after the login on the phone, I do have a Google token, but AppService wouldn't know what to do with it and returns me an HTTP Unauthorized.
The mobile client SDK gives me an API, but that doesn't work with such a token.
var jObject = new JObject(
new JProperty("access_token", auth.AccessToken),
new JProperty("id_token", auth.IdToken));
await ServiceClient.LoginAsync(MobileServiceAuthenticationProvider.Google, jObject);
Any idea on the proper way to integrate this without having to write my own server-side token validation?
You would still need to configure the web application in Google since you are attempting to access a non-Google API. The native login on its own is not enough.
That means you will still need to provide the backend with an ID and secret. The client is responsible for obtaining an id token and authorization code which get sent to the server, and the server does the actual retrieval of the access token, per the Google documentation.
So that means your call will actually look something like the following:
var jObject = new JObject(
new JProperty("authorization_code", auth.ServerAuthCode), // not sure what property your auth binding exposes this as
new JProperty("id_token", auth.IdToken));
await ServiceClient.LoginAsync(MobileServiceAuthenticationProvider.Google, jObject);
There isn't documentation for the end-to-end using Xamarin.Android, but you might find it useful to glance over the App Service iOS documentation for this scenario just to see the moving parts. The general pattern you will follow is:
Configure everything for the server flow (as you've done before)
Set up the Google Sign-in SDK (seems like you've done that already, too).
Make the call as described above
The main issue you might run into is making sure that you have the API console registration correct. You'll want to make sure you have an Android client there connected to the web application client ID you are using. I'd recommend giving the Google Sign-in for Android setup instructions a quick look. Also note that authorization codes are one-time use, and there are some throttles that Google puts in place for a user requesting too many of them within some span of time. You might run into that during dev.
AS far as I know, the native client flow also use the google code flow to get access token.
According to this article, the Android, iOS, or Chrome applications doesn't need the secret to get the access token.
The client secret obtained from the API Console. This value is not needed for clients registered as Android, iOS, or Chrome applications.
But the web app backend will not authorized this access token if you don't set in your backend to enable Azure App Service authentication/authorization. Because the backend will have its own logic(the mobile server library write the logic according to the access token) to return the auth token according to the access token.
Now, the most easily way to enable the client flow in your mobile app is set in your backend to enable Azure App Service google authentication/authorization with the same clientid and secret(based on my test: if you don't set the right secret, the backend will still return the auth token).
Here is the test image:
If you still don't want to enable the app google easy auth, I suggest you could create custom authentication which contains your own logic to check the accesstoekn and get the user information from the google.
If the checked result is success and get the enough value, you could generate the auth token and return to the client side.
More details about how to create custom authentication in the mobile app backend , you could refer to this article.
I'm using Parse as my backend but I'm also using the AWS s3 service so I need to also use Amazon Cognito. So far Amazon Cognito integrates with 3rd party identity providers such as Facebook, Google, and Twitter but not Parse. So I'm guessing I would use the Basic flow which
"Uses Cognito + STS and requires identity pool plus IAM roles"
https://docs.aws.amazon.com/AWSiOSSDK/latest/Classes/AWSCognitoCredentialsProvider.html#//api/name/getIdentityId
since I'm using Parse as my backend I won't be able to use the Developer authenticated identities method. But I'm not entirely sure.
But my only issue is how I could get session tokens for temporary AWS Service access for users? Most of the tutorials/blogs I find online explain how to access the tokens on the server side but not on ios unless I'm missing a crucial concept here
If you're authenticating users with Parse, you should be able to use Developer Authenticated Identities, having the user send login credentials to your backend which would then validate those with Parse.
The mobile SDKs can get credentials to access AWS resources. These are vended for users based on their state, which is where the roles you mentioned come in. If you log in (with Parse, for example), your credentials would allow you to access what the auth role dictates, but if you don't, they'd be scoped to what the unauth role dictates. The developer guide has more information on getting credentials.
As far as your backend, have you looked into Cognito Sync? If you have and opted to go with Parse instead, was there a particular feature it was lacking that caused you to not use it?
I am currently trying to use amazon s3 for uploading images from IOS app with a Rails Back-end.
I currently don't understand how security works. In their docs
http://docs.aws.amazon.com/mobile/sdkforios/developerguide/s3transfermanager.html
it's not clear to me how to upload/destroy safely objects in sync with the back-end. For instance, in order to post/destroy, I was expecting a mechanism of asking a signature to the Rails server, and only then be able to upload the image to amazon. But I can't find this kind of mechanism.
Has someone gone through this kind with aws?
If you are using your server to generate temporary credentials for the AWS Mobile SDK, we recommend the following approach:
Generate the access key, secret key, and session token on your server. You have many language options including Java, .NET, PHP, Ruby, Python, and Node.js.
Implement your credentials provider by conforming to AWSCredentialsProvider. Take a look at the implementations of AWSWebIdentityCredentialsProvider and AWSCognitoCredentialsProvider as examples. This credentials provider should:
Retrieve the access key, secret key, and session key from your server.
Persist them locally until they expire.
Return the credentials when requested.
Re-retrieve them from your server if they are expired.
Initiate the credentials refreshing process when - refresh is called.
I encourage you to take a look at Amazon Cognito Identity. With Amazon Cognito, you can create unique end user identifiers for accessing AWS cloud services by using public login providers such as Amazon, Facebook, Google, and any OpenID Connect compatible provider, or by using your own user identity system. It covers many of the custom server use cases, and it is easier to use and manage.