An iOS Authentication Architecture for All

1,656 views

Published on

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,656
On SlideShare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
24
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

An iOS Authentication Architecture for All

  1. 1. Get Ready 1
  2. 2. An iOS Authentication Architecture for All How to stop reinventing the auth wheel 2
  3. 3. René CacheauxSenior iOS Engineerrene.cacheaux@mutualmobile.com 3
  4. 4. There’s aPattern for That 4
  5. 5. WHAT’S THE BIG DEAL? 5
  6. 6. Spend TimeBuildingFeatures that ROCK 6
  7. 7. EngineerAmazingFirstImpressions 7
  8. 8. BuildReliable and Secure Apps 8
  9. 9. Meet John 9
  10. 10. 10
  11. 11. image by adamjackson1984 11
  12. 12. image by Cbeck527 12
  13. 13. 13
  14. 14. What to Build? 14
  15. 15. 15
  16. 16. Business Cards 16
  17. 17. Ready, Set... 17
  18. 18. 18
  19. 19. 19
  20. 20. but then... 20
  21. 21. 21
  22. 22. O...AUTH 22
  23. 23. Really!? 23
  24. 24. What exactly is OAuth? 24
  25. 25. WAIT!I have to use aUIWebView?! 25
  26. 26. Is there a library for this?? 26
  27. 27. YESGTMOAuth, whew. 27
  28. 28. JustDownload It! 28
  29. 29. But then... 29
  30. 30. Things start going wrong... 30
  31. 31. GTMOAuth 1 or 2? 31
  32. 32. Is Linked in OAuth 1 or 2? 32
  33. 33. BOTH? 33
  34. 34. One Hour Later 34
  35. 35. 35
  36. 36. Jen! 36
  37. 37. 37
  38. 38. Jen went toCocoaConf and... 38
  39. 39. Well...There’s a Pattern 39
  40. 40. CocoaAuth 40
  41. 41. AND there’s a reference implementation 41
  42. 42. Auth Kit 42
  43. 43. Three Patterns Three Steps 43
  44. 44. Three PattersThree Steps 1 2 3Accounts Auth Auth UI Controllers 44
  45. 45. But first... 45
  46. 46. John chose OAuth 2 for Linked in 46
  47. 47. Why? 47
  48. 48. John chose Google’s GTMOAuth 48
  49. 49. Why? 49
  50. 50. Back to:Three patterns Three steps 50
  51. 51. Three PattersThree Steps 1 2 3Accounts Auth Auth UI Controllers 51
  52. 52. So we want toimplement Accounts... 52
  53. 53. FirstAn Intro 53
  54. 54. Meet OAuth 2.0 OAuth 2 54
  55. 55. 1st thing... 55
  56. 56. image by tv The Access Token 56
  57. 57. It’s... 57
  58. 58. Opaque 58
  59. 59. It has... 59
  60. 60. Scopes 60
  61. 61. and it... 61
  62. 62. Expires 62
  63. 63. That’s OAuth 2 Access Token On to Step 1, Accounts 63
  64. 64. 1Accounts 64
  65. 65. If you need Authyou have user’s... 65
  66. 66. And if you haveusers, you need account management 66
  67. 67. Accounts makes up the model layer 67
  68. 68. 3 Entities in Accounts 68
  69. 69. 1 Credentials2 Accounts3 Store 69
  70. 70. 1 Credentials2 Accounts3 Store 70
  71. 71. AKOAuth2AccountCredential : NSObject@property(nonatomic, copy) NSString *accessToken;@property(nonatomic, strong) NSDate *expirationDate; 71
  72. 72. That’s all for credentials, super easy.Accounts is next. 72
  73. 73. 1 Credentials2 Accounts3 Store 73
  74. 74. AKAccount : NSObject@property(nonatomic, copy, readonly) NSString *identifier;@property(nonatomic, copy, readonly) NSString *username;@property(nonatomic, copy, readonly) NSString *accountType;- (void)clearCredential; 74
  75. 75. 1 Account Type2 Subclassing 75
  76. 76. Account Type“com.linkedin” 76
  77. 77. SubclassingAKAccount 77
  78. 78. Class Structure Base Auth Protocol Library 78
  79. 79. AKAccount Base@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 79
  80. 80. AKOAuth2Account@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 80
  81. 81. AKGTMOAuth2Account@implementation AKGTMOAuth2Account- (AKOAuth2AccountCredential *)OAuth2Credential { // Get credential from Googles GTMOAuth2 library.}- (void)clearCredential { // Remove credential from storage.}@end 81
  82. 82. AKAccount : NSObject@property(nonatomic, copy, readonly) NSString *identifier;@property(nonatomic, copy, readonly) NSString *username;@property(nonatomic, copy, readonly) NSString *accountType;- (void)clearCredential; 82
  83. 83. 1 Credentials2 Accounts3 Store 83
  84. 84. AKAccountStore : NSObject+ (void)registerAccountTypeClass:(Class)accountTypeClass;+ (instancetype)sharedStore;- (AKAccount *)newAccount;- (void)saveAccount:(AKAccount *)account;- (AKAccount *)authenticatedAccount; 84
  85. 85. Implementing1 Account Ref Store2 Credential Store 85
  86. 86. Implementing1 Account Ref Store2 Credential Store 86
  87. 87. Implementing1 Account Ref Store2 Credential Store 87
  88. 88. Credential Store 1 Keychain 2 Library Provided 88
  89. 89. 1 Keychain 89
  90. 90. 2 Library Provided Store 90
  91. 91. GTMOAuth 2- (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;} 91
  92. 92. AKAccountStore : NSObject+ (void)registerAccountTypeClass:(Class)accountTypeClass;+ (instancetype)sharedStore;- (AKAccount *)newAccount;- (void)saveAccount:(AKAccount *)account;- (AKAccount *)authenticatedAccount; 92
  93. 93. Accounts, done.Next pattern, #2 93
  94. 94. 2Auth Controller 94
  95. 95. Before looking atAuth Controller... 95
  96. 96. MoreOAuth2 Fun 96
  97. 97. The Actors Client Authorization Server Resource Server 97
  98. 98. The Client APP 98
  99. 99. Authorization Server 99
  100. 100. Resource Server 100
  101. 101. Before you canauthenticate against an API’s OAuth you have to ... 101
  102. 102. Register the Client 102
  103. 103. Linked in 103
  104. 104. And that gives you: 104
  105. 105. Client ID 105
  106. 106. Client Secret 106
  107. 107. That’s it. The Basics. 107
  108. 108. 2 Auth Controllerimage by Damien Erambert 108
  109. 109. If you have auth... 109
  110. 110. You have a login... 110
  111. 111. If you have login,UIKit has to launch a login flow. 111
  112. 112. Something has tobe in control, no? 112
  113. 113. 2 Protocols 113
  114. 114. <AKAuthControl>- (void)beginAuthenticationAttempt;- (void)unauthenticateAccount:(AKAccount *)account; <AKAuthHandler>- (void)presentAKLoginViewController:(UIViewController *)viewController;- (void)authControllerAccount:(AKAccount *)account didAuthenticate:(id<AKAuthControl>)authController;- (void)authControllerAccount:(AKAccount *)account didUnauthenticate:(id<AKAuthControl>)authController; 114
  115. 115. Now the star of the show,AKAuthController 115
  116. 116. AKAuthController : NSObject<AKAuthControl>@property(nonatomic, weak) id<AKAuthHandler> authHandler;+ (instancetype)sharedController; it’s abstract 116
  117. 117. Simple 117
  118. 118. How does it work? 118
  119. 119. 1 The Flows2 Linkedin Auth Controller3 Calling Linkedin API 119
  120. 120. The Flows 120
  121. 121. Login View Flowid <AKAuthHandler> AKAuthController Login UIViewController beginAuthenticationAttempt initialize presentAKLoginViewController: user authenticated authControllerAccount:didAuthenticate: 121
  122. 122. Authenticated Flow id <AKAuthHandler> AKAuthController beginAuthenticationAttempt authControllerAccount:didAuthenticate: 122
  123. 123. Bounce Back Flowid <AKAuthHandler> AKAuthController Safari App Delegate beginAuthenticationAttempt open URL open URL user authenticated authControllerAccount:didAuthenticate: 123
  124. 124. So, the Linked inAuth Controller 124
  125. 125. But first... 125
  126. 126. Last OAuth 2 Lesson 126
  127. 127. Two Steps1 The Grant2 The Access Token (Part 2) 127
  128. 128. The Grant 128
  129. 129. Yes, there ISanother token. 129
  130. 130. Auth Code Browser The Request The Redirect 130
  131. 131. Browser 131
  132. 132. The Request 132
  133. 133. Client Browser Auth Server Auth Code Request URL Auth Code GET Request HTML Flow Redirect URL with Auth Code Redirect URL with Auth Code 133
  134. 134. Query String Paramshttps://www.linkedin.com/uas/oauth2/authorization ?response_type=code                                           &client_id=YOUR_API_KEY                                           &scope=SCOPE                                           &state=STATE                                           &redirect_uri=YOUR_REDIRECT_URI 134
  135. 135. The Redirect 135
  136. 136. Client Browser Auth Server Auth Code Request URL Auth Code GET Request HTML Flow Redirect URL with Auth Code Redirect URL with Auth Code 136
  137. 137. And now, get the Auth Code... 137
  138. 138. It’s in the redirect URL query string.YOUR_REDIRECT_URI/?code=AUTHORIZATION_CODE 138
  139. 139. So that’s the Auth Code Grant 139
  140. 140. Now, it’s time forsome more Access Token fun. 140
  141. 141. The Access Token 141
  142. 142. Now that I have an Auth Code... 142
  143. 143. How do I get anAccess Token? 143
  144. 144. RequestResponse 144
  145. 145. Request 145
  146. 146. Client Auth Server Access Token POST Request with Auth Code JSON with Access Token 146
  147. 147. Query String Paramshttps://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
  148. 148. Response 148
  149. 149. Client Auth Server Access Token POST Request with Auth Code JSON with Access Token 149
  150. 150. Payload{ "expires_in":5184000, "access_token":"AQXdSP_W41_UPs5ioT_t8HESyODB4FqbkJ8LrV_5mf f4gPODzOYR"} 150
  151. 151. So that’s how youget an Access Token 151
  152. 152. Back to... Linked in Auth Controller 152
  153. 153. Subclass Structure AKAuthController Base AKGTMOAuth2AuthController Auth Protocol MALinkedInAuthController Library 153
  154. 154. Using GTMOAuth2 154
  155. 155. Code Demo 155
  156. 156. We now have anAccess token in the Keychain 156
  157. 157. Time to make some API Calls 157
  158. 158. Calling theLinked in API 158
  159. 159. 1 Getting Access Token from Account Store2 Using the Access Token3 Handling Bad Token Responses 159
  160. 160. 1 Getting Access Token 160
  161. 161. 2Using Access Token 161
  162. 162. Client Resource Server API Request with Access Token Protected Resource 162
  163. 163. Code Demo 163
  164. 164. FINALLY! API Calls 164
  165. 165. 3 Bad Token 165
  166. 166. Get Auth Controller 166
  167. 167. AKAuthController Client Resource Server API Request with Access Token Bad Token Unauthenticate Account 167
  168. 168. Log Out Account 168
  169. 169. And... Wait Howwill the app react? 169
  170. 170. That’s where Auth UI comes in. 170
  171. 171. 3Auth UI 171
  172. 172. Container View Controller 172
  173. 173. Application Container View ControllerUnauthenticated View Authenticated View Controller Controller 173
  174. 174. 1 Children View Controllers2 Installation3 Flows 174
  175. 175. Children 175
  176. 176. Installation 176
  177. 177. Code Demo 177
  178. 178. Flows 178
  179. 179. Log In 179
  180. 180. Child Controller Container Auth Controller beginAuthenticationAttempt beginAuthenticationAttempt authControllerAccount:didAuthenticate: transition into authenticated view controller 180
  181. 181. Log Out 181
  182. 182. Child Controller Container Auth Controller authControllerAccount:didUnauthenticate: transition into unauthenticated view controller 182
  183. 183. That’s AuthUI 183
  184. 184. Whew!Those are the Patterns 184
  185. 185. Back in SFO... 185
  186. 186. image by adamjackson1984 186
  187. 187. 187
  188. 188. And the winner is... 188
  189. 189. 189
  190. 190. 190
  191. 191. 10 years later... 191
  192. 192. 192
  193. 193. John opens ahookah bar... 193
  194. 194. YES...a hookah bar 194
  195. 195. and 195
  196. 196. JUSTMARRIED! 196
  197. 197. The End 197
  198. 198. So what’s the point? 198
  199. 199. Auth Sucks 199
  200. 200. Auth Takes Time 200
  201. 201. It gets in the way 201
  202. 202. Don’t spendTIME on auth 202
  203. 203. Spend time onFeatures 203
  204. 204. Benefits 204
  205. 205. Save Time and Effort 205
  206. 206. Consistent Interface 206
  207. 207. It’s simple 207
  208. 208. Future 208
  209. 209. Future of iOS 209
  210. 210. Future ofCocoaAuth & Auth Kit 210
  211. 211. Resources 211
  212. 212. /RCacheaux/AuthKit 212
  213. 213. René CacheauxSenior iOS Engineerrene.cacheaux@mutualmobile.com@RCachATXrene.cacheaux@gmail.com 213
  214. 214. 214

×