Wednesday, January 31, 2018

Understanding SFSafariViewControllerDelegate and SFAuthenticationSession on IOS 11

SFSafariViewControllerDelegate 
SFSafariViewControllerDelegate has added the below new method in iOS 11
public func safariViewController(_ controller: SFSafariViewController, initialLoadDidRedirectTo URL: URL)
but Apple does not give much information in the API document.

One may attempt to use this method in oAuth library to handle redirect url after authorization is validated. However the testing shows this method is only called when a redirect (301) happens during loading the initial url in SFSafariViewController. After the page is loaded, any redirect (301) happened in following requests from client to server will not trigger this method. Probably that is why the method name is "initialLoadDidRedirectTo".

In addition, after initial load is done, if javascript uses a html form to post the page to a different host and port, or uses window.location to set to a different host and port, none of the operations will trigger this callback method.

The above behaviour pretty much makes the new method useless for oauth authentication and the traditional custom url scheme is still needed to handle the oauth authentication from mobile device.

By the way, the SFSafariViewController use the same cache mechanism as mobile Safari browser, so in order to delete the cached response, such as 301 (Permanent Moved), you will need to clear the cache from Mobile Safari settings page. Just delete and reinstall the application on your iOS device will not delete the cache for SFSafariViewController.

  
SFAuthenticationSession
For ios 11, SFAuthenticationSession is a good choice to handle oAuth. The important thing is set the callbackurlScheme parameter properly.

Although the parameter can be set to nil, which will rely the application open URL delegate method to handle the oauth result, but that really does not make sense, as the point of using this new method is avoiding defining custom url scheme and the related logic in application's openURL method.

The callbackurlScheme must be set to a custom schema, setting it to "http" or "https" will not work. In addition, the parameter must only contain the scheme, not a full url. For example, if the oauth redirect url is "sapbi://mypayload", then the parameter needs to be set as "sapbi" without any colon or slash.

It does not matter whether the custom url is loaded by redirect or by form submit, as long as webview tries to open the custom url, the callback method will be called. Once the callback method is called, then the webview will be automatically dismissed, so there is no need to explicitly call cancel in the completing block.

The biggest benefit of the SFAuthenticationSession for oauth is no longer required the app to define the custom URL scheme at compile time, the oauth redirect url can be changed at runtime when creating the SFAuthenticationSession object.

Allow asp.net core apps running on IIS express accessible from external computer

By default Asp.net core applications running on IIS Express can only be accessed from localhost, in order to access it from other computer or mobile device, the IIS Express needs to have some custom configuration.

The below steps are for Windows 10 box with Visual Studio 2017:

1. Open IIS express configuration file under the Visual Studio project folder, like
ProjectName\.vs\config\applicationhost.config
(The file will be generated after running the project at least once)

Change the below setting from
   <bindings>
          <binding protocol="http" bindingInformation="*:50532:localhost" />

  </bindings>

To
        <bindings>
          <binding protocol="http" bindingInformation="*:50532:localhost" />
          <binding protocol="http" bindingInformation="*:50532:*" />
        </bindings>


2.Stop and restart Visual Studio in Administrator mode, and run the asp.net core app on IIS Express

I saw few people posted the solution requires firewall disable as well as netsh, but those steps are not needed in my testing. Although I have the McAfee installed on my windows box.

Friday, January 19, 2018

Using FireFox SAML tracer to fix SAML identity authentication issue

When using SAML authentication, sometimes after changing the SAML Identity provider from one to another, the SAML authentication may stop work, one reason that may cause the error is due to the different SAML identity provider may have configured different SAML attribute assertion.

FireFox has a nice SAML Tracer that can be used to figure out this issue. First installing the SAML tracer on FireFox browser, and then testing with the SAML identity provider that works, notice what subject ID and attribute assertions are sent in the SAML response. Then replacing the SAML identity provider to the new one and repeat the same testing, and check whether any attributes are missing or whether the format or attribute names are different.

