HttpResponseMessage Content Property in Compact Framework - c#

I am building a .NET 4.5 MVC 4 Web API that will have publicly exposed Controller Methods that I wish to secure access to. I have created a Action Filter Attribute to check for a properly encoded RSA token shown below gutted for brevity:
public class TokenValidationAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
try
{
//authorize user
}
catch (Exception)
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden)
{
Content = new StringContent("Unauthorized User")
};
}
}
}
And then in my .NET 3.5 CF application I would do the following:
public static List<string> GetAvailableProjectIds()
{
var idList = new List<string>();
var url = "the url";
var req = CreateRequest(url, true);
try
{
using (var response = (HttpWebResponse)req.GetResponse())
{
//do something with the resonse
}
}
catch (Exception ex)
{
}
return idList;
}
The Exception that is caught is a WebException and contains the correct 403 Forbiden Status Code. But nothing more helpful that I can find.
Is there a way to get at the Content property so I can display to the end user that they tried authenticating with an "Unauthorized User"?

I never really liked that behavior, that it uses exceptions when the communication was just fine. Try adding this extension method:
private static HttpResponse GetAnyResponse(this HttpRequest req)
{
HttpResponse retVal = null;
try
{
retVal = (HttpWebResponse)req.GetResponse()
}
catch (WebException webEx)
{
retVal = webEx.Response;
}
catch (Exception ex)
{
// these are the "bad" exceptions, let them pass
throw;
}
return webEx;
}
And then change your code to this:
using (var response = (HttpWebResponse)req.GetAnyResponse())
{
//do something with the resonse
}

Related

How to Decrypt the payload on server during authorization and map to model in web api

I've been trying to follow this answer trying to decrypt the Encrypted payload during the Authorization before it gets model mapped to the controller.
From the client only the Payload will be encrypted and on the server side I'm trying to decrypt. Thing is the entire Response.content cannot be decrypted as only the payload needs to decrypted.
Inside the content we're receiving the payload in Result and when I'm trying to change that it is showing that it is read only and I couldn't see any other options. In the image above the result is not encrypted yet, I was testing to see if we can change that.
I've done it in another way where I'll be passing the entire encrypted string to the controller and then decrypting it and mapping to model inside the controller like this:
[Route("api/xxxxxx")]
[HttpPost]
public HttpResponseMessage PostTest(string encryptedValue)
{
//creating an instance of class
HttpResponseMessage response = new HttpResponseMessage();
try
{
string decryptJson = AES.DecryptString(encryptedValue);
Model list = JsonConvert.DeserializeObject<Model>(decryptJson);
//rest of the operation
}
//to catch exceptions if any
catch (Exception ex)
{
output.Success = false;
output.Message = Literals.GetErrorMessage(ex.Message);
}
//creating response
response = Request.CreateResponse(HttpStatusCode.OK, JObject.FromObject(output));
//returning response
return response;
}
This is working as expected but I'm trying if at all it's possible to do this at Authorization instead of doing it individually to every controller.
Any advice is appreciated.
Using new StringContent() to add the decrypted string to the Response.Content:
public class LogAttribute : AuthorizeAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
try
{
var resoponseContent = actionContext.Request.Content.ReadAsStringAsync();
var result = resoponseContent.Result;
var decryptedString = AESEncryptDecrypt.DecryptStringAES(result);
actionContext.Request.Content = new StringContent(decryptedString, Encoding.UTF8, "application/json");
var checkingDecryptedResponseContent = actionContext.Request.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
}
}
}
After updating the new content the Model will be auto mapped to the controller.
[LogAttribute]
[Route("api/xxxxxx")]
[HttpPost]
public HttpResponseMessage PostTest(Model data)
{
//creating an instance of class
HttpResponseMessage response = new HttpResponseMessage();
try
{
//rest of the operation
}
//to catch exceptions if any
catch (Exception ex)
{
output.Success = false;
output.Message = Literals.GetErrorMessage(ex.Message);
}
//creating response
response = Request.CreateResponse(HttpStatusCode.OK, JObject.FromObject(output));
//returning response
return response;
}

How to publish message without waiting for response RabbitMQ

