We are using IIS 7.5 with only windows authentication enabled. providers are ntlm and negogiate ( since we want it to be accessible via internet).
The client is silverlight calling wcf services. even though we have session established the client sends the negotiate and server return 401 with some authentication token. this happends intermettinetly , with many sucessful calls ( intermingled with failed calls)
Many calls work fine and just send sessionid and everthing works fine.
In fiddler we see below
Client sends
Authorization: Negotiate TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw==
ASP.NET_SessionId=0ix0fqf02j1imrpfc4awit3w
Server sends
WWW-Authenticate: Negotiate TlRMTVNTUAACAAAACgAKADgAAAAVgonitqRU/FVLp9EAAAAAAAAAAI4AjgBCAAAABgGxHQAAAA9BAEQATABBAEIAAgAKAEEARABMAEEAQgABAA4AQwBJAFIAVAAtAEQAMwAEABYAYQBkAGwAYQBiAC4AbABvAGMAYQBsAAMAJgBDAEkAUgBUAC0ARAAzAC4AYQBkAGwAYQBiAC4AbABvAGMAYQBsAAUAFgBhAGQAbABhAGIALgBsAG8AYwBhAGwABwAIAMsTFgtFNc4BAAAAAA
I'm not positive I understand your question but I'm guessing that you want to resolve the intermittent NTLM failures?
The headers you describe are part of the challenge response protocol of NTLM. Here's a more complete example:
Client: Get / HTTP/1.1
Server: HTTP/1.1 401 Unauthorized
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
Client: Get / HTTP/1.1
Authorization: Negotiate ###################### (encrypted Negotiate)
Server: HTTP/1.1 401 Unauthorized
WWW-Authenticate: Negotiate ###################### (encrypted Challenge)
Client: Get / HTTP/1.1
WWW-Authenticate: Negotiate ###################### (encrypted Response)
Server: HTTP/1.1 200 OK
It's probably a bad idea to use this Authentication method across the public internet; it's intended to be used within private intranets where both client and server can access a common Windows Active Directory Domain.
I suspect that your issue may be addressed in the "You are intermittently prompted for credentials or experience time-outs when you connect to Authenticated Services" KB article.
Here are some other related references:
NTLM Bottlenecks and the RPC runtime
NTLM and MaxConcurrentApi Concerns
Performance tuning for NTLM authentication
Related
I get this error can hrlp me :
{"error":"The HTTP request is unauthorized with client authentication scheme \u0027Ntlm\u0027. The authentication header received from the server was \u0027Negotiate,NTLM\u0027."}
thanks
I'm trying to set up an API Management Gateway using a custom domain. However, when I go to test it out, I get an SSL error. I am not sure if I've missed any steps or I've misconfigured my custom domain. The API returns a 200 response when I use the default Gateway URL but returns a 400 when I use my custom domain.
Any help in this domain is appreciated. Thanks
I've described the steps I've followed below:
Steps followed to create a custom domain:
Setup a CNAME for my custom domain api.something.com in Route 53 with Value as .azure-api.net
When creating a custom domain, I added my PFX certificate to the custom domain. When creating my certificate, I set CN="*.something.com. Additional settings such as Negotiate Client Certificate: false and Default SSL binding: true
Created an API with the suffix app1 so that my API is reachable at api.something.com/app1
Now, when I try to test it out through the portal, I get the error
HTTP/1.1 400 Bad Request
content-length: 123
content-type: application/json
vary: Origin
{
"error": "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."
}
This is the request header. ALs I've turned off Require Subscription Key but I'm not sure why the subscription key is still included in the header
GET https://api.something.com/app1/api/heartbeat HTTP/1.1
Host: api.something.com
Ocp-Apim-Subscription-Key: xxxxxxxxx
Ocp-Apim-Trace: true
Following on from this question:
AADSTS50013: Assertion audience claim does not match the required value
I've now successfully got the web apps running with this security model:
SPA application using adal.js/adal_angular.js to authenticate via AAD.
Returned token is passed to web api [API1] that runs on the same machine.
That web api gets a new token on behalf of the user to access a downstream API [API2].
The downstream api gets a new token on behalf of the user to access another downstream API [API3].
Now, when I have [API2] running locally, this is all working.
However, when I deploy that web app to my Azure subscription, and attempt to call it (without changing anything else other than the url in the REST API call from [API1]), I get the following:
{"Message":"Authorization has been denied for this request."}
There doesn't appear to be any other error details returned or in the Fiddler trace. Comparing the jwt token payloads between the call that works and the one that doesn't, doesn't reveal much. They appear the same other than the expiry claims and the "aio" (not sure what that is).
The only change is the URL of the deployed web app (from http://localhost:8080/ to http://mywebappname.azurewebsites.net/)
Note that the web app is deployed into a different AD tenant to the one where the app registrations and [API3] are located, but I didn't think this mattered.
Any thoughts out there on what I might need to change when I deploy, or how to troubleshoot this further?
Update: Request works with Curl
Making the same request using curl is working:
curl -H "Authorization: Bearer ey..." http://mywebapi.azurewebsites.net/api/resource
So the issue appears to be how I'm making the request in my C# code? Comparing the headers in Fiddler, I don't see any difference.
This is the Fiddler trace from curl that is working:
GET http://mywebapi.azurewebsites.net/api/resource HTTP/1.1
Host: mywebapi.azurewebsites.net
User-Agent: curl/7.46.0
Accept: */*
Connection: Keep-Alive
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJ<snip>
This is the Fiddler trace from my code that is not working:
GET http://mywebapi.azurewebsites.net/api/resource HTTP/1.1
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJ<snip>
Accept: */*
User-Agent: RestSharp/100.0.0.0
Host: mywebapi.azurewebsites.net
Accept-Encoding: gzip, deflate
Here is the request from C#:
var restClient = new RestClient(serviceUrl) { Timeout = timeout};
var restRequest = new RestRequest(apiEndpoint, Method.GET);
var bearerToken = $"Bearer {securityToken}";
restRequest.AddParameter("Authorization", bearerToken, ParameterType.HttpHeader);
var response = restClient.Execute(restRequest);
On the Azure web site logs, I can see that the authentication type for the successful curl request is "JWT", however for the failed requests from my code they are "anonymous".
Somehow the header must be being stripped despite it showing up correctly in the Fiddler trace? Is this possible?
In an unrelated issue, I had to delete all untrusted certificates from my machine (Internet Options->Content->Certificates).
And I noticed after doing this, my problem was resolved. It was a very long list of certificates, so I don't know which one(s) were causing the problem, or why.
Given the lack of responses, its obviously a very obscure issue, but unfortunately we didn't get to the bottom of it. If it occurs again, I can be a bit more methodical when I do it.
Suppose I expose a REST service (over HTTPS) that uses bearer token authentication (JWT) and responds to a GET request with the Cache-Control: private header.
Now suppose my application is used in kiosk mode (multiple users use same browser session as same OS user, think internet cafe or something). User1 makes an authenticated request to a resource.
GET /api/resource
Authorization: bearer <token1>
The response starts with:
HTTP/1.1 200 OK
Cache-Control: private
Now, User1 signs out of my application and User2 signs in. The browser makes a request to the same resource on her behalf (but with a different JWT token).
GET /api/resource
Authorization: bearer <token2>
Now my question is, would the browser consider serving this from cache as it's the same request from the same OS user? Or would the browser consider the Authorization value in that decision?
If the former, would a Vary: Authorization header in the original response change that behavior.
Per RFC 2616, Section 14.9.1, the Cache-Control: private response header will indeed mean that your multiple kiosk users, sharing the same browser session, will all get the same cached response.
And yes, adding a Vary: Authorization response header would help, as indicated by Section 13.6 of RFC 2616; it tells the cache to keep/select from among different "representations" of the resource, based on the request headers listed in the Vary response header value.
Hope this helps!
We are using IIS Aplication Request routing and URL Rewrite rules to reverse proxy access to an internal webserver.
This works when IIS is configured with Anonymous authentication, but adding Basic Authentication causes problems. Without getting into too much detail about the internal webserver's authentication mechanisms, what I would like to do is not pass the Authorization Header from the IIS Proxy to the target webserver.
clientIP proxyIP HTTP GET /resource HTTP/1.1
Cache-Control: max-age=0\r\n
...
Authorization: Basic Base64EncodedCredentials
....
proxyIP serverIP HTTP GET /resource HTTP/1.1
Cache-Control: max-age=0\r\n
...
Authorization: Basic Base64EncodedCredentials <--need to remove this
....
Any tips would be greatly appreciated!