C# OAuthWebSecurity Google Provider URL? - c#

I've got an existing C# project with the following POST method:
// POST: /Account/ExternalLogin
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider, string returnUrl)
{
return new ExternalLoginResult(provider, Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
}
Which uses:
OAuthWebSecurity.Login(provider, ...);
I'm kinda new to OAuth, and haven't done anything with it in this C# project. I do however implemented Google-authorization on an Android App, and I want to use the following class/method for the HttpPost:
public class TaskPostAPI extends AsyncTask<String, Void, String>
{
GoogleApiClient googleAPI;
public TaskPostAPI(GoogleApiClient googleAPI){
this.googleAPI = googleAPI;
}
#Override
protected String doInBackground(String... urls){
String response = "";
for(String url : urls){
DefaultHttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
try{
List<NameValuePair> nvPairs = new ArrayList<NameValuePair>(2); //(3);
//nvPairs.add(new BasicNameValuePair("personName", Plus.PeopleApi.getCurrentPerson(googleAPI).getDisplayName()));
//nvPairs.add(new BasicNameValuePair("personGooglePlusProfile", Plus.PeopleApi.getCurrentPerson(googleAPI).getUrl()));
//nvPairs.add(new BasicNameValuePair("personEmail", Plus.AccountApi.getAccountName(googleAPI)));
nvPairs.add(new BasicNameValuePair("provider", ???));
URL u = new URL(url);
nvPairs.add(new BasicNameValuePair("returnUrl", u.getProtocol() + "://" + u.getHost()));
post.setEntity(new UrlEncodedFormEntity(nvPairs));
HttpResponse execute = client.execute(post);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String s = "";
while((s = buffer.readLine()) != null)
response += s;
}
catch(Exception ex){
ex.printStackTrace();
}
}
return response;
}
}
So my question: What should I put at the POST-method's ???. So what is the Provider? In my Android App I log in using Google, and got the GoogleApiClient and Person (com.google.android.gms.plus.model.people.Person).
At this website I see the following url: https://accounts.google.com/o/oauth2/auth. Is this the url I should use as provider? Or should I add parameters to this url? Or should I use a completely different string as provider?
PS: If someone can send me a link to a list of provider-urls (like Google's, Facebook's, Twitter's, etc.) and how to use them for the C# OAuthWebSecurity I would appreciate it.
Thanks in advance for the responses.

Ok it turns out it was very simple.. The provider is just "Google", nothing more, nothing less.. This provider name I found at the RegisterClient method in de C# project:
OAuthWebSecurity.RegisterClient(client, "Google", extraData);
Now the POST works, except for the message "The required anti-forgery cookie "__RequestVerificationToken" is not present.", but at least I can continue. And adding a Cookie to a HttpPost isn't that hard I believe when using a CookieManager.

Related

Routing a redirect URL in Web Api .Net

I am working on Github api Oauth.
The main problem is to match callback URl with method in Web Api
[HttpGet]
[Route("api/values/callback/{code}&{state}")]
public JsonResult Get (string code, string state)
{
var s = User.Claims;
return new JsonResult(s);
}
In StartUp file:
options.CallbackPath = new PathString("/api/values/callback/");
Redirect in URL that should match an action in service
http://localhost:5000/api/values/callback/?code=b1b0659f6e0&state=CfDJ8Ir-xT
So, I can not build rout which has pattern /?param1&param2
Here is redirect URL that should match :
Would be glad for help :)
You can use [FromQuery] to get values from the query string.
[HttpGet]
[Route("api/values/callback")]
public JsonResult Get([FromQuery]string code, string state)
{
string s = "code:" + code + " state:" + state;
return new JsonResult(s);
}
Test
If you're using OidClient you can use the following to inject the service to the method and get the querystring to process.
// route method here
public async Task<ActionResult> ProcessCallback([FromServices] HttpListenerRequest request){
...
// generate the options using `OidcClientOptions`
var client = new OidcClient(options);
var result = await client.ProcessResponseAsync(request.QueryString.ToString(), null);
...
}
I would suggest to edit the route to api/values/callback/code={code}&state={state} .

How to get the authentication header from a request sent to an ASP.NET core 2.0 API controller action

I am working on an ASP.NET Core 2.0 RESTful API. I have a scenario where I need to use an HTTPGet method to call an action on my API controller and I need to extract a username and password value that will be used to call another 3rd party API. The username and password are not related to the current logged in user Identity, they are just values I want to send to another API from within my own API, but I do not want to just pass them in a query string.
Can I use basic authentication in the client to add the username and password to the HttpRequestMessage authentication header and then extract that header in my ASP.NET Core 2.0 API controller action?
My client wold have something like this in the code that will call the API
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, relativeUrl);
var byteArray = new UTF8Encoding().GetBytes(string.Format($"username:password"));
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
and, my API controller action would start something like this;
[HttpGet()]
public IActionResult GetUploadedFileList([FromQuery]int pageNumber, [FromQuery]int pageSize)
{
//Extract Authentication header values for username and password
}
Can anyone provide an example of how to get the Authorization header from the HTTPGet request
I realize I can easily do this with an HTTPPost [FromBody] but my use case calls for this method to be an HTTGet.
Thanks in advance for any help.
EDIT 1 - SOLUTION
I was able to get the code below to work, thanks to some hints from this link. Although this seems like a lot of work, so if anyone has a better or cleaner solution, please post your example.
[HttpGet()]
public IActionResult GetUploadedFiles([FromQuery]int pageNumber, [FromQuery]int pageSize)
{
string username = string.Empty;
string password = string.Empty;
if (Request.Headers.TryGetValue("Authorization", out StringValues authToken))
{
string authHeader = authToken.First();
string encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();
Encoding encoding = Encoding.GetEncoding("iso-8859-1");
string usernamePassword = encoding.GetString(Convert.FromBase64String(encodedUsernamePassword));
int seperatorIndex = usernamePassword.IndexOf(':');
username = usernamePassword.Substring(0, seperatorIndex);
password = usernamePassword.Substring(seperatorIndex + 1);
}
else
{
return BadRequest("Missing Authorization Header.");
}
//Build FilesUploadedListRequest
FilesUploadedListRequest filesUploadedListRequest = new FilesUploadedListRequest
{
Username = username,
Password = password,
PageNumber = pageNumber,
PageSize = pageSize
};
//Call GetUploadedFilesList
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
CancellationToken cancellationToken = cancellationTokenSource.Token;
Task<FilesUploadedListResponse> FilesUploadedListResponse = _clientService.GetListOfUploadedFilesAsync(filesUploadedListRequest, cancellationToken);
//Return results
if (filesUploadedListResponse.Result.Success)
{
return Ok(filesUploadedListResponse.Result);
}
return StatusCode(filesUploadedListResponse.Result.StatusCode, filesUploadedListResponse.Result.Reason);
}
ASP.NET Core supports a [FromHeader] attribute for action parameters, similar to [FromBody] and [FromQuery]. So adding a [FromHeader]string authorization arg to your action will shave a couple lines off your solution, as well as make the method more testable since you can avoid accessing the Request object.

