How to sign-out using the end session endpoint IdentityServer4? - c#

I've tried to logout from my session using GET request from IdentityServer4 docs.
HttpResponseMessage looks like this:
HttpResponseMessage res = await client.GetAsync($"connect/endsession?id_token_hint={idTokenHint}&post_logout_redirect_uri={postLogoutRedirectUri}");
At first, I have a problem with Uri lenght. When I send request, method catch exception
Invalid URI: The Uri scheme is too long.
To fix this problem I've tried send parameters into string like this:
var parameters = $"?id_token_hint={idTokenHint}&post_logout_redirect_uri={postLogoutRedirectUri}";
HttpResponseMessage res = await client.GetAsync("connect/endsession" + parameters );
Also add MaxRequestLineSize in Program.cs like this:
UseKestrel(options =>
{
options.Limits.MaxRequestLineSize = 20480;
})
Also tried this way: https://stackoverflow.com/a/32457474/9541386 But nothing working for me.
I've tried send this request by Postman. Request was sent
http://localhost:5000/connect/endsession?id_token_hint={idTokenHint}&post_logout_redirect_uri={postLogoutRedirectUri}
but in FindClientByIdAsync method from IClientStore interface clientId parameter looks like this:
But in normal case there is Id. I can't see what happens before it because it's first entry point.
How can I fix problem with Uri length and wrong parameter?

The problem is most likely an invalid character in the query parameters:
?id_token_hint={idTokenHint}&post_logout_redirect_uri={postLogoutRedirectUri}
In this case I suspect the string postLogoutRedirectUri that contains the character :, which is invalid if not escaped: %3A.
Encode the uri:
var encodedUri = System.Web.HttpUtility.UrlEncode(postLogoutRedirectUri);
And use this as parameter:
?id_token_hint={idTokenHint}&post_logout_redirect_uri={encodedUri}
While that may fix the problem, why don't you use the provided methods to signout? E.g.:
//using Microsoft.AspNetCore.Authentication;
//using Microsoft.AspNetCore.Mvc;
// Remove cookie
await HttpContext.SignOutAsync("Cookies");
// Signout oidc
await HttpContext.SignOutAsync("oidc");

Related

Controller is not returning any type of data when called except for a test string

I am connecting to a 3rd party API that requires calls to retrieve an authorization code and a token.
The API requires a redirect URL, which when returned, contains the authorization code attached to the query string.
So, on my side so I set up this controller below that will read the queryString.
Then, my app needs to fire a POST request to the API to get the token, and you will see me calling the controller the contains the POST request.
When I click my button to connect to the API, in my browser window, I do see that I am redirected to the GetGeologicalPeriod() controller below because I see the message:
you have reached the GeologicalPeriod endpoint.
And I do see the authorization code in the query string.
But I don't see anything else, no errors, nothing.
I was expecting to see the results retuned from the call to GetGeologicalPeriodToken, or at least an error that it failed, but I am getting nothing...not even in the browser console window.
So I am kind of at a loss as to what is actually happening.
Since this is on a development server, I can't step through it locally in Visual Studio.
Is there anyway to show messages or write to console so I can see what's going on?
Thanks!
[ApiController]
public class GeologicalPeriodController : ControllerBase
{
[HttpGet]
public ActionResult<String> GetGeologicalPeriod()
{
string getTest = "you have reached the GeologicalPeriod endpoint.";
var queryString = Request.Query["code"];
var postResult = GetGeologicalPeriodToken(queryString);
return postResult;
}
[HttpPost("AuthRequest")]
public ActionResult<String> GetGeologicalPeriodToken(string authCode)
{
string authToken = authCode;
string authString = "admin";
var queryString = Request.Query["code"];
var client = new RestClient("https://geologicalPeriod.geo.gov/oauth/token?accessType=professor&code=" + authCode + "&redirect_uri=https://jamaica.round.astro.edu/api/geologicalPeriodauth/geologicalPeriod/AuthRequest");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", authString);
IRestResponse response = client.Execute(request);
var apiResponse = response;
return apiResponse.Content.ToString();
}

1. Forward slash in routing parameter

I have a GET end point which will take user name as parameter. Below is the action
[Route("user/{userName}")]
public User GetUserByName([FromUri] string userName)
{
// logic here
}
This is how i make the request.
var restClient = new RestClient("uri");
var request = new RestRequest("user/" + userName);
var response = restClient.Execute(request);
It worked fine for all cases till a user with name containing forward slash came.
Eg: Akbar/Badhusha
Then the request will looks like user/Akbar/Badhusha
This causing the request to return Not Fount error
I tried to add the parameter with AddQueryParameter method. All returning Not found error.
I also tried HttpUtility.UrlEncode
Also tried replacing / with %2f
Also tried user?userName=Akbar/Badhusha
All of them failed.
Is there any way to make it work?
Try removing [FromUri] from the parameter as shown below,
[Route("user")]
public User GetUserByName(string userName)
{
// logic here
}
And the request may look like,
user?userName=Akbar/Badhush

Getting a 404 when calling Authentication API using auth0.net

I am trying to authenticate using auth0.net (.NET client for the Auth0 API), however, I'm getting an Auth0.Core.Exceptions.ApiException error with an HTTP status code of NotFound (404).
I'm using the following code:
var client = new AuthenticationApiClient(new Uri(Auth0Url));
var authenticationRequest = new AuthenticationRequest();
authenticationRequest.ClientId = ClientId;
authenticationRequest.Username = username;
authenticationRequest.Password = password;
authenticationRequest.Connection = "Username-Password-Authentication";
AuthenticationResponse response = null;
Task.Run(async () =>
{
response = await client.AuthenticateAsync(authenticationRequest);
}).Wait();
What is wrong here? The Management API works fine and the ClientID is correct.
Just had this problem myself.
Two things.
First make sure you are using the correct API Url.
E.g.
https://<company>.au.auth0.com/api/v2
And not
https://<company>.au.auth0.com
Second Make sure you are using the base API
E.g.
https://<company>.au.auth0.com/api/v2
And not
https://<company>.au.auth0.com/api/v2/users

Find a User by Email Address

I'm trying find out if an email address is already taken in my Azure AD B2C directory.
var token = await this.GetTokenAsync();
var client = new HttpClient();
var id = HttpUtility.UrlEncode("adrian_mydomain.com#EXT##xxxxxxxxx.onmicrosoft.com");
////var id = HttpUtility.UrlEncode("adrian#mydomain.com"); // This also fails.
////var id = HttpUtility.UrlEncode("adrian_mydomain.com#EXT#"); // This also fails.
////var id = "xxxx-xxxx-xxxxxxxx-xxxxxxxxxx"; // This also fails (user object id).
var resource = $"{this.graphConfig.GraphUri}/{this.graphConfig.Tenant}/users/{id}?api-version=1.6";
//// This line below works, it returns all the users, so I do know the token is good and the resource URI is valid, etc.
////var resource = $"{this.graphConfig.GraphUri}/{this.graphConfig.Tenant}/users?api-version=1.6";
var request = new HttpRequestMessage(HttpMethod.Get, resource);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
var response = await client.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();
I'm encoding my email address in the same way that I see my email address encoded when I get all users. I have a feeling I'm close, if it is even possible to query by email address.
Currently all the things I've tried either return a 400 or a 404. Does anyone know if there is a way to query by email address (sign in name)?
EDIT
On a similar theme, I'm also trying a query to change a user's password to no avail. I figure if I can get the query working for one, I can get it working on the other.
Since it is a odata, you can query using odata syntax. Odata syntax here
var queryString = HttpUtility.ParseQueryString(string.Empty);
queryString["api-version"] = "1.6";
queryString["$filter"] = "signInNames/any(x:x/value eq 'paule#test.in')";
string url = "https://graph.windows.net/" + tenant + "/users"+ "?" + queryString;
$filter did the trick
queryString["$filter"] = "signInNames/any(x:x/value eq 'paule#test.co.uk')";
Take a look at the B2C.exe implementation, first get that working:
https://azure.microsoft.com/nl-nl/documentation/articles/active-directory-b2c-devquickstarts-graph-dotnet/
You will notice that the user is referenced by GUID or by UPN, not by email!
Emails are in the collection signInNames
To query on email address, you will need to specify a filter:
https://msdn.microsoft.com/en-us/library/azure/ad/graph/api/users-operations#GetUsers
Start with the GetUsers(to get all users), then update password and last the filter.
signInNames isn't the only place that emails are stored. It could also be userPrincipalName or otherMails. You'll want to use the following query to search all possible fields for an email.
/users?api-version=1.6&$filter=otherMails/any(x:x eq '{email}') or userPrincipalName eq '{email}' or signInNames/any(x:x/value eq '{email}')
I'm also trying to find a user by their login/email address.
Here's my (obfuscated XXXX) query string:
"https://graph.windows.net/XXXX.onmicrosoft.com/users?api-version=1.6&$filter=signInNames/any(x: x/value eq 'dd.rrr#XXXX.com')"
It doesn't error, but doesn't find the user (whom I know to exist, because GetAllUsers finds it).
However, looking at the user details, I can see:
"showInAddressList": null,
"signInNames": [],
"sipProxyAddress": null,
Could this be a clue as to why search doesn't work?
How can a user NOT have a signInName?

Extend Facebook Token

I am using the Microsoft.AspNet.Mvc.Facebook NuGet package. I would like to exchange a regular token for the extended access token (the one that replaced the offline_access permission).
From Googling around I found the URL should be in this format:
https://graph.facebook.com/oauth/access_token?
client_id=[APP_ID]&
client_secret=[APP_SECRET]&
grant_type=fb_exchange_token&
fb_exchange_token=[EXISTING_ACCESS_TOKEN]
So I use the following code:
var longToken = await context.Client.PostTaskAsync("/oauth/access_token",
new
{
client_id = fbApp.AppId,
client_secret = fbApp.AppSecret,
grant_type = "fb_exchange_token",
fb_exchange_token = context.AccessToken
});
This returns a null. No error or anything. Just a null value.
Edit: Also tried the following, which also did not work. But a GET seems more logical than a POST anyway.
dynamic result = context.Client.Get("oauth/access_token",
new
{
client_id = fbApp.AppId,
client_secret = fbApp.AppSecret,
grant_type = "fb_exchange_token",
fb_exchange_token = context.AccessToken
});
var longToken = result.access_token as string;
I have successfully done this as a GET request, not a POST :) Just put the necessary parameters into the URL and request it as a GET request and the response returns the long term access token.
EDIT
When you get the result from this, you should parse the query string first (am not sure in C# but maybe you could use this link: http://msdn.microsoft.com/en-us/library/ms150046(v=vs.110).aspx).
After that try to get the access_token property and I got it right on my end. I was doing it in node.js though, but essentially the same flow.

Categories

Resources