an ios authentication architecture for all

Post on 12-Nov-2014

767 Views

Category:

Documents

6 Downloads

Preview:

Click to see full reader

DESCRIPTION

 

TRANSCRIPT

Get Ready1

An iOS Authentication Architecture for All

How to stop reinventing the auth wheel

2

René CacheauxSenior iOS Engineer

rene.cacheaux@mutualmobile.com

3

PatternThere’s a

for That

4

WHAT’S THE BIG DEAL?

5

SpendTime

Building Features

that ROCK

6

EngineerAmazingFirst Impressions

7

BuildReliable

andSecure

Apps

8

Meet John

9

10

13

What to Build? 14

15

Business Cards

16

Ready, Set...17

18

19

but then...

20

21

O...AUTH22

Really!?23

What exactly is OAuth?

24

I have to use a UIWebView?!

WAIT!

25

Is there a library for this??

26

YESGTMOAuth, whew.

27

Just Download

It!

28

But then...

29

Things start going wrong...

30

GTMOAuth1 or 2?

31

Is Linked in OAuth 1 or 2?

32

BOTH?

33

One Hour Later

34

35

Jen!

36

37

Jen went to CocoaConf and...

38

Well...There’s a Pattern

39

CocoaAuth

40

AND there’s a reference implementation

41

Auth Kit

42

Three PatternsThree Steps

43

Accounts

1 2 3Auth

ControllersAuth UI

Three PattersThree Steps

44

But first...

45

John chose OAuth 2for Linked in

46

Why?47

John chose Google’sGTMOAuth

48

Why?49

Back to:Three patterns

Three steps

50

Accounts

1 2 3Auth

ControllersAuth UI

Three PattersThree Steps

51

So we want to implement Accounts...

52

First An Intro

53

OAuth 2

Meet OAuth 2.0

54

1st thing...

55

It’s...

57

Opaque58

It has...

59

Scopes60

and it...

61

Expires62

That’s OAuth 2 Access Token

On to Step 1, Accounts

63

Accounts

1

64

If you need Auth you have user’s...

65

And if you have users, you need

account management

66

Accounts makes up the model layer

67

3 Entities in Accounts

68

1

2

3

Credentials

Accounts

Store

69

1

2

3

Credentials

Accounts

Store

70

@property(nonatomic, copy) NSString *accessToken;@property(nonatomic, strong) NSDate *expirationDate;

AKOAuth2AccountCredential : NSObject

71

That’s all for credentials, super easy.

Accounts is next.

72

1

2

3

Credentials

Accounts

Store

73

@property(nonatomic, copy, readonly) NSString *identifier;@property(nonatomic, copy, readonly) NSString *username;@property(nonatomic, copy, readonly) NSString *accountType;

- (void)clearCredential;

AKAccount : NSObject

74

Account Type

Subclassing

1

2

75

Account Type“com.linkedin”

76

Subclassing AKAccount

77

Base

Auth Protocol

Library

Class Structure

78

@interface AKAccount ()@property(nonatomic, copy, readwrite) NSString *identifier;

@end

@implementation AKAccount

+ (instancetype)accountWithIdentifier:(NSString *)identifier { return [[self alloc] initWithIdentifier:identifier];}

- (id)initWithIdentifier:(NSString *)identifier { self = [super init]; if (self) { _identifier = identifier; } return self;}