For example, in a recent testing with custom SAP cloud identity provider, the user authentication always fails. After comparing the saml response, it indicates one attribute "display_name" is set by default SAP cloud identity, but is not configured by custom SAP cloud identity as shown below, after
adding the display_name attribute in the custom identity provider attribute then the function works as expected.


        <Subject>
            <NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">I826633</NameID>
            <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
                <SubjectConfirmationData InResponseTo="Sa71696cb-67b6-42c8-b667-e91abbf02f2b-HPjGyP7iI5mFsWJ2rfj_YOFtZs_6FfDhQhvVAtK5MYQ"
                                         NotOnOrAfter="2018-01-18T21:54:13.288Z"
                                         Recipient="https://mobile-i826633sapdev.int.sap.hana.ondemand.com/odata/applications/latest/com.sap.fiori.client.debug/Connections(&apos;cfd5cea6-d078-4ace-9125-c452ebb061d6')"
                                         />
            </SubjectConfirmation>
        </Subject>
        <Conditions NotBefore="2018-01-18T21:39:13.288Z"
                    NotOnOrAfter="2018-01-18T21:54:13.288Z"
                    >
            <AudienceRestriction>
                <Audience>https://sap.hana.ondemand.com</Audience>
            </AudienceRestriction>
        </Conditions>
        <AuthnStatement AuthnInstant="2018-01-18T21:44:13.288Z"
                        SessionIndex="S-SP-8698d43a-d131-4bc6-b623-26401f791236"
                        SessionNotOnOrAfter="2018-01-19T09:44:13.288Z"
                        >
            <AuthnContext>
                <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</AuthnContextClassRef>
            </AuthnContext>
        </AuthnStatement>
        <AttributeStatement>
            <Attribute Name="mail">
                <AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                xsi:type="xs:string"
                                >jonathan.li@sap.com</AttributeValue>
            </Attribute>
            <Attribute Name="display_name">
                <AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                xsi:type="xs:string"
                                >Jonathan Li I826633</AttributeValue>
            </Attribute>
            <Attribute Name="first_name">
                <AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                xsi:type="xs:string"
                                >Jonathan</AttributeValue>
            </Attribute>
            <Attribute Name="last_name">
                <AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                xsi:type="xs:string"
                                >Li</AttributeValue>
            </Attribute>
        </AttributeStatement>
    </Assertion>
</Response>

 AML response.

Monday, January 8, 2018

Using mobile Authenticator app for time-based two factor authentication TOTP

1. What authenticator mobile app does
Many major identity service (Google, Microsoft, SAP etc) providers have published their Authenticator mobile application for time-based two factor authentication. Essentially, the Authenticator app uses a shared secret between identity service provider and mobile Authenticator app, and current time to generate a passcode, and if the key matches with each other within 30 seconds period, then the identity will accept the passcode generated by Authenticator app and pass the authentication.

A sample authenticator configuration for google accout looks like below
otpauth://totp/Google%3Ajonathanli2000%40gmail.com?secret=rrrhpj3zrgzgwq4d53qrmyb6fsttuwee&issuer=Google

In addition, all authenticator apps use the same logic, so as long as they use the same configuration, then no matter the passcode is generated by with company's authenticator app, it can also pass the check by other company's identity service provider.

2. Where to implement TOTP two factor authentication
If the web application handles the user account by itself, like maintaining the user account in a user table, then the application must implement the TOTP logic, which keeps the secret key for each user account and then verify the client side Authenticator generated passcode based on the secret key and current time.
However, preferably, the user account management is handled by third party identity service provider. In that case, enabling and handling the TOTP authentication should only need to be configured and handled by the identity service provider, which is transparent to the application. For example, if the google social login service is used, once the two factor authentication using mobile device is enabled, then the user will be automatically prompted to input the Authenticator generated passcode during user authentication, there is nothing in the web app that needs to be changed for this purpose.


3. Note
The mobile authenticator app does not need to communicate with identity service provider when it generates the passcode, so it does not to be online when doing so.
In addition, user changes the account password does affect the mobile authenticator app, as long as the shared secret is not changed.

Thursday, January 4, 2018

View ipa file and its bundle content as regular folder on MAC

It is easy to view the content of an IPA file or bundle file in mac Finder. Instead of always needing to use the context menu of "Show Content" to open the bundle file.

For ipa file, just change the file extension from "ipa" to "zip" and then double click the zip file will extract the zip file to a regular folder.

Then in the payload subfolder, you will see a bundle file. In order to change the bundle file to a normal folder, right click the file and select context menu "get info", then from there, changing the Name and Extension section to remove ".app" from the file name. The bundle file now should show as a regular mac folder.