How to authenticate using sendSynchronous request in NSURLConnection - asynchronous

Can any one tell me how to send a authentication request using the NSURLConnection.I tried out the following code snippet by following the link stackoverflow question but still its not working.
I want to authenticate using synchronous request and authentication is asked twice
1.Over a proxy: proxy.net
2.Main site :main.mainsite.com (same code not listed here)
I have used the following code to do the same-
NSURLCredential *credential = [NSURLCredential credentialWithUser:#"user.me"
password:#"Passme#4me"
persistence:NSURLCredentialPersistenceForSession];
NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc]
initWithHost:#"proxy.net"
port:0
protocol:#"http"
realm:nil
authenticationMethod:NSURLAuthenticationMethodDefault];
[[NSURLCredentialStorage sharedCredentialStorage] setCredential:credential
forProtectionSpace:protectionSpace];
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://main.mainsite.com/" cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:30.0];
NSData* returnData=[[NSURLConnection sendSynchronousRequest:theRequest returningResponse:&response error:&err];
But the proxy is blocking the request even though the credentials are correct.Can anyone give me a way to authenticate using the method
[NSURLConnection sendSynchronousRequest:theRequest returningResponse:&response error:&err];

what about trying with 2 distinct protection spaces... one for "proxy.net" and the other for "mainsite.com"... ?

Related

ADFS 2016 On behalf of flow : cannot get any user informations

I'm trying to implement the "on behalf of" flow in an application using ADFS 2016 as STS. As a reference, I look at this Microsoft tutorial (https://learn.microsoft.com/en-ca/windows-server/identity/ad-fs/development/ad-fs-on-behalf-of-authentication-in-windows-server). It's working as it should, I can login into my web application and then use my original access token in UserAssertion to generate a new access token with the proper audience to call my API BUT I found absolutely no way to include any user informations (sub, name, email, upn etc.) into the access token for my API, even if I set claim rules into my ADFS configurations for the API.
I checked the communication between my app and adfs using Fiddler and everything looks like the informations in the tutorial. See the screen shot of the "on behalf of" request below :
Here's the resulting access token :
Finally, here's the code I use to generate my new access token :
private async Task<string> GetAccessToken(ClaimsPrincipal user, string originalAccessToken)
{
var authority = "[authority]";
var context = new AuthenticationContext(authority, false);
string userName = user.FindFirstValue("upn");
var userAssertion = new UserAssertion(originalAccessToken, "urn:ietf:params:oauth:grant-type:jwt-bearer",userName);
var cc = new ClientCredential("https://localhost:44387/", "[client_secret]");
var result = await context.AcquireTokenAsync("https://localhost:44339/", cc, userAssertion);
return result.AccessToken;
}
Have you struggle with that scenario and if yes, did you find a way to fix this ?
Thanks
I've only used the Microsoft On Behalf Of flow with Azure AD and not ADFS, but it looks like you need to send a more detailed scope in your User Info request.
Maybe try sending 'openid profile email', to indicate that you want that type of detail, as in Section 17 of my blog post. Of course this assumes that this type of data has been registered for all users.
TROUBLESHOOTING
Looks like one of these will be the cause:
A suboptimal Microsoft library that does not allow you to send the required scope
Or ADFS 2016 perhaps lacks the scope features that work correctly in Azure AD
I would concentrate on making extra sure you are sending the correct form URL encoded request message, using a tool such as curl, Postman or a plain C# HttpClient. Here is the code I used to send the correct scope - using an open source library rather than a Microsoft one:
Sample NodeJS Code
If you can get the scope sent correctly then you should have a resolution either way:
Either you get the correct data and can update your code
Or the behaviour you want is not supported by ADFS
Good luck ...

BizTalk 2016: How to use HTTP Send adapter with API token

I need to make calls to a rest API service via BizTalk Send adapter. The API simply uses a token in the header for authentication/authorization. I have tested this in a C# console app using httpclient and it works fine:
string apiUrl = "https://api.site.com/endpoint/<method>?";
string dateFormat = "dateFormat = 2017-05-01T00:00:00";
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("token", "<token>");
client.DefaultRequestHeaders.Add("Accept", "application/json");
string finalurl = apiUrl + dateFormat;
HttpResponseMessage resp = await client.GetAsync(finalurl);
if (resp.IsSuccessStatusCode)
{
string result = await resp.Content.ReadAsStringAsync();
var rootresult = JsonConvert.DeserializeObject<jobList>(result);
return rootresult;
}
else
{
return null;
}
}
however I want to use BizTalk to make the call and handle the response.
I have tried using the wcf-http adapter, selecting 'Transport' for security (it is an https site so security is required(?)) with no credential type specified and placed the header with the token in the 'messages' tab of the adapter configuration. This fails though with the exception: System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
I have tried googling for this specific scenario and cannot find a solution. I did find this article with suggestions for OAUth handling but I'm surprised that even with BizTalk 2016 I still have to create a custom assembly for something so simple.
Does anyone know how this might be done in the wcf-http send adapter?
Yes, you have to write a custom Endpoint Behaviour and add it to the send port. In fact with the WCF-WebHttp adapter even Basic Auth doesn't work so I'm currently writing an Endpoint Behaviour to address this.
One of the issues with OAuth, is that there isn't one standard that everyone follows, so far I've had to write 2 different OAuth behaviours as they have implemented things differently. One using a secret and time stamp hashed to has to get a token, and the other using Basic Auth to get a token. Also one of them you could get multiple tokens using the same creds, whereas the other would expire the old token straight away.
Another thing I've had to write a custom behaviour for is which version of TLS the end points expects as by default BizTalk 2013 R2 tries TLS 1.0, and then will fail if the web site does not allow it.
You can feedback to Microsoft that you wish to have this feature by voting on Add support for OAuth 2.0 / OpenID Connect authentication
Maybe someone will open source their solution. See Announcement: BizTalk Server embrace open source!
Figured it out. I should have used the 'Certificate' for client credential type.
I just had to:
Add token in the Outbound HTTP Headers box in the Messages tab and select 'Transport' security and 'Certificate' for Transport client credential type.
Downloaded the certificate from the API's website via the browser (manually) and installed it on the local servers certificate store.
I then selected that certificate and thumbprint in the corresponding fields in the adapter via the 'browse' buttons (had to scroll through the available certificates and select the API/website certificate I was trying to connect to).
I discovered this on accident when I had Fiddler running and set the adapter proxy setting to the local Fiddler address (http://localhost:8888). I realized that since Fiddler negotiates the TLS connection/certificate (I enabled tls1.2 in fiddler) to the remote server, messages were able to get through but not directly between the adapter and the remote API server (when Fiddler WASN'T running).

URLRequestDefaults.setLoginCredentialsForHost not setting the user & pwd in authorization header

I want to access html files which are protected by basic authentication.
I am trying to load this html page using htmlloader and sending the request by urlRequest.
I am using URLRequestDefaults class to set the credentials but when I see the request being send in the fiddler I don't see any authorization header being set by this.
Am I doing something wrong here. My code is below.
URLRequestDefaults.authenticate = false;
URLRequestDefaults.setLoginCredentialsForHost("www.xyz.com", "madhur", "sharma");
var req:URLRequest = new URLRequest("http://bazinga.xyz.com/MyHtml/index.html");
htmlControl.htmlLoader.load(urlRequest);
You should read the API more carefully:
Note that "example.com", "www.example.com", and "sales.example.com" are each considered unique hosts.
In this case, the domains don't match.

PL/SQL OpenID+OAuth Implementation - 400 - Bad Request

I am trying to implement (OpenId+OAuth) hybrid protocol using PL/SQL.
I have setup OpenID Authentication successfully with google for my site http://example.com where the user is directed to google accounts for authentication. After successful authentication, the user is redirected back to example.com with OAuthRequestToken attached.
I am then trying to exchange this token with OAuthAccessToken to access various google sevices.
The OAutheRequestToken that I get after hybrid(OpenID+OAuth) authentication is as follows:
oauth_token = 4/AR17dDMb4xHG3L4WFYLIzkhCj0c7
The oauth_base_string I get is as follows:
oauth_base_string = GET&https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetAccessToken&oauth_consumer_key%3Dexample.com%26oauth_nonce%3D56575A5754587057576E6C77576B78695757354F%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1308046070%26oauth_version%3D1.0%26oauth_token%3D4%2FAR17dDMb4xHG3L4WFYLIzkhCj0c7
I then place a request to exchange this oauth_token(OAuthRequestToken) with OAuthAccessToken in the query string itself as :
https://www.google.com/accounts/OAuthGetAccessToken?oauth_consumer_key=example.com&oauth_token=4/AR17dDMb4xHG3L4WFYLIzkhCj0c7&oauth_signature_method=HMAC-SHA1&oauth_signature=RpqSLGp5nIGvL8W4vmC8inUfBFQ%3D&oauth_timestamp=1308046070&oauth_nonce=56575A5754587057576E6C77576B78695757354F&oauth_version=1.0
This results in 400 - Bad Request.
I have tried searching for something similar but still no luck.
This Post from Stack Overflow deals with a similar issue. It says
...% escaping can be an issue
which is a bit confusing.
Do we have to urlencode oauth_signature param twice in the request?
I am using the following code to generate oauth_signature:
oauth_sig_mac := DBMS_CRYPTO.mac (UTL_I18N.string_to_raw
(oauth_base_string,
'AL32UTF8'),DBMS_CRYPTO.hmac_sh1,
UTL_I18N.string_to_raw (oauth_key,
'AL32UTF8'));
oauth_signature := UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode
(oauth_sig_mac));
Here:
oauth_key := urlencode('oauth-consumer-secret-key') || '&';
Any help is greatly appreciated.
I recommend using https://runscope.com to test your api. Its great.
I make my calls to the Zero api using oauth 1.0, so I'm not sure if its just the endpoint that's different but a couple things you could check are:
Encoding the oauth token you recieve from the previous request so that, that '/' is ASCII encoded.
And, test your api through runscope to check your timestamp if its to old or to new this will throw a bad request.
P.s a bad request is a better error than the 401 anauthorised so your almost there