- (void)clearCredential { // Abstract method.}

@end

AKAccount Base

79

@class AKOAuth2AccountCredential;

@interface AKOAuth2Account : AKAccount

@property(nonatomic, strong, readonly) AKOAuth2AccountCredential *OAuth2Credential;

@end

@implementation AKOAuth2Account

- (AKOAuth2AccountCredential *)OAuth2Credential { // Subclasses should implement this. They should always access // credentials from a secure store. return nil;}

@end

AKOAuth2Account

80

@implementation AKGTMOAuth2Account

- (AKOAuth2AccountCredential *)OAuth2Credential { // Get credential from Google's GTMOAuth2 library.}

- (void)clearCredential { // Remove credential from storage.}

@end

AKGTMOAuth2Account

81

@property(nonatomic, copy, readonly) NSString *identifier;@property(nonatomic, copy, readonly) NSString *username;@property(nonatomic, copy, readonly) NSString *accountType;

- (void)clearCredential;

AKAccount : NSObject

82

1

2

3

Credentials

Accounts

Store

83

+ (void)registerAccountTypeClass:(Class)accountTypeClass;

+ (instancetype)sharedStore;

- (AKAccount *)newAccount;

- (void)saveAccount:(AKAccount *)account;

- (AKAccount *)authenticatedAccount;

AKAccountStore : NSObject

84

1

2

Account Ref Store

Credential Store

Implementing

85

1

2

Account Ref Store

Credential Store

Implementing

86

1

2

Account Ref Store

Credential Store

Implementing

87

Credential Store

2

1 Keychain

Library Provided

88

Keychain

1

89

Library Provided Store

2

90

- (AKOAuth2AccountCredential *)OAuth2Credential { AKGTMOAuth2AuthController *authController = [AKGTMOAuth2AuthController sharedController]; GTMOAuth2Authentication *auth = [authController newGTMOAuth2Authentication]; if (!auth) { return nil; } BOOL isAuthenticated = [GTMOAuth2ViewControllerTouch authorizeFromKeychainForName:authController.keychainItemName authentication:auth]; if (!isAuthenticated) { return nil; }

AKOAuth2AccountCredential *credential = [[AKOAuth2AccountCredential alloc] init]; credential.accessToken = auth.accessToken; return credential;}

GTMOAuth 2

91

+ (void)registerAccountTypeClass:(Class)accountTypeClass;

+ (instancetype)sharedStore;

- (AKAccount *)newAccount;

- (void)saveAccount:(AKAccount *)account;

- (AKAccount *)authenticatedAccount;

AKAccountStore : NSObject

92

Accounts, done.

Next pattern, #2

93

Auth Controller

2

94

Before looking at Auth Controller...

95

More OAuth2

Fun

96

The Actors

Client

Authorization Server

Resource Server

97

The Client

APP

98

Authorization Server99

Resource Server100

Before you can authenticate against an API’s OAuth you

have to ...

101

Register the Client102

Linked in103

And that gives you:

104

Client ID105

Client Secret106

That’s it. The Basics.

107

image by Damien Erambert

2Auth Controller

108

If you have auth...

109

You have a login...

110

If you have login,UIKit has to launch

a login flow.

111

Something has to be in control, no?

112

2 Protocols

113

- (void)beginAuthenticationAttempt;

- (void)unauthenticateAccount:(AKAccount *)account;

<AKAuthControl>

- (void)presentAKLoginViewController:(UIViewController *)viewController;

- (void)authControllerAccount:(AKAccount *)account didAuthenticate:(id<AKAuthControl>)authController;

- (void)authControllerAccount:(AKAccount *)account didUnauthenticate:(id<AKAuthControl>)authController;

<AKAuthHandler>

114

Now the star of the show,

AKAuthController

115

@property(nonatomic, weak) id<AKAuthHandler> authHandler;

+ (instancetype)sharedController;

AKAuthController : NSObject<AKAuthControl>

it’s abstract116

Simple

117

How does it work?

118

1

2

3

The Flows

Linkedin Auth Controller

Calling Linkedin API

119

The Flows120

id <AKAuthHandler> AKAuthController Login UIViewController

beginAuthenticationAttempt

initialize

presentAKLoginViewController:

user authenticated

authControllerAccount:didAuthenticate:

Login View Flow

121

Authenticated Flowid <AKAuthHandler> AKAuthController

beginAuthenticationAttempt

authControllerAccount:didAuthenticate:

122

Bounce Back Flowid <AKAuthHandler> AKAuthController Safari

beginAuthenticationAttempt

open URL

user authenticated

authControllerAccount:didAuthenticate:

App Delegate

open URL

123

So, the Linked in Auth Controller

124

But first...

125

Last OAuth 2 Lesson

126

The Grant

The Access Token (Part 2)

Two Steps

1

2

127

The Grant128

Yes, there IS another token.

129

Auth Code

Browser

The Request

The Redirect

130

Browser

131

The Request

132

Client Browser Auth Server

Auth Code Request URL

Auth Code GET Request

Redirect URL with Auth Code

Redirect URL with Auth Code

HTML Flow

133

Query String Params

https://www.linkedin.com/uas/oauth2/authorization

?response_type=code                                           &client_id=YOUR_API_KEY                                           &scope=SCOPE                                           &state=STATE                                           &redirect_uri=YOUR_REDIRECT_URI

134

The Redirect

135

Client Browser Auth Server

Auth Code Request URL

Auth Code GET Request

Redirect URL with Auth Code

Redirect URL with Auth Code

HTML Flow

136

And now, get the Auth Code...

137

It’s in the redirect URL query string.

YOUR_REDIRECT_URI/?code=AUTHORIZATION_CODE

138

So that’s the Auth Code Grant

139

Now, it’s time for some more Access

Token fun.

140

The Access Token141

Now that I have an Auth Code...

142

How do I get an Access Token?

143

Request

Response

144

Request

145

Client Auth Server

Access Token POST Request with Auth Code

JSON with Access Token

146

Query String Params

https://www.linkedin.com/uas/oauth2/accessToken

?grant_type=authorization_code                                           &code=AUTHORIZATION_CODE                                           &redirect_uri=YOUR_REDIRECT_URI                                           &client_id=YOUR_API_KEY                                           &client_secret=YOUR_SECRET_KEY

147

Response

148

Client Auth Server

Access Token POST Request with Auth Code

JSON with Access Token

149

Payload

{ "expires_in":5184000, "access_token":"AQXdSP_W41_UPs5ioT_t8HESyODB4FqbkJ8LrV_5mf f4gPODzOYR"}

150

So that’s how you get an Access Token

151

Back to... Linked in Auth Controller

152

Base

Auth Protocol

Library

AKAuthController

AKGTMOAuth2AuthController

MALinkedInAuthController

Subclass Structure

153

Using GTMOAuth2

154

Code Demo

155

We now have an Access token in the

Keychain

156

Time to make some API Calls

157

Calling the Linked in API

158

Getting Access Token from Account Store

Using the Access Token

Handling Bad Token Responses

1

23

159

Getting Access Token

1

160

Using Access Token

2

161

Client Resource Server

API Request with Access Token

Protected Resource

162

Code Demo

163

FINALLY! API Calls

164

Bad Token

3

165

Get Auth Controller

166

Client Resource Server

API Request with Access Token

Bad Token

AKAuthController

Unauthenticate Account

167

Log Out Account168

And... Wait How will the app react?

169

That’s where Auth UI comes in.

170

Auth UI

3

171

Container View Controller

172

Application Container View Controller

Unauthenticated View Controller

Authenticated View Controller

173

1

2

3

Children View Controllers

Installation

Flows

174

Children

175

Installation

176

Code Demo

177

Flows

178

Log In

179

Container Auth ControllerChild Controller

beginAuthenticationAttempt

beginAuthenticationAttempt

authControllerAccount:didAuthenticate:

transition into authenticated view controller

180

Log Out

181

Container Auth ControllerChild Controller

authControllerAccount:didUnauthenticate:

transition into unauthenticated view controller

182

That’s AuthUI

183

Whew! Those are the

Patterns

184

Back in SFO...

185

187

And the winner is...

188

189

190

10 years later...

191

192

John opens a hookah bar...

193

YES...a hookah bar

194

and

195

JUST MARRIED!

196

The End

197

So what’s the point?

198

Auth Sucks

199

Auth Takes Time

200

It gets in the way

201

TIMEDon’t spend

on auth

202

FeaturesSpend time on

203

Benefits

204

Save Time and

Effort

205

Consistent Interface

206

It’s simple

207

Future

208

Future of iOS

209

Future of CocoaAuth

&Auth Kit

210

Resources

211

/RCacheaux/AuthKit

212

214

top related