Error requesting access token for client default after upgrading to Duende Identity Server - identityserver4

After upgrading from IdentityServer4 (v2) to Duende Identity Server, I am getting this error when an app is trying to get a token to connect to an API:
error requesting access token for client default
There is no "Error" in the logs, but the token request returns a 404:
Microsoft.AspNetCore.Routing.Matching.DfaMatcher:
|No candidates found for the request path '//connect/token'
Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware:
|Request did not match any endpoints
Duende.IdentityServer.Hosting.EndpointRouter:
|No endpoint entry found for request path: //connect/token
Microsoft.AspNetCore.Hosting.Diagnostics:
|Request finished HTTP/1.1 POST https://accounttest.veic.org//connect/token
application/x-www-form-urlencoded 29 - 404 - - 2.0641ms
This same app used to work fine before the Identity Server upgrade.

As it turns out, this error has nothing to do with Duende Identity Server. The problem is that upgrading .NET to use EndPoint Routing can cause this issue.
The previous code to app.UseMvcWithDefaultRoute was more gracious about accepting double slashes in a URL. The new app.UseEndpoints routing does not handle this double slash in the URL and route it to an action.
Here is a good answer about how to deal with the double slash in the URL.

Related

IdentityServer API unauthorized if hosted in IIS

I added additional API to the Duende IdentityServer 6.2 as described here. Then I tried to access it from a sample App, using typed httpClient using their own library called AccessTokenManagement (aka Identity.Model) pretty much following their simple example. I use Authorization Code flow, everything pretty much simple and default.
It works well until both server and client are on the same dev machine under localhost. As soon as I publish IdentityServer to IIS, the API stops to work, while the rest still works well (I can be authenticated, and I see in the Fiddler that token exchanges work normally).
The call to API consists from two calls:
Calling to /connect/token using refresh token. Server returns access token.
Calling my endpoint using this new access token.
The flow fails on the step 1. Call to /connect/token is already unauthorized and I can't understand why. The "good" and "bad" calls looks the same, I cannot see any differences. Previous call moment ago to /connect/userinfo consists of the same two steps and it works. Logs on both server and client give no clues.
No reverse proxies, just good plain simple URI. Automatic key management is enabled and the keys are in the SQL table, common for dev and published server. Asp.Net Core Data Protection is enabled and keys are also common.
Relevant parts of logs are below. I noticed that "No endpoint entry found for request path" is specific to IdentityServer and it doesn't actually mean that endpoint was not found. It was found but not processed. I also noticed reacher response headers from bad request and log entry about "Cookie signed-in" in good request but not sure what does it mean and whether it's relevant.
I'm running out of ideas.
Bad response from IIS while trying to get new Access Token:
Proper response while developing:
///////Relevant part of log for BAD request
|Duende.AccessTokenManagement.OpenIdConnect.UserAccessAccessTokenManagementService|Token for user test#test.com needs refreshing.
|Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler|AuthenticationScheme: cookie was successfully authenticated.
|Duende.AccessTokenManagement.OpenIdConnect.UserTokenEndpointService|refresh token request to: https://auth.mysite.org/connect/token
|Duende.AccessTokenManagement.OpenIdConnect.UserAccessAccessTokenManagementService|Error refreshing access token. Error = Unauthorized
|System.Net.Http.HttpClient.IdsService.ClientHandler|Sending HTTP request POST https://auth.mysite.org/mycontroller/myaction
|System.Net.Http.HttpClient.IdsService.ClientHandler|Received HTTP response headers after 117.7278ms - 401
///////Same part of GOOD request
|Duende.AccessTokenManagement.OpenIdConnect.UserAccessAccessTokenManagementService|Token for user test#test.com needs refreshing.
|Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler|AuthenticationScheme: Cookies was successfully authenticated.
|Duende.AccessTokenManagement.OpenIdConnect.UserTokenEndpointService|refresh token request to: https://localhost:5001/connect/token
|Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler|AuthenticationScheme: Cookies signed in.
|System.Net.Http.HttpClient.IdsService.ClientHandler|Sending HTTP request POST https://localhost:5001/mycontroller/myaction
|System.Net.Http.HttpClient.IdsService.ClientHandler|Received HTTP response headers after 1994.9611ms - 200
///////Server log during BAD request
Duende.IdentityServer.Hosting.EndpointRouter No endpoint entry found for request path: "/mycontroller/myaction"
Duende.IdentityServer.Hosting.LocalApiAuthentication.LocalApiAuthenticationHandler HandleAuthenticateAsync called
Duende.IdentityServer.Hosting.LocalApiAuthentication.LocalApiAuthenticationHandler AuthenticationScheme: "IdentityServerAccessToken" was not authenticated.
Duende.IdentityServer.Hosting.LocalApiAuthentication.LocalApiAuthenticationHandler AuthenticationScheme: "IdentityServerAccessToken" was challenged.
Okay, found it. Thankfully, looked at Fiddler's WebView and had seen familiar picture!
Then, found this topic. The solution was disabling Basic authentication in IIS settings. Access token request has basic authentication header and it seems like IIS intercepts it. Still a bit unclear why other parts of flow worked.