What is the ASP.NET Core MVC equivalent to Request.RequestURI?

I found a blog post that shows how to "shim" familiar things like HttpResponseMessage back into ASP.NET Core MVC, but I want to know what's the new native way to do the same thing as the following code in a REST Post method in a Controller:
// POST audit/values
[HttpPost]
public System.Net.Http.HttpResponseMessage Post([FromBody]string value)
{
var NewEntity = _repository.InsertFromString(value);
var msg = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Created);
msg.Headers.Location = new Uri(Request.RequestUri + NewEntity.ID.ToString());
return msg;
}
In an ASP.NET Core MVC project, I can't seem to get Request.RequestUri.
I tried inspecting Request, and I was able to make a function like this:
private string UriStr(HttpRequest Request)
{
return Request.Scheme + "://" + Request.Host + Request.Path; // Request.Path has leading /
}
So I could write UriStr(Request) instead. But I'm not sure that's right. I feel like I'm hacking my way around, and not using this correctly.
A related question for earlier non-Core ASP.NET MVC versions asks how to get the base url of the site.
Personally, I use :
new Uri(request.GetDisplayUrl())
GetDisplayUrl fully un-escaped form (except for the QueryString)
GetEncodedUrl - fully escaped form suitable for use in HTTP headers
These are extension method from the following namespace : Microsoft.AspNetCore.Http.Extensions
A cleaner way would be to use a UriBuilder:
private static Uri GetUri(HttpRequest request)
{
var builder = new UriBuilder();
builder.Scheme = request.Scheme;
builder.Host = request.Host.Value;
builder.Path = request.Path;
builder.Query = request.QueryString.ToUriComponent();
return builder.Uri;
}
(not tested, the code might require a few adjustments)
Here's a working code. This is based off #Thomas Levesque answer which didn't work well when the request is from a custom port.
public static class HttpRequestExtensions
{
public static Uri ToUri(this HttpRequest request)
{
var hostComponents = request.Host.ToUriComponent().Split(':');
var builder = new UriBuilder
{
Scheme = request.Scheme,
Host = hostComponents[0],
Path = request.Path,
Query = request.QueryString.ToUriComponent()
};
if (hostComponents.Length == 2)
{
builder.Port = Convert.ToInt32(hostComponents[1]);
}
return builder.Uri;
}
}

Cookies disappearing in MVC4

I'm working on a REST API Project where users log in and make calls. In order to do that, i create a cookie where i encrypt the username. My server is deployed and something really weird is going on. From time to time i just don't receive the cookies in the response. In this case I just have to make any modification in the web.config file and it starts working again... I really don't understand why... Any ideas ?
Here's my login code :
[Route("login", Order = 1)]
[HttpPost]
[HttpGet]
public async Task<HttpResponseMessage> Login([FromUri] string userId, [FromUri] string userPassword)
{
try
{
Tuple<string, string> result = userService.Authenticate(userId, userPassword);
string sessionIds = result.Item1;
string message = result.Item2;
CookieHeaderValue cookie = CreateSessionsCookie(sessionIds);
cookie.Secure = true;
// Store username for later use
CookieHeaderValue userCookie = new CookieHeaderValue(Strings.Id, Encryption.Protect(userId, Strings.Id));
userCookie.Secure = true;
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, JsonConvert.DeserializeObject(message));
response.Headers.AddCookies(new CookieHeaderValue[] { cookie, userCookie });
return response;
}
catch (Exception ex)
{
return HandleException(ex);
}
}
It is a bit of an anti-pattern to use a cookie for a restful web service. Just include the username in the header instead.
As to why this is timing out I suspect it has to do with your session timing out.

Using twilio c# client to pass twilio response back

I am using the twilio c# wrapper and am able to receive communication from twilio. I am having trouble responding back to twilio with a response and having twilio recognize it. Currently I am trying to respond with a TwilioResponse. Anyone have a good example? This is a WebApi self hosted windows service.
ex. TwilioResponse().Message("ok");
I have used Same web API you can use the below menioned code but First you have to configure your APP in Twilio UserAccount.
public class WelcomeController : ApiController
{
public HttpResponseMessage Post(VoiceRequest request)
{
var response = new TwilioResponse();
response.Say("Welcome to Dhaval demo app. Please enter your 5 digit ID.");
response.Gather(new { numDigits = 5, action = string.Format("/api/Authenticate") });
return this.Request.CreateResponse(HttpStatusCode.OK, response.Element, new XmlMediaTypeFormatter());
}
}
When I press the 5 digit no then it will lend to Authetication Controller it' look like
public HttpResponseMessage Post(VoiceRequest request)
{
var response = new TwilioResponse();
var validIds = new List<string> { "12345", "23456", "34567" };
var userId = request.Digits;
var authenticated = validIds.Contains(userId);
if (!authenticated)
{
response.Say("You entered an invalid ID.");
response.Hangup();
}
else
{
response.Say("ID is valid.");
response.Redirect(string.Format("/api/Name?userId={0}", userId));
}
return this.Request.CreateResponse(HttpStatusCode.OK, response.Element, new XmlMediaTypeFormatter());
}
and it's work fine in my side, once again check it properly you have given the correct AuthToken
Cheers
After tinkering for a while, this seems to do the trick.
var twiml = new TwilioResponse().Message("test");
return TwilioResponse(twiml);
private HttpResponseMessage TwilioResponse(TwilioResponse twilioResponse)
{
return new HttpResponseMessage()
{
Content = new StringContent(twilioResponse.ToString(), Encoding.UTF8, "text/xml"),
StatusCode = System.Net.HttpStatusCode.OK
};
}

Categories

Resources