将 iPhone 应用程序与 Shibboleth 集成

2023-11-28

有人将 iPhone 应用程序与 Shibboleth 身份提供商集成吗?谷歌搜索没有得到任何结果,所以我直接询问大师。

如果以前没有这样做过,这样做是否可行?


两者的答案都是“是”。

我是一名 Java 人员,所以两周前被问到:

  • 学习 Objective-C
  • 编写一个原生 iPhone 应用程序
  • 使用 Shibboleth 以编程方式进行身份验证
  • 下载受 Shibboleth 保护的显示数据文件

……有点令人畏惧。更糟糕的是,由于没有任何论坛帖子可以提供帮助,促使我分享我的经验。

以下是概述,后面是一些希望非常有用的示例代码。如果有帮助的话请为我的回答投票!这值得我花几周的时间:)

对于 iPhone 上的应用程序来说,要下载 Shibbolized 资源,需要执行以下操作:

  1. 使用 Cocoa 中的 URL API 提交对相关资源的 HTTP 请求。
  2. 为请求实现委托类:
  3. 响应 SP 重定向至 IdP(Cocoa 自动提供)
  4. 响应服务器证书信任挑战
  5. 响应用户凭据挑战
  6. 响应错误(如果需要)
  7. 接收经过身份验证的用户的 IdP“绑定模板”,这是一个 HTML 表单,可使用两个参数将用户重定向回 SP
  8. 以编程方式将两个参数从 IdP HTTP POST 回 SP。
  9. Cookie 会自动存储并再次由 Cocoa 提供转发
  10. 实现第二个 URL 请求委托来接收原始请求数据。

以下是 Apple 和 Shibboleth 的一些有用参考:

  • http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html
  • https://spaces.internet2.edu/display/SHIB2/IdPSPLocalTestInstall

希望我可以包含所有源代码以进行快速演示。

ApplicationDelegate.h
----------
#import <UIKit/UIKit.h>
#import "ConsoleViewController.h"

/*
 The application delegate will hold references to the application's UIWindow and a ConsoleViewController.
 The console does all of the interesting Shibboleth activities.
*/
@interface ApplicationDelegate : NSObject <UIApplicationDelegate> {

 UIWindow *window;
 ConsoleViewController *consoleViewController;
}


@end

ApplicationDelegate.m
----------
#import "ApplicationDelegate.h"
#import "ConsoleViewController.h"

/*
 The implementation for the ApplicationDelegate initializes the console view controller and assembles everything.
 The console does all of the interesting Shibboleth activities.
 */
@implementation ApplicationDelegate


- (void)applicationDidFinishLaunching:(UIApplication *)application {    

 // Initialize the console.
 consoleViewController = [[ConsoleViewController alloc] init];

 window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
 [window setBackgroundColor:[UIColor lightGrayColor]];
 [window addSubview:[consoleViewController view]];

 [window makeKeyAndVisible];
}


- (void)dealloc {
    [window release];
 [ConsoleViewController release];
    [super dealloc];
}


@end

ConsoleController.h
----------
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

/*
 The ConsoleViewController's interface declares references to the network data used in negotiating with Shibboleth
 and a UITextView used to display the final result or errors.
 */
@interface ConsoleViewController : UIViewController {

 NSMutableData *responseData;
 NSString *responseString;
 UITextView *console;
}

@end

ConsoleController.m
----------
#import "ApplicationDelegate.h"
#import "ConsoleViewController.h"


/*
 This delegate is used when making the second HTTP request with Shibboleth.  If you're just getting here, start
 by reading the comments for ConsoleViewController below.

 All we need to do now is receive the response from the SP and display it.
 If all goes well, this should be the secured page originally requested.
 */
@interface AuthenticationRedirectDelegate : NSObject {

 NSMutableData *authResponseData;
 NSString *authResponseString;
 UITextView *console;
}

@property (nonatomic retain) UITextView *console;

@end


/*
 Refer to the comments for the interface above.
 */
@implementation AuthenticationRedirectDelegate

@synthesize console;

-(id)init {
 authResponseData = [[NSMutableData alloc] retain];
 return self;
}


- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
 [authResponseData setLength:0];
}


- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
 [authResponseData appendData:data];
}


- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
 [console setText:[error localizedDescription]]; 
}


/*
 Once the data is received from Shibboleth's SP, display it.
 */
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {  

 authResponseString = [[NSString alloc] initWithData:authResponseData encoding:NSUTF8StringEncoding]; 
 [console setText:authResponseString]; 
 [connection release];
}