duende identity server RequestClientCredentialsTokenAsync won't pass redirect uri

I'm using Duende Identity Server 6 and trying to get Access Token from my Identity Server
in my API Controller using http client base on duende documentation.
But I get this Invalid redirect uri in my Identity Server console logs.
As you can see the redirectUri is null in information log,
and there is my code in Client API.Controller
You are trying to make a client credentials flow. The endpoint you need to invoke is /connect/token. Is not necessary redirect uri in this flow.

React axios Cors Policy error with 3rd side server

I have react client that sends get request to my node server using axios, which received in my server after I allowed cors,
and the server passes the request to 3rd side server which I have no access to its configuration at all so I cannot allow cors in that server ,and the request sent with the client Origin of course. For that reason, I get No Access-Control-Allow-Origin error. I read and try many ways to solve that, still without success. Any idea how to solve that?
FYI if I send the request from my server without the client its success.
Edit:
React:
axios.get(host+url).then(...)
Node:
app=express();
....some code here for init auth params(clientId,secret)
and session init
app.get(url,auth.authenticate(failUrl,successUrl);
app.use(auth.init());
The auth.authenticate is libary that after logic that I am not fully aware of taking some params of openid connect authentication, and send get request with all of this params.
At the end of the operation I should be redirected to fail/success url, however I am not even get there.

Salesforce returning "unsupported_grant_type"

We implemented OAuth 2.0 using Web Server Authentication Flow. It was working fine in October/November but all of a sudden it has stopped working. Whenever we try authorising another client the server return (400) Bad Request with the body
{"error":"unsupported_grant_type","error_description":"grant type not supported"}
grant_type is set as authorization_code which is definitely valid.
Is there any reason why OAuth would suddenly stop working?
This is how we have implemented OAuth:
First user is directed to: https://login.salesforce.com/services/oauth2/authorize?response_type=code&client_id=blah.id&redirect_uri=https://domain.com/Web/Salesforce/Callback.aspx&scope=api%20refresh_token
User is prompted by Salesforce to login to their account.
Once user is authenticated Salesforce calls Callback.aspx, Callback.aspx requests refresh token on behalf of the client by making a POST request to: https://login.salesforce.com/services/oauth2/token with the payload:
grant_type=authorization_code&code=blah.code&client_id=blah.Id&client_secret=11111111&redirect_uri=https://domain.com/Web/Salesforce/Callback.aspx
Content type is definitely: application/x-www-form-urlencoded
After lot of fiddling around with fiddler figured out there was a space before grant_type=authorization_code in HTTP POST payload that was causing the issue.
Interestingly that space has been there in code base since July and this issue was first noticed on 14th Jan. It is possible Salesforce fixed a bug or made an internal change to reject space before grant_type=authorization_code.
Make sure you are using 'https' not http
If you are having this error while authorising an Org through terminal sfdx command -
error authenticating with auth code due to: grant type not supported
Worked for me 'https' solved my grant type not supported problem.

Connection Refused using access token from OAuth 2.0 User-Agent Authentication from Salesforce

I'm using OAuth2.0 User-Agent Authentication flow to get the access & refresh tokens so that I can use the Foce.com REST API over remote access. Now, the problem is that I'm able to authorize successfully and recieve the tokens, but while using those tokens just after authorizing my client application, I'm recieving a java.net.ConnectException: Connection refused error.
Following Steps I'm doing
Redirecting to
https://login.salesforce.com/services/oauth2/authorize?response_type=token&client_id={my_client_id}&redirect_uri={my_redirect_uri}&state=myState
Authorizing the app in salesforce and then receiving back the access token and refresh tokens in the hash of the redirect_uri as
{my_redirect_uri}#access_token={my_access_token}&refresh_token={my_refresh_token}&instance_url=https%3A%2F%2Fap1.salesforce.com&id=https%3A%2F%2Flogin.salesforce.com%2Fid%2F00D90000000gscOEAQ%2F00590000000sdtJAAQ&issued_at=1351151192815&signature={my_signature_value}&state=myState
&scope=id+api+refresh_token
Now I'm using the REST API using the same access token by doing a POST to
https://ap1.salesforce.com/services/data/v20.0/sobjects/Lead/
with request headers:
Content-Type: application/json
Authorization: OAuth {my_access_token}
I have not escaped the access token while sending the post as it needs to be done when using CURL. Is that needed when using HttpClient Java API also?
The response that I'm getting is "java.net.ConnectException: Connection refused error."
Can someone please let me know what I'm doing wrong or how I can debug it further ?? Is there any way to see whats happening at Salesforce end? Some logs may be ?
I'm getting the exact same connection refused error if I try OAuth Refresh Token Process also.
Sorry for the noise.
I was getting "invalid_grant" with "expired access/refresh token" while validating the customer secret using the Refresh Token Procedure but since it was secured transmission so all I was getting in Java was "Connection Refused" with no detailed error message.
I got to know the detailed error by Setting up SSL Proxy in Charles as described here. After that I was able to see the request parameters and response send to https://ap1.salesforce.com which was earlier not readable.

Resources