在 swift 中从 ios 访问 Sharepoint Web 服务时被禁止访问 403
getting 403 forbidden when access sharepoint web service from ios in swift
我是 ios 开发的新手,我正在尝试从 ios 访问 Sharepoint Web 服务,但我得到 403 forbidden
响应
我也参考过this link for authentication,但是没用
然后我尝试使用我从 this link
引用的 didReceiveAuthenticationChallenge
方法进行身份验证
根据 developer.apple.com 文档,此方法已弃用,我使用 willSendRequestForAuthenticationChallenge
方法
代码如下
var message:String = "<?xml version='1.0' encoding='utf-8'?><soap12:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap12='http://www.w3.org/2003/05/soap-envelope'><soap12:Body><GetList xmlns='http://schemas.microsoft.com/sharepoint/soap/'><listName>ThemeGallery</listName></GetList></soap12:Body></soap12:Envelope>"
var urlString = "https://domainname/_vti_bin/Lists.asmx"
var url = NSURL(string: urlString)
var req = NSMutableURLRequest(URL: url!)
var msglength = String(countElements(message))
req.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
req.addValue(msglength, forHTTPHeaderField: "Content-Length")
req.addValue("http://schemas.microsoft.com/sharepoint/soap/GetList", forHTTPHeaderField: "SOAPAction")
req.HTTPMethod = "POST"
req.HTTPBody = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
var connection = NSURLConnection(request: req, delegate: self, startImmediately: true)
connection?.start()
连接方法
func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge) {
if challenge.previousFailureCount == 0
{
var newCredential = NSURLCredential(user: self.username, password: self.password, persistence: NSURLCredentialPersistence.ForSession)
challenge.sender.useCredential(newCredential, forAuthenticationChallenge: challenge)
}
else
{
challenge.sender.cancelAuthenticationChallenge(challenge)
}
}
解析方法
func connectionDidFinishLoading(connection: NSURLConnection!) {
var xmlParser = NSXMLParser(data: self.mutableData)
xmlParser.delegate = self
xmlParser.parse()
xmlParser.shouldResolveExternalEntities = true
}
检查它是否可以从像 curl
这样的实用程序的命令行调用中工作,例如
curl -D- -u user:password http://....
如果您在那里看到 403,可能是 Sharepoint 不接受 HTTP 基本身份验证,您的代码将无法运行。
I have got solution for authentication to share point web service
I have use FedAuth
Cookie and rtFa
Cookie to pass credential
Fisrt I have load the sharepoint login page in UIWebView
When user successfully log in. We have to get those Cookies
by Below method
func verifyCookies()
{
var rtFa:NSHTTPCookie?
var fedAuth:NSHTTPCookie?
let storage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
let cookieArray = storage.cookies!
for tempCookie in cookieArray
{
if tempCookie.name == "rtFa"
{
rtFa = tempCookie as? NSHTTPCookie
continue
}
else if tempCookie.name == "FedAuth"
{
fedAuth = tempCookie as? NSHTTPCookie
continue
}
}
if rtFa != nil && fedAuth != nil
{
self.webView.hidden = true
self.cookieFound(rtFa!,fedAuthCookie: fedAuth!) // method mention below.
}
}
And after that I have use those cookie to pass credential to my request.
Below is my request code
func cookieFound(rtFaCookie:NSHTTPCookie,fedAuthCookie:NSHTTPCookie)
{
var message:String = "<?xml version='1.0' encoding='utf-8'?><soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body><GetListItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'><listName>demo</listName><viewName></viewName><query></query><viewFields></viewFields><rowLimit></rowLimit><QueryOptions></QueryOptions><webID></webID></GetListItems></soap:Body></soap:Envelope>"
var messageLength = String(countElements(message))
var url = NSURL(string: "https://domain/_vti_bin/Lists.asmx")
var therequest = NSMutableURLRequest(URL: url!)
therequest.addValue(messageLength, forHTTPHeaderField: "Content-Length")
therequest.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
therequest.addValue("http://schemas.microsoft.com/sharepoint/soap/GetListItems", forHTTPHeaderField: "SOAPAction")
// Authentication is passed in request header
var cookieArray = NSArray(objects: rtFaCookie,fedAuthCookie)
var cookieHeaders = NSHTTPCookie.requestHeaderFieldsWithCookies(cookieArray)
var requestHeaders = NSDictionary(dictionary: cookieHeaders)
therequest.allHTTPHeaderFields = requestHeaders
therequest.HTTPMethod = "POST"
therequest.HTTPBody = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
var connection = NSURLConnection(request: therequest, delegate: self, startImmediately: true)
connection?.start()
}
I have called verifyCookies()
method from below 'UIWebView delegate' methods
func webViewDidStartLoad(webView: UIWebView) {
self.verifyCookies()
}
func webViewDidFinishLoad(webView: UIWebView) {
self.verifyCookies()
}
Hope it will help someone
我是 ios 开发的新手,我正在尝试从 ios 访问 Sharepoint Web 服务,但我得到 403 forbidden
响应
我也参考过this link for authentication,但是没用
然后我尝试使用我从 this link
引用的didReceiveAuthenticationChallenge
方法进行身份验证
根据 developer.apple.com 文档,此方法已弃用,我使用 willSendRequestForAuthenticationChallenge
方法
代码如下
var message:String = "<?xml version='1.0' encoding='utf-8'?><soap12:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap12='http://www.w3.org/2003/05/soap-envelope'><soap12:Body><GetList xmlns='http://schemas.microsoft.com/sharepoint/soap/'><listName>ThemeGallery</listName></GetList></soap12:Body></soap12:Envelope>"
var urlString = "https://domainname/_vti_bin/Lists.asmx"
var url = NSURL(string: urlString)
var req = NSMutableURLRequest(URL: url!)
var msglength = String(countElements(message))
req.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
req.addValue(msglength, forHTTPHeaderField: "Content-Length")
req.addValue("http://schemas.microsoft.com/sharepoint/soap/GetList", forHTTPHeaderField: "SOAPAction")
req.HTTPMethod = "POST"
req.HTTPBody = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
var connection = NSURLConnection(request: req, delegate: self, startImmediately: true)
connection?.start()
连接方法
func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge) {
if challenge.previousFailureCount == 0
{
var newCredential = NSURLCredential(user: self.username, password: self.password, persistence: NSURLCredentialPersistence.ForSession)
challenge.sender.useCredential(newCredential, forAuthenticationChallenge: challenge)
}
else
{
challenge.sender.cancelAuthenticationChallenge(challenge)
}
}
解析方法
func connectionDidFinishLoading(connection: NSURLConnection!) {
var xmlParser = NSXMLParser(data: self.mutableData)
xmlParser.delegate = self
xmlParser.parse()
xmlParser.shouldResolveExternalEntities = true
}
检查它是否可以从像 curl
这样的实用程序的命令行调用中工作,例如
curl -D- -u user:password http://....
如果您在那里看到 403,可能是 Sharepoint 不接受 HTTP 基本身份验证,您的代码将无法运行。
I have got solution for authentication to share point web service
I have use
FedAuth
Cookie andrtFa
Cookie to pass credentialFisrt I have load the sharepoint login page in
UIWebView
When user successfully log in. We have to get those
Cookies
by Below method
func verifyCookies()
{
var rtFa:NSHTTPCookie?
var fedAuth:NSHTTPCookie?
let storage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
let cookieArray = storage.cookies!
for tempCookie in cookieArray
{
if tempCookie.name == "rtFa"
{
rtFa = tempCookie as? NSHTTPCookie
continue
}
else if tempCookie.name == "FedAuth"
{
fedAuth = tempCookie as? NSHTTPCookie
continue
}
}
if rtFa != nil && fedAuth != nil
{
self.webView.hidden = true
self.cookieFound(rtFa!,fedAuthCookie: fedAuth!) // method mention below.
}
}
And after that I have use those cookie to pass credential to my request.
Below is my request code
func cookieFound(rtFaCookie:NSHTTPCookie,fedAuthCookie:NSHTTPCookie)
{
var message:String = "<?xml version='1.0' encoding='utf-8'?><soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body><GetListItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'><listName>demo</listName><viewName></viewName><query></query><viewFields></viewFields><rowLimit></rowLimit><QueryOptions></QueryOptions><webID></webID></GetListItems></soap:Body></soap:Envelope>"
var messageLength = String(countElements(message))
var url = NSURL(string: "https://domain/_vti_bin/Lists.asmx")
var therequest = NSMutableURLRequest(URL: url!)
therequest.addValue(messageLength, forHTTPHeaderField: "Content-Length")
therequest.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
therequest.addValue("http://schemas.microsoft.com/sharepoint/soap/GetListItems", forHTTPHeaderField: "SOAPAction")
// Authentication is passed in request header
var cookieArray = NSArray(objects: rtFaCookie,fedAuthCookie)
var cookieHeaders = NSHTTPCookie.requestHeaderFieldsWithCookies(cookieArray)
var requestHeaders = NSDictionary(dictionary: cookieHeaders)
therequest.allHTTPHeaderFields = requestHeaders
therequest.HTTPMethod = "POST"
therequest.HTTPBody = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
var connection = NSURLConnection(request: therequest, delegate: self, startImmediately: true)
connection?.start()
}
I have called
verifyCookies()
method from below 'UIWebView delegate' methods
func webViewDidStartLoad(webView: UIWebView) {
self.verifyCookies()
}
func webViewDidFinishLoad(webView: UIWebView) {
self.verifyCookies()
}
Hope it will help someone