@end


/*
 The implementation of the ConsoleViewController, and AuthenticationRedirectDelegate above, contain the real logic of
 this Shibboleth exercise.  The ConsoleViewController performs the following:
 1. Prepare the initial HTTP request to a Shibboleth protected resource.
 2. Act as the delegate whilst Cocoa's URL Loading API receives the HTTP Response.
 NOTE: We instruct Cocoa in advance to take care of the SP redirecting to the IdP, accepting the server certificate,
 and submitting the user credentials
 3. Once the HTTP Response is finished loading, parse the <form action, RelayState and SAMLResponse from the IdP's
 response
 4. Call a utility method to prepare a second HTTP POST Request to the <form action/SP with the IdP's parameters
 NOTE: We do not need to transfer over any of Shibboleth's cookies, since Cocoa is doing this automatically
 5. Use a new instance of AuthenticationRedirectDelegate to receive the POST's response, which should be the secured
 page originally requested.
 6. Display the final content in the UITextView known as console.
 */
@implementation ConsoleViewController


/*
 A handy utility method for extracting a substring marked by two provided token strings.
 Used in parsing the HTML form returned by the IdP after the first HTTP Request.
 */
+(id)substringFromString:(NSString *)source BetweenOpenToken:(NSString *)openToken AndCloseToken:(NSString *)closeToken {

 NSUInteger l = [source length];
 NSUInteger openTokenLen = [openToken length];

 NSUInteger openTokenLoc = ([source rangeOfString:openToken]).location;
 NSUInteger valueLoc = openTokenLoc + openTokenLen;
 NSRange searchRange = NSMakeRange(valueLoc, l - valueLoc);
 NSUInteger closeTokenLoc = ([source rangeOfString:closeToken options:NSCaseInsensitiveSearch range:searchRange]).location;
 searchRange = NSMakeRange(valueLoc, closeTokenLoc - valueLoc);
 NSString *result = [source substringWithRange:searchRange];

 return result;
}


/*
 This function takes the three properties returned by the IdP after the first HTTP request and 
 HTTP POSTs them to the SP as specified by the IdP in the "url" parameter.
 */
-(void)authReturnTo:(NSURL *)url WithRelay:(NSString *)relayState AndSAML:(NSString *)samlResponse {

 // Here we assemble the HTTP POST body as usual.
 NSString *preBody = [[NSString alloc] initWithString:@"RelayState="];
 preBody = [preBody stringByAppendingString:relayState];
 preBody = [preBody stringByAppendingString:@"&"];
 preBody = [preBody stringByAppendingString:@"SAMLResponse="];
 preBody = [preBody stringByAppendingString:samlResponse];

 /* The SAMLResponse parameter contains characters (+) that the SP expects to be URL encoded.
  Here we simply manually URL encode those characters.  You may wish to harden this with proper
  URL encoding for production use.
  */
 NSString *httpBody = [preBody stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"];
 NSData *httpBodyData = [httpBody dataUsingEncoding:NSUTF8StringEncoding];

 NSString *httpContentLength = [NSString stringWithFormat:@"%d", [httpBodyData length]];

 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
              cachePolicy:NSURLRequestReloadIgnoringCacheData
              timeoutInterval:12.0];
 [request setHTTPMethod:@"POST"];
 [request setValue:httpContentLength forHTTPHeaderField:@"Content-Length"];
 [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

 [request setHTTPBody:httpBodyData];

 // Submit the HTTP POST using the second delegate class to receive the response
 AuthenticationRedirectDelegate *delegate = [[AuthenticationRedirectDelegate alloc] init];
 delegate.console=console;
 [[NSURLConnection alloc] initWithRequest:request delegate:delegate];
}


/*
 When this UIViewController finishes loading, automatically prepare and send a request to the Shibboleth SP Web Server
 for a secured resource.
 */
- (void)viewDidLoad {
 [super viewDidLoad];

 console = [[UITextView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
 [[self view] addSubview:console];

 responseData = [[NSMutableData data] retain];

 // TODO: Enter your own URL for a Shibboleth secured resource.
 NSURL *url = [NSURL URLWithString:@"<URL>"];

 NSURLRequest *request = [NSURLRequest requestWithURL:url
       cachePolicy:NSURLRequestUseProtocolCachePolicy
       timeoutInterval:12.0];

 [[NSURLConnection alloc] initWithRequest:request delegate:self];

 /* Control flows to the delegate methods below */
}


/*
 Refer to Apple's docs on the URL Loading System for details.
 http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html
 */
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
  [responseData setLength:0];
}


/*
 Refer to Apple's docs on the URL Loading System for details.
 http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html
 */
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
 [responseData appendData:data];
}

/*
 This implementation in the delegate let's Cocoa trust my SP Web Server's self-signed certificate.
 TODO: You will want to harden this for production use.

 Refer to Apple's docs on the URL Loading System for details.
 http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html
 */
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
 return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust] || [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic];
}


/*
 This implementation for the delegate does two things:
 1. Respond to challenges for my server's self-signed certificate
 2. Respond to the IdP's challenge for the username and password.
 TODO: Enter your own username and password here.
 Refer to Apple's docs on the URL Loading System for details.
 http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html
 */
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
 // TODO: Enter the correct username and password below.
 /*
  WARNING: Using an incorrect user name and password will result in your application being re-challenged
  by the IdP.  Cocoa will return to this function in a never-ending loop.  This can result in the message
  "NSPosixErrorDomain Too many open files".  You'll need to perform additional coding to handle this.
  */
 if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
  [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
 else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic])
  [challenge.sender useCredential:[NSURLCredential credentialWithUser:@"<USERNAME>" password:@"<PASSWORD>" persistence:NSURLCredentialPersistenceNone] forAuthenticationChallenge:challenge];
 else
  [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}


/*
 You may wish to add more code here to log errors.

 Refer to Apple's docs on the URL Loading System for details.
 http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html
 */
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
 [console setText:[error localizedDescription]];
}


/*
 Once Cocoa has received a (hopefully) authenticated response from the IdP, we parse out the relevant pieces and prepare to
 HTTP POST them back to the SP as specified by the IdP in the <form action attribute.

 Refer to Apple's docs on the URL Loading System for details.
 http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html
 */
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {  
 [connection release];
 responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];

 if([responseString rangeOfString:@"SAMLResponse"].length < 1)
 {
  [console setText:[@"Unexpected response:\n]n" stringByAppendingString:responseString]];
  return;
 }

 NSString *relayState = [ConsoleViewController substringFromString:responseString BetweenOpenToken:@"RelayState\" value=\"" AndCloseToken:@"\"/>"];
 NSString *SAMLResponse = [ConsoleViewController substringFromString:responseString BetweenOpenToken:@"SAMLResponse\" value=\"" AndCloseToken:@"\"/>"];
 NSString *formAction = [ConsoleViewController substringFromString:responseString BetweenOpenToken:@"<form action=\"" AndCloseToken:@"\""];
 NSURL *formActionURL = [[NSURL alloc] initWithString:formAction];
 [self authReturnTo:formActionURL WithRelay:relayState AndSAML:SAMLResponse];
}


@end
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 iPhone 应用程序与 Shibboleth 集成 的相关文章

  • UIScrollView - 启用分页后,我可以“更改”页面宽度吗?

    将滚动视图 将 pagingEnabled 设置为 YES 将页面宽度设置为滚动视图边界以外的其他值的最简单方法是什么 让我举个例子 假设我有一个包含 10 个项目的滚动视图 每个项目的宽度为 150 像素 而我的滚动视图的宽度为 300
  • WhatsApp 显示警告“此项目无法共享。请选择其他项目。”对于 iOS 应用程序。

    我正在开发一个 iOS 应用程序 在该应用程序中 我有社交共享功能 并且社交共享功能使用深度链接来共享 URL 该网址共享对于所有应用程序都运行良好 除了WhatsApp 它会显示一个警报弹出窗口 此项目无法共享 请选择其他项目 以下是我的
  • 通过 AJP 将 REMOTE_USER 转发到 tomcat(例如用于 shibboleth)

    今天我刚刚遇到了以下问题 1 我将apache配置为基本身份验证 需要有效用户 这有效 2 我进一步配置 apache 将某些路径 在我的例子中为 idp 的请求转发到 tomcat servlet shibboleth IDP 结果是 s
  • UIWebView Bug:-[UIWebView cut:]:无法识别的选择器发送到实例

    In the UIWebView 如果包含文本的输入元素具有焦点 并且按下按钮导致输入失去焦点 则随后双击输入以重新获得焦点并从出现的弹出栏中选择 剪切 或 复制 或 粘贴 会导致这UIWebView因错误而崩溃 UIWebView cut
  • 核心数据 NSFetchRequest 还获取实体的子对象

    我是 iOS 开发和 Core Data 的新手 我有一个父 NSManagedObject class Units interface Properties NSManagedObject property nonatomic retai
  • 径向渐变绘制性能 - OpenGL-ES 可以改进吗?

    我正在开发一个图像处理应用程序 它将径向渐变叠加在从照片库加载的图像上 在屏幕上 我有一个滑块可以动态地增大 减小径向渐变的半径 我发现模拟器上的性能很好 但在 iPhone 3G 或 3GS 上就很糟糕了much移动滑块时重绘速度较慢 我
  • Objective-C中如何使继承的类能够看到父类的隐藏方法[重复]

    这个问题在这里已经有答案了 我有两个类 Class1 和 Class2 第二个类继承自第一个类 我需要重写 Class1 的 update 方法来实现我的目标 继承方法中 update方法的改变是在代码中间进行的 所以我不能使用 超级更新
  • iPhone 崩溃日志?

    我已经配置了一部 iPhone 并让用户安装了该应用程序 它失败 是否有崩溃日志可以让我看到 iPhone 上失败的原因 Ian 如果您可以使用 xcode 将 iPhone 连接到计算机 则在管理器窗口中它会显示每个应用程序崩溃的崩溃日志
  • 如何在 iOS 中注册自定义文件类型

    我目前正在创建一个应用程序 我想让用户在其中备份他们的文件 plist m4a 我压缩文件并将扩展名更改为自定义扩展名 专门针对我的应用程序 例如 MyBackup 然后 用户可以通过电子邮件或 iTunes 文件共享进行导出 我已经阅读过
  • 使用 Google place API 从 lat long 获取附近的地点

    我正在使用 google place API 即 https maps googleapis com maps api place search json location 33 7167 73 0667 radius 500 type f
  • 混合静态和动态 UITableViewController 内容会导致 NSRangeException

    我一直在寻找这个错误 并找到了一些具有类似行为的帖子 但没有解决问题的解决方案 我有一个 UITableViewController 在 SB 中声明为静态 它具有以下部分 第 0 部分 配方 是静态的 有 4 个单元格 第 1 部分 口味
  • iPhone Developer' 与任何有效的、未过期的证书/私钥对不匹配 - 但我正在创建 iPad 应用程序 [重复]

    这个问题在这里已经有答案了 可能的重复 代码签名错误 身份 iPhone Developer 与默认钥匙串中的任何有效证书 私钥对不匹配 https stackoverflow com questions 2108503 code sign
  • iPhone - 如何在矩形中间绘制文本

    有没有一种方法可以在矩形中间绘制文本 我可以找到各种对齐方式 但我尝试过的任何方法都不能将文本垂直居中在矩形中 有没有一种简单的方法可以做到这一点 或者有什么方法可以将矩形居中然后在其中绘制 我直接绘制到 CGContext 尝试使用 NS
  • 将 iPhone 上的 stderr 写入文件和控制台

    我正在遵循答案中的建议here https stackoverflow com questions 5179108 iphone how to read application logs from device用于将 iOS 设备上的 NS
  • iPhone,如何隐藏标签栏按钮?

    如何隐藏单个标签栏按钮 我已经搜索过 但什么也没找到 只找到了完整的栏 我已经取得了一些进展 但仍然遇到问题 此代码位于我的应用程序委托中 带有选项卡栏的出口 我在其中调用它viewDidLoad选项卡栏中显示的第一个视图的视图 void
  • 如何从通讯录 ios 以编程方式编辑电话号码值

    我正在尝试在 iOS 中以编程方式替换特定联系人的特定电话号码 获取联系人表单地址簿 我不知道为什么我无法保存新的电话号码并刷新地址簿以显示更改 我正在这样做 BOOL changeContactPhoneNumber NSString p
  • 如何将设备令牌和应用程序版本发送到服务器

    我已经实现将设备令牌和应用程序版本发送到 serverm 它在模拟器 硬编码数据 中工作正常 但在设备中无法工作 任何形式的帮助将不胜感激 先感谢您 这是代码 void application UIApplication applicati
  • iPhone UI 带有 Tableview 或 Scrollview? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 在 iPhone 中保存会话数据

    我想将数据存储在应用程序中的不同点 以便应用程序中的对象可以访问这些数据 类似于 php 中的 session 或全局变量 我知道我可以使用 NSUserDefaults 但我不确定如何继续向它添加值然后访问它 例如 首先我想存储登录期间使
  • Apple 允许后台任务运行多长时间?

    我必须将一系列图像文件上传到数据库 因此 我偶然发现苹果后台执行指南 https developer apple com library ios documentation iPhone Conceptual iPhoneOSProgram

随机推荐