I'm new to RabbitMq and I just followed internet resource as a tutorial. here I have created two separate API for OrderRequest and OrderConsume. from the order request, I'm calling something like this.
IRequestClient<OrderRequest> _client;
public OrderRepo(IRequestClient<OrderRequest> requestClient)
{
_client = requestClient;
}
public async Task<string> GetOrderList(OrderRequest orderRequest)
{
string datas = "";
try
{
using (var request = _client.Create(orderRequest))
{
var response = await request.GetResponse<OrderReponse>();
datas = response.Message.orderName;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
return datas;
}
and from the OrderConsume, I did something like this.
public class OrderConsumer : IConsumer<OrderRequest>
{
public Task Consume(ConsumeContext<OrderRequest> context)
{
OrderReponse request = new();
try
{
var data = context.Message.orderName + " HelloWorld";
request.orderName = data;
}
catch (System.Exception ex)
{
System.Console.WriteLine(ex.Message);
throw;
}
return Task.CompletedTask;
}
}
When I debugging the code Consume part working fine, but here you can see, I'm not passing any response from there. there for from the request API. I'm getting time out error.
Timeout waiting for response, RequestId: a1670000-a53b-c025-bd0b-08d9d52ca58a.
Actually I don't need any response from Consumer side, and just wanted to pass the request to consumer. I think I need to change my code here?
using (var request = _client.Create(orderRequest))
{
var response = await request.GetResponse<OrderReponse>();
datas = response.Message.orderName;
}
is it correct? but actually i don't know how to do it. please help me to solve this.
If your order command does not require a response, don't use the request client. Just publish the command and forget about it.
IPublishEndpoint _publishEndpoint;
public OrderRepo(IPublishEndpoint publishEndpoint)
{
_publishEndpoint = publishEndpoint;
}
public async Task<string> GetOrderList(OrderRequest orderRequest)
{
string datas = "";
try
{
await _publishEndpoint.Publish<OrderRequest>(orderRequest);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
return datas;
}
Of course, in your original code you were actually using the response, so...

How to throw a 401 Unauthorized Exception in .NET (JWT Validate Token)?

I have a .NET 4.5 API application. It's protected with OWIN/Oauth. I make a call with POSTMAN and fake the Bearer token, so i can test this case.
How to break the code execution after the validateToken function finds out that the JWT token has been manipulated/is not valid?
ClaimsPrincipal principal = handler.ValidateToken(protectedText, _validationParameters, out validToken);
This row gives back a SecurityTokenException. I catch the Exception like that:
catch (SecurityTokenException ex)
{
var msg = new HttpResponseMessage(HttpStatusCode.Unauthorized) { ReasonPhrase = "Access Token is manipulated" };
throw new HttpResponseException(msg);
}
After that the application execution continues and goes in the constructor of the ApiController I called through postman, which is protected with [Authorize], instead of giving me a HTTPResponse with 401 Unauthorized
P.S. Here is the code of the constructor in the ApiController
public class TicketController : ApiController
{
private readonly TicketService _svcTicket;
public TicketController()
{
try
{
_svcTicket = new TicketService(JwtFormat.AppContext);
}
catch (SecurityTokenException ex)
{
var msg = new HttpResponseMessage(HttpStatusCode.Unauthorized) { ReasonPhrase = "Access Token is manipulated" };
throw new HttpResponseException(msg);
}
catch (Exception ex)
{
throw ex;
}
}
}
I found it out:
public class TicketController : ApiController
{
private readonly TicketService _svcTicket;
public TicketController()
{
try
{
if(tokenIsManipulated) {
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Unauthorized)
{
Content = new StringContent("Access Token is manipulated")
});
}
}
catch(HttpResponseException)
{
throw;
}
}
}
There are 2 important things my code was missing before:
A new HttpResponseMessage object while throwing
An extra catch block for HttpResponseException's

Returning exceptions from OWIN middleware

I have a OWIN middleware class to do some authentication based on some custom tokens. All works fine. However I would like to return a useful error response to the client. My reasoning is that if the client asked for a 'application/json' response and they are expecting a serialize object, then that's what they should get, even if it is a 401 status code.
Here is the Invoke section of my middleware:
public override async Task Invoke(IOwinContext context)
{
try
{
this.DoAuthorization(context);
await this.Next.Invoke(context);
}
catch (UnauthorizedAccessException ex)
{
this.GenerateErrorResult(context, HttpStatusCode.Unauthorized, this.ExceptionToString(ex));
}
catch (Exception ex)
{
this.GenerateErrorResult(context, HttpStatusCode.InternalServerError, this.ExceptionToString(ex));
}
}
private void GenerateErrorResult(IOwinContext context, HttpStatusCode code, string errorMessage)
{
var result = new Result { Status = Result.EStatus.Error, ErrorText = errorMessage };
context.Response.StatusCode = (int)code;
context.Response.ContentType = "application/json";
context.Response.Write(JsonConvert.SerializeObject(result));
}
This all works fine, however:
is this the 'correct' way?
what if the client asks for 'application/xml', which obviously Web API is quite capable of supporting
Is there a better way to return a custom response object ('Result' in my case) that is serialized as the client would expect?
Well this seems to work, using an extra OwinMiddleware inserted first:
public override async Task Invoke(IOwinContext context)
{
try
{
await Next.Invoke(context);
}
catch (UnauthorizedAccessException ex)
{
var result = new Result { Status = Result.EStatus.Error, ErrorText = ExceptionToString(ex) };
this.ReturnFormattedResult(result, HttpStatusCode.Unauthorized, context);
}
catch (Exception ex)
{
var result = new Result { Status = Result.EStatus.Error, ErrorText = ExceptionToString(ex) };
this.ReturnFormattedResult(result, HttpStatusCode.InternalServerError, context);
}
}
private void ReturnFormattedResult(Result result, HttpStatusCode code, IOwinContext context)
{
// what should our response be?
var mediaType = context.Request.MediaType ?? context.Request.ContentType;
// use the accept header (unless it is empty or '*/*' in which case use the content-type
if (!string.IsNullOrEmpty(context.Request.Accept) && !context.Request.Accept.Contains("*/*"))
{
mediaType = context.Request.Accept;
}
// find a formatter for this media type, if no match then use the first one
var formatter = this.config.Formatters.FindWriter(typeof(Result), new MediaTypeHeaderValue(mediaType));
if (formatter == null)
{
formatter = this.config.Formatters.First();
mediaType = formatter.SupportedMediaTypes.First().MediaType;
}
context.Response.StatusCode = (int)code;
context.Response.ContentType = mediaType;
formatter.WriteToStreamAsync(typeof(Result), result, context.Response.Body, null, null).Wait();
}

Best practice for throwing exceptions in an utility class

I am creating a utility class that will be used in my Facebook application for tasks that are commonly done, such as retrieving a Facebook Page ID from a URL. I am unsure if the below code is the correct way to throw and catch exceptions. Could someone please advise, thanks.
Utility Class:
public static class FacebookUtilities
{
public static string GetPageIDFromGraph(string pageUri, string accessToken)
{
try
{
FacebookClient client = new FacebookClient(accessToken);
dynamic result = client.Get(GetPageIDFromUri(pageUri), new { fields = "id" });
return result.ToString();
}
catch (FacebookOAuthException)
{
throw;
}
catch (FacebookApiException)
{
throw;
}
}
public static string GetPageIDFromUri(string pageUri)
{
if (pageUri.Contains('/'))
pageUri = pageUri.Substring(pageUri.LastIndexOf('/') + 1);
if (pageUri.Contains('?'))
return pageUri.Substring(0, pageUri.IndexOf('?'));
else
return pageUri;
}
}
Program class, just testing:
- Note "input" and "output" are just textboxes.
private void btnGetPageID_Click(object sender, EventArgs e)
{
try
{
output.Text = FacebookUtilities.GetPageIDFromGraph(input.Text, "Some Access Token Goes Here");
}
catch (FacebookOAuthException ex)
{
if (ex.ErrorCode == 803)
{
output.Text = "This page does not exist";
}
}
catch (FacebookApiException ex)
{
if (ex.ErrorCode == 100)
{
output.Text = "The request was not supported. The most likely cause for this is supplying an empty page ID.";
}
}
}
Is it correct to simply rethrow the exception from the utility class so that the calling class can catch it and do what needs to be done?
It seems that you do nothing with catched exceptions - so dont catch them. There are a lot of discussions about exception handling, but in general you should catch exceptions when you have something to do with them, or at least using finally to clean up resourses.
Since you aren't handling the exceptions in any way, your code can just be:
public static string GetPageIDFromGraph(string pageUri, string accessToken)
{
FacebookClient client = new FacebookClient(accessToken);
dynamic result = client.Get(GetPageIDFromUri(pageUri), new { fields = "id" });
return result.ToString();
}
You should only catch exceptions when you can meaningfully handle them, and it doesn't look like you can in your GetPageIDFromGraph method, so you should just propagate them.

Categories