Webservice.wsdl and credentials

So I've got a bit of an issue I'm trying to work through. Perhaps some Flex guru could assist?
I have a WebService instance that attempts to load a WSDL file from our JBoss Application Server. If I do something like this:
webService = new WebService();
webService.destination = WebService.DEFAULT_DESTINATION_HTTP;
webService.wsdl = "http://<removed>/services/ApiService?wsdl";
webService.loadWSDL();
everything works fine. The WSDL is loaded successfully and the application can invoke methods against the web service.
The issue is when I need to add some HTTP authentication to the mix:
webService.setCredentials(userName, password);
this line ends up throwing an error stating that credentials are only supported on HTTPS. Ok fair enough, I want to use secure HTTPS anyway!
So then I tried to change it up to this...
webService = new WebService();
webService.destination = WebService.DEFAULT_DESTINATION_HTTPS;
webService.wsdl = "https://<removed>/services/ApiService?wsdl";
webService.setCredentials(userName, password);
webService.loadWSDL();
and now the WebService instance cannot load the WSDL. The error received is:
[FaultEvent fault=[RPC Fault faultString="HTTP request error" faultCode="Server.Error.Request" faultDetail="Unable to load WSDL. If currently online, please verify the URI and/or format of the WSDL (https://<removed>/services/ApiService?wsdl)"] messageId="6905CC5B-5317-C4B3-2D12-84647EE648A7" type="fault" bubbles=false cancelable=true eventPhase=2]
I can reach this URI in the browser just fine and it returns the WSDL as expected.
I am not a Flex guy (learning) but instead a Java developer. I am trying out Flex as a potential client to our system but this has caused me all kinds of grief today. Google doesn't appear to have any quick answers for me and I am a bit stumped.
First question on StackOverflow so hopefully this gets a bite somewhere and helps some other poor Java dev staying late in the office on a Friday night :-)
This seems to be related to your question. We are planning to use https in the future, so I'm curious to know the solution of your problem.

Resources