1 of 78

Secure and Usable OAuth for Mobile Apps

William Denniss, Product Manager, Google. @WilliamDenniss

2 of 78

We’ve spent a lot of energy promoting federated sign-on as a way to reduce password usage and improve the user experience.

But what happens when people don’t implement federated sign-on correctly?

3 of 78

The following is based on a true story.

4 of 78

Alibaba

5 of 78

6 of 78

7 of 78

8 of 78

9 of 78

10 of 78

11 of 78

12 of 78

13 of 78

14 of 78

15 of 78

16 of 78

17 of 78

18 of 78

19 of 78

20 of 78

21 of 78

22 of 78

23 of 78

24 of 78

25 of 78

26 of 78

27 of 78

28 of 78

29 of 78

30 of 78

31 of 78

32 of 78

33 of 78

34 of 78

35 of 78

36 of 78

37 of 78

38 of 78

39 of 78

40 of 78

41 of 78

*Phew*, I’m done.

42 of 78

48%

WebView

==

Bad conversion

WebView sign-in flows abandoned when no signed-in state.

43 of 78

Single Sign-On means you only sign-on once!

44 of 78

45 of 78

Wait a minute, can the host app inspect the webview?

46 of 78

The host app can extract the cookies:

String cookies = CookieManager.getInstance().getCookie(url);

Or inject javascript:

webView.evaluateJavascript(

"(function() { return document.getElementById('password').value; })();",

new ValueCallback<String>() {

@Override public void onReceiveValue(String s) {

Log.d("WebViewField", s);

}

});

47 of 78

Even trusted developers create risk

Third Party SDK

Third Party SDK

Third Party SDK

Trusted Developer

Enterprise

48 of 78

In-app Browser Tabs

To the rescue

49 of 78

In-App Browser Tabs

Secure context,

host app cannot inspect contents.

Shared cookie state

Custom tabs are

a system browser activity�presented in the app context

50 of 78

In-app Browser Tabs: A Better Way to Sign-in

Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem

51 of 78

52 of 78

If the user needs to login, they log in once

auth response

auth�request

Sign in

Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem

53 of 78

Subsequent requests get SSO

auth response

auth�request

Sign in

Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem

54 of 78

More Complex “Chained Auth” Works Too

auth response

auth�request

Sign in

Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem

55 of 78

Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem

56 of 78

Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem

57 of 78

Advanced Options: Mutual TLS with Certificates

Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem

58 of 78

Advanced Options: FIDO U2F over NFC!

YubiKey NEO

Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem

59 of 78

Most Devices support in-app browser tabs today!

96% of Android devices can run Chrome 45

84% of Apple devices support SFSafariViewController

Source: Apple, June 2016

Source: Google, June 2016

Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem

60 of 78

100% of users supported by launching �the browser as fallback

Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem

61 of 78

Production Example

The Google Sign-in library on iOS uses in-app browser tabs today.

https://developers.google.com/identity/sign-in/ios/

Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem

62 of 78

Implementation Details

63 of 78

Draft IETF Best Current Practice

Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem

64 of 78

Authorization Server Requirements

  1. Don’t assume that the client can keep a secret
  2. Support custom URI-scheme redirect URI
  3. Recommended: support PKCE (RFC7636)

Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem

65 of 78

PKCE to Protect the Code Grant

66 of 78

The following authorization servers already support the requirements of the best practice:

Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem

67 of 78

AppAuth: OAuth Client Libraries for Apps

Google made the initial contribution of AppAuth for Android and iOS to the OpenID Foundation’s Connect WG.

Android library: http://openid.github.io/AppAuth-Android

iOS library: http://openid.github.io/AppAuth-iOS

Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem

68 of 78

AppAuth for Android Codelab!

Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem

69 of 78

Cordova

My team has open sourced a plugin for cordova to support in-app browser tabs on iOS and Android.

https://github.com/google/cordova-plugin-browsertab/

CIS Launch!

Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem

70 of 78

Example Integration

71 of 78

AppAuth: Discovery

NSURL *issuer = [NSURL URLWithString:@"https://accounts.google.com"];��[OIDAuthorizationService discoverServiceConfigurationForIssuer:issuer� completion:^(OIDServiceConfiguration *_Nullable configuration, NSError *_Nullable error) {�� if (!configuration) {� NSLog(@"Error retrieving discovery document: %@", [error localizedDescription]);� return;� }�� // builds authentication request� OIDAuthorizationRequest *request =� [[OIDAuthorizationRequest alloc] initWithConfiguration:configuration� clientId:kClientIDscopes:@[OIDScopeOpenID,� OIDScopeProfile]� redirectURL:KRedirectURI� responseType:OIDResponseTypeCode� additionalParameters:nil];� � // next slide... perform authorization request�}];

72 of 78

AppAuth: Making the Authorization Request

AppDelegate *appDelegate =� (AppDelegate *)[UIApplication sharedApplication].delegate;��appDelegate.currentAuthorizationFlow =� [OIDAuthState authStateByPresentingAuthorizationRequest:request� presentingViewController:selfcallback:^(OIDAuthState *_Nullable authState,� NSError *_Nullable error) {� if (authState) {� NSLog(@"Got authorization tokens. Access token: %@", authState.lastTokenResponse.accessToken);� [self setAuthState:authState];� } else {� NSLog(@"Authorization error: %@", [error localizedDescription]);� [self setAuthState:nil];� }�}];

73 of 78

AppAuth: Declaring the redirect scheme

In the app’s XCode config:

74 of 78

A word on Redirect URI schemes

Choose a collision-resistant URI scheme like:

com.yourcompany.yourapp:/

�Avoid generic schemes like:

app:/

75 of 78

AppAuth: Receiving the OAuth Redirect

The response is delivered to the specified handler, and can be extracted from the intent data:

Code sample

- (BOOL)application:(UIApplication *)app� openURL:(NSURL *)url� options:(NSDictionary<NSString *, id> *)options {� // Sends the URL to the current authorization flow (if any) which will// process it if it relates to an authorization response.if ([_currentAuthorizationFlow resumeAuthorizationFlowWithURL:url]) {� _currentAuthorizationFlow = nil;� return YES;� }�� // Your additional URL handling (if any) goes here.�� return NO;�}

76 of 78

AppAuth: Making API Calls

[_authState withFreshTokensPerformAction:^(NSString *_Nonnull accessToken,� NSString *_Nonnull idToken,� NSError *_Nullable error) {� if (error) {� NSLog(@"Error fetching fresh tokens: %@", [error localizedDescription]);� return;� }�� // perform your API request using the tokens�}];

Read more at: http://openid.github.io/AppAuth-iOS/ and � http://openid.github.io/AppAuth-Android/

77 of 78

Given its flaws, and the viable alternatives, don’t assume Google will always support WebView for OAuth.

78 of 78

Thank You!

#AppAuth

William Denniss

@WilliamDenniss