Monday, May 25, 2020

Temporary AWS Credentials with Third Party Identity Provider via STS and Android SDK

Role has been the preferred way to gain access to AWS for mobile apps instead of hard coded credentials. A mobile app can assume a specific role via AWS STS (Security Token Service) in which a temporary AWS credentials will be returned. However, the implementation is not as easy as I thought it would be. 

Problem

During my implementation time, I found that the documentation was not as clear and ended up spending a lot of time doing trial and error and re-reading articles.

One of my requirements is I don't want to rely on AWS Cognito for identity at all since I already use a third party identity provider. It is, however, possible to use AWS Cognito as a bridge between the mobile app and the third party identity provider. My next requirement is I don't want to use AWS Amplify. AWS pushes Amplify usage very hard and it is indeed very easy to use, but I'm not too fond of the level of abstraction for my application. Another requirement is if possible, I want to use SDK instead of manually making a REST call.

With those requirements in mind, I went to look for the documentation. My first meaningful documentation is the following article about AssumeRoleWithWebIdentity:


In that section, AWS recommends AWS Cognito and nowhere obvious can I find what to do if I don't want to use it. After missing it a few times, the link that says AmazonSTSCredentialsProvider at the end of the section gives a clue and it leads to the following blog post:


Although the blog says for iOS, it is also applicable to Android.

After rummaging through the API reference, AmazonSTSCredentialsProvider has many implementations, in which the one applicable to my case is the WebIdentityFederationSessionCredentialsProvider since it takes a token from third party identity provider and roleArn.


At this point, it is still not clear on what I need to do to be able to use the class above. 

Solution

After few more online searches, I found the articles below to be helpful:



Eventually, the articles above lead to the article that helps me setup the whole thing:


To make it work, few things I need to do:
  1. Create a role and note the ARN
  2. Create an IAM Identity Provider entity. The link can be found in the IAM console page.
  3. Set the role's Trust relationship with the Identity Provider as the trusted entity
  4. On the mobile app, I use the following code:
  5. At first, I made a mistake by providing an access token. It threw an error that it can't find iat property. When I switched to use id token, it managed to retrieve the temporary credentials which I then used to successfully to make an API call. For example, DynamoDB API call:
In conclusion, my code in Kotlin that works is:
val wif = WebIdentityFederationSessionCredentialsProvider(
                idToken,
                null,
                roleArn)
val dynamoDBClient = AmazonDynamoDBClient(wif)
dynamoDBClient.setRegion(Region.getRegion(region))
val scanRequest = ScanRequest(tableName)

Thursday, May 7, 2020

Forms Authentication Auto Redirects to /Account/Login

We are required to add a different authentication method on our ASP.NET Web Forms app. It is currently configured to use OWIN, so I thought I can just disable the current authentication method and revert to the old web.config forms authentication for testing purposes. Turns out it is harder than I thought.

Problem

After disabling the current authentication method, I add the common Forms Authentication web.config entry:

<authorization>
   <deny users ="?" />
   <allow users = "*" />
</authorization>
<authentication mode="Forms">
   <forms name=".ASPXFORMSAUTH" loginUrl="~/login.aspx" protection="All" path="/" timeout="30" />
</authentication>

Then I try to access the protected page and to my surprise I got redirected to /Account/Login?ReturnUrl=. That is weird and I verified other settings and none seems to be out of place. 

Solution

Searching online, I happened to find the following thread: 

https://forums.asp.net/t/1847413.aspx?How+is+authentication+mapped+to+Account+Login.

Following the instruction, I added the following under <appSettings> tag in web.config and it redirects properly.

<add key="loginUrl" value="~/login.aspx" />

Update 

5/8/2020

According to the following article, there is a way to disable the redirect instead of changing the destination.


To disable the auto redirect, add the following under <appSettings> tag in web.config:

<add key="enableSimpleMembership" value="false" />
<add key="autoFormsAuthentication" value="false" />