通过AppAuth iOS理解Google OIDC服务
来源:互联网 发布:php都开发过什么软件 编辑:程序博客网 时间:2024/06/03 21:58
转载于:http://www.jianshu.com/p/00ae475fb041
通过AppAuth-iOS体验Google OIDC服务非常容易,只需要配置下面三个配置项。
static NSString *const kIssuer = @"https://accounts.google.com";static NSString *const kClientID = @"24408797720-p6d3uj34k564kl4s85o2d1rdgvlp7nef.apps.googleusercontent.com";static NSString *const kRedirectURI = @"com.googleusercontent.apps.24408797720-p6d3uj34k564kl4s85o2d1rdgvlp7nef:/oauth2redirect/";
通过https://accounts.google.com/.well-known/openid-configuration可以获取到Google Auth所有的相关信息,非常丰富的信息。这个配置文件的详细介绍可以参考:OpenID Connect Discovery 1.0 incorporating errata set 1。
从配置信息可以看出Google把auth和login放在accounts.google.com
域下面,token单独放在www.googleapis.com
域下面。
接下来看看如何发起授权。构造OIDAuthorizationRequest请求之后,使用In-App browser(iOS使用SFSafariViewController)打开相应的URL。
// builds authentication requestOIDAuthorizationRequest *request = [[OIDAuthorizationRequest alloc] initWithConfiguration:configuration clientId:clientID clientSecret:clientSecret scopes:@[ OIDScopeOpenID, OIDScopeProfile ] redirectURL:redirectURI responseType:OIDResponseTypeCode additionalParameters:nil];// performs authentication requestAppDelegate *appDelegate = (AppDelegate *) [UIApplication sharedApplication].delegate;[self logMessage:@"Initiating authorization request %@", request];appDelegate.currentAuthorizationFlow = [OIDAuthorizationService presentAuthorizationRequest:request presentingViewController:self callback:^(OIDAuthorizationResponse *_Nullable authorizationResponse, NSError *_Nullable error) { if (authorizationResponse) { OIDAuthState *authState = [[OIDAuthState alloc] initWithAuthorizationResponse:authorizationResponse]; [self setAuthState:authState]; [self logMessage:@"Authorization response with code: %@", authorizationResponse.authorizationCode]; // could just call [self tokenExchange:nil] directly, but will let the user initiate it. } else { [self logMessage:@"Authorization error: %@", [error localizedDescription]]; } }];- (SFSafariViewController *)safariViewControllerWithURL:(NSURL *)URL { SFSafariViewController *safariViewController = [[SFSafariViewController alloc] initWithURL:URL entersReaderIfAvailable:NO]; return safariViewController;}
本来我还想将SFSafariViewController改成UIWebView,以观察所有URL的流转关系。结果没法使用UIWebView,Google发现是UIWebView会直接报错。
Google Auth返回的id_token已经包含了用户信息,但是还是提供一个单独的userinfo_endpoint去换取用户信息。
手动authorize流程如下所示。
11:09:02: Fetching configuration for issuer: https://accounts.google.com11:09:02: Got configuration: OIDServiceConfiguration authorizationEndpoint: https://accounts.google.com/o/oauth2/v2/auth, tokenEndpoint: https://www.googleapis.com/oauth2/v4/token, registrationEndpoint: (null), discoveryDocument: [<OIDServiceDiscovery: 0x608000012970>]11:09:02: Initiating authorization request <OIDAuthorizationRequest: 0x6000000ac180, request: //第一步,获取auth code,参数都在URL里面。https://accounts.google.com/o/oauth2/v2/auth?response_type=code&code_challenge_method=S256&scope=openid%20profile&code_challenge=zkJhG3SZa9vHx8P8TvikiEozUDNQwlJXnlskEe0wJGA&redirect_uri=com.googleusercontent.apps.24408797720-p6d3uj34k564kl4s85o2d1rdgvlp7nef:/oauth2redirect/&client_id=24408797720-p6d3uj34k564kl4s85o2d1rdgvlp7nef.apps.googleusercontent.com&state=KX_4c-UQCxrshPrtHD75CLPoj80gipzxTr1r2hGNhus>//拿到auth code11:09:51: Authorization response with code: 4/SS-PVx_JADts0XLrN4VDQiK5QUOTd0qvKtYO_UZJO2E//第二步,获取access token和refresh token,参数都通过post发出去。//Google Auth比较有特色的一点是没有client_secret11:09:52: Performing authorization code exchange with request [<OIDTokenRequest: 0x6080000ac360, request: <URL: https://www.googleapis.com/oauth2/v4/token, HTTPBody: code=4/SS-PVx_JADts0XLrN4VDQiK5QUOTd0qvKtYO_UZJO2E&code_verifier=9zUuBzJkfD4y8Ei-424Cx-lWIwObhnSbC5_dOGZXSCk&redirect_uri=com.googleusercontent.apps.24408797720-p6d3uj34k564kl4s85o2d1rdgvlp7nef:/oauth2redirect/&client_id=24408797720-p6d3uj34k564kl4s85o2d1rdgvlp7nef.apps.googleusercontent.com&grant_type=authorization_code>>]11:09:53: Received token response with accessToken: ya29.GltBBBYWx0rhh87WWK1oV0peHCI9_EwwoWWf4lUiwBc_--bTXv_Ag6OWdBU6SAHhYx5O6RdOsX1HMCPcELfeIlw-5rESYDuGmyRTqAuchGbHl1Ws-hC10O80YAmi
上面的参数中,code_challenge_method
、code_challenge
、code_verifier
这三个看起来很神秘。它们是为了避免auth code被拦截而做了保护措施。第一步通过code_challenge_method
给code_verifier
做一次计算得到code_challenge
。Authorization Endpoint会保存code_challenge
相关的信息。第二步直接把code_verifier
传递给token endpoint,服务器端做一次对比。如果对不上,就报错。详细信息请参看:Proof Key for Code Exchange by OAuth Public Clients。
继续往下分析一下state这个参数的作用吧。state参数是为了防止CSRF攻击,详细信息请参看:OAuth2:忽略 state 参数引发的 csrf 漏洞 #68。In-App browser回跳到App时,要检查一下URL里面的state是否跟之前的state一致。
OpenID Connect标准集里面包含一个Dynamic Client Registration
的标准,用于动态注册客户端,不过我目前还没有看到哪个OIDC服务器的Discovery里面有registration_endpoint
,包括Google OIDC服务器。
AppAuth客户端是支持这个特性的,很多地方都会判断是否配置了client_id。如果没有配置的话,那么通过Dynamic Client Registration
注册一个客户端。
if (!kClientID) { [self doClientRegistration:configuration callback:^(OIDServiceConfiguration *configuration, OIDRegistrationResponse *registrationResponse) { [self doAuthWithAutoCodeExchange:configuration clientID:registrationResponse.clientID clientSecret:registrationResponse.clientSecret]; }];} else { [self doAuthWithAutoCodeExchange:configuration clientID:kClientID clientSecret:nil];}}];
- 通过AppAuth iOS理解Google OIDC服务
- 通过编程访问Google账户和服务
- 通过hosts设置访问Google服务
- iOS 通过UIActivityViewController实现更多分享服务
- 谷歌关闭Google.cn 通过香港网站提供服务
- Google发布了能理解人类语言的云服务
- google服务
- google服务
- ios通过google map显示地图和乘车信息
- ios通过google map显示地图和乘车信息
- 通过实现一个TableView来理解iOS UI编程
- 通过实现一个TableView来理解iOS UI编程
- 通过实现一个 TableView 来理解 iOS UI 编程
- 通过实现一个TableView来理解iOS UI编程
- 通过实现一个 TableView 来理解 iOS UI 编程
- 通过实现一个TableView来理解iOS UI编程
- 通过实现一个TableView来理解iOS UI编程
- 关于通过PHPMailer 用Google企业邮箱 提供邮件服务 资料转载
- C# List根据某一字段排序 将字段相同的排序到一起
- ios在同一个控制器中 动态显示和隐藏状态栏
- 面试题 11:数值的整数次方
- “玲珑杯”线上赛 Round #15 河南专场 D -- 咸鱼商店
- Navicat 无法连接到 mysql 解决办法
- 通过AppAuth iOS理解Google OIDC服务
- 链表头使用指针的问题
- 解决could not create leading directories of '/usr/local/Homebrew/Library/Taps/caskroom/homebrew-cask':
- Xcode连线Touch触发事件
- Python 日期与时间
- 第三章 tensorflow入门
- Java函数式编程笔记(一)—— Lambda表达式
- Go flag包示例
- 关于SSM的配置文件和Web.xml的配置