I am developing a cross-platform mobile application using Xamarin.Forms. I have an Amazon Cognito User Pool, equipped to do identity federation via third parties (Facebook, Google), as well as native application user auth (username/password), that contains all of my users. I currently have a single Cognito app client with a single redirect URL, https://localhost:PORT
I have written .NET Standard helper library that interfaces with Cognito. I have an interface ICognitoAuthHelper
which contains a method AuthenticateUserAsync(PoolRequest request)
. The PoolRequest
object has an AuthorizationCode
property which is used in auth code grant flows. The AuthenticateUserAsync
function essentially posts the authorization code to the Cognito app client TOKEN endpoint to receive a JWT, which I then have the utility library decode to retrieve the claims about the authenticated user's identity.
Enter the problem: I would like to leverage this utility library I have written to do authentication in my Xamarin.Forms app.
Here's a simple use-case, and how I would (and do) execute an auth flow in an ASP.NET Core MVC web app:
1) I make the click of the "Login with Facebook" button redirect to the AUTHORIZE endpoint of the Cognito app client
2) When the app client redirects back to my redirect URL (localhost
), I grab the code
query parameter out of the URL, wrap it up in a PoolRequest
, and feed it to my utility library. The library will then, as explained above, post the authorization code (code
) to the TOKEN endpoint to begin the decoding process of the returned JWT.
3) The response from the utility library will contain the user claims, and I can redirect to a profile page, set session variables, etc.
How can I achieve this sort of auth flow via a Xamarin.Forms app? I have considered using a WebView
, but am unsure as to how I can capture the auth code that will come back from the Cognito app client. What do I set as a redirect URL on the app client for Xamarin? How do I make the WebView
navigate to a profile page after I decode the token set?
Any help on this is greatly appreciated.
I think have solved this issue. I do not own a Mac, so I have only been able to test on Android, but the solution entailed a couple of things:
myapp://login
public ICommand FacebookLogin => new Command(FacebookLoginCommand);
public ICommand GoogleLogin => new Command(GoogleLoginCommand);
private async void FacebookLoginCommand()
{
var redirect = "<COGNITO APP CLIENT AUTHORIZE URL (FB)>"; //
await Launcher.OpenAsync(redirect);
}
private async void GoogleLoginCommand()
{
var redirect = "<COGNITO APP CLIENT AUTHORIZE URL (Google)>"; //
await Launcher.OpenAsync(redirect);
}
Note that here I am referencing the custom scheme redirect URLs, as described above, in the redirect
varibale.
IntentFilter
on my MainActivity
in the Android-specific project that specifies the custom URL scheme.[IntentFilter(
new [] { Intent.ActionView },
DataScheme = "myapp",
DataHost = "login",
AutoVerify = true,
Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable})]
public class MainActivity : global::Xamarin.Forms.Android.FormsAppCompatActivity
{
...
}
Override the OnNewIntent(Intent intent)
method in MainActivity
to capture the authorization code query parameter. It can be extracted with intent.Data?.GetQueryParameter("code")
.
Use my utility library to exchange the code for tokens/user identity