无法通过HTTP基本身份验证工作

时间:2014-08-18 20:19:36

标签: ios swift nsurlcredential

我正在尝试使用HTTP Basic Auth调用本地Rest Service。

根据我的要求,我得到以下信息:

发现:错误 - 未经授权的 找到:原因 - 需要密码

这是我正在执行请求的函数。

func connect(url: String) -> Bool {

    let url: NSURL = NSURL(string: url);
    let login:String = "admin";
    let password:String = "test123";

    var defaultCredentials: NSURLCredential = NSURLCredential(user: login, password: password, persistence: NSURLCredentialPersistence.ForSession);

    let host: String = url.host;
    let port: Int = url.port;
    let prot: String = url.scheme;

    println("set following vars \(host) + \(port) + \(prot)");

    var protectionSpace: NSURLProtectionSpace = NSURLProtectionSpace(host: host,port: port,`protocol`: prot,realm: nil,authenticationMethod: NSURLAuthenticationMethodHTTPBasic);

    var credentialStorage: NSURLCredentialStorage = NSURLCredentialStorage.sharedCredentialStorage();
    credentialStorage.setCredential(defaultCredentials, forProtectionSpace: protectionSpace);

    var sessionConfiguration: NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration();
    sessionConfiguration.URLCredentialStorage = credentialStorage;

    let session: NSURLSession = NSURLSession(configuration: sessionConfiguration); //NSURLSession.sharedSession()


    //NSURLSession.sessionWithConfiguration(sessionConfiguration);

    let task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in
        println("Task completed")
        if((error) != nil) {
            // If there is an error in the web request, print it to the console
            println(error.localizedDescription)
        }
        var err: NSError?
        var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
        if(err != nil) {
            // If there is an error parsing JSON, print it to the console
            println("JSON Error \(err!.localizedDescription)")
        }


        self.delegate.didReceiveAPIResults(jsonResult);

    })
    task.resume()

    return true
}

有人可以给我一个提示吗?

4 个答案:

答案 0 :(得分:1)

我会考虑使用AFNetworking。我尝试使用AlamoFire但遇到了Basic Auth(more info on that here)的问题。这就是我以前在Swift中做的Basic Auth。

    static let sharedInstance = NetworkManager(url: NSURL(string: baseUrl))
    ...
    sharedInstance.requestSerializer.clearAuthorizationHeader()
    sharedInstance.requestSerializer.setAuthorizationHeaderFieldWithUsername(email, password:password)
    sharedInstance.POST(loginAPI,
        parameters: nil,
        success: success,
        failure: failure)

请注意,成功和失败是关闭(如果你来自Objective C,就像块一样)我将传递给我的方法。

如果你还没有将Objective C库导入Swift,我建议你像往常一样使用cocoapods。然后只需将此行添加到Bridging-Header.h文件中。

#import <AFNetworking/AFNetworking.h>

答案 1 :(得分:0)

这是最基本的方式(从这里:https://stackoverflow.com/a/24380884),但有效:

// set up the base64-encoded credentials
let username = "user"
let password = "pass"
let loginString = NSString(format: "%@:%@", username, password)
let loginData: NSData = loginString.dataUsingEncoding(NSUTF8StringEncoding)
let base64LoginString = loginData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.fromMask(0))

// create the request
let url = NSURL(string: "http://www.example.com/")
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")

// fire off the request
// make sure your class conforms to NSURLConnectionDelegate
let urlConnection = NSURLConnection(request: request, delegate: self)

如果您收到身份验证质询,则更好的方法在此解释:

https://stackoverflow.com/a/24975120

答案 2 :(得分:0)

SWIFT 2.0 +

        let username = "USER_NAME"
        let password = "PASSWORD"
        let credentialData = "\(username):\(password)".dataUsingEncoding(NSUTF8StringEncoding)!
        let base64Credentials = credentialData.base64EncodedStringWithOptions([])
        let headers = ["Authorization": "Basic \(base64Credentials)"]


//        let manager = Alamofire.Manager.sharedInstance

        Alamofire.Manager.sharedInstance.session.configuration.timeoutIntervalForRequest = 300

        Alamofire.Manager.sharedInstance.upload(.POST,url,headers : headers,multipartFormData: { multipartFormData in
            NSLog("url----- %@ \n perameter --- %@",url, dicsParams)
            for (key, value) in dicsParams {
            },
            encodingCompletion: { encodingResult in
                switch encodingResult {
                case .Success(let upload, _, _):
                    upload.responseJSON { response in
                        debugPrint(response)
                        AppHelper.hideLoadingSpinner()
                        if response.result.value is NSNull
                        {
                        }
                        else
                        {
                            if let JSON = response.result.value {
                                var mydict = NSMutableDictionary()
                                mydict = JSON as! NSMutableDictionary

                                if (self.delegate != nil){
                                    print("response:--------------------\n %@",mydict)

                                }
                            }
                            else
                            {
                                print("response not converted to JSON")
                            }

                        }
                    }
                case .Failure(let encodingError):
                    print(encodingError)
                    if (self.delegate != nil){
                        self.delegate.HttpWrapperfetchDataFail!(self, error: encodingError as NSError);
                    }
                }
            }
        )

答案 3 :(得分:0)

我正在使用Alamofire 3及更高版本。将标头传递给Webservice。我将标题放在“标题:”参数

中,如下所示
Alamofire.request(
            .POST,
            "https://mysuperurl.com/path",
            parameters:nil,
            encoding: .URL,
            headers:["Authorization": "Basic " + base64String!])
            .validate()
            .responseJSON { response in
                switch response.result {
                case .Success: 
                    print("Validation Successful")
                case .Failure(let error):
                    print(error)
                }
        }