Problems catching exception from http flurl client - winforms

I have a rest api with .net5, which has a global exception filter, and returns an ErrorMessage object in case of exceptions.
I call the api from a WinForms .net framework 4.8 application and the badrequests from the server, from the client side I get a System.AggregateException exception and according to the flurl documentation it should be FlurlHttpException.
I tried to make calls with HttpClient, and everything works as expected, but I find it easier to use flurl, so I want to find a solution to the problem, if someone has any idea how to do it and wants to share it would be great
try
{
var result = (serverUrl)
.AppendPathSegment(endPoit)
.PostJsonAsync(new { Email = email, Password = password }).Result;
if (result.ResponseMessage.IsSuccessStatusCode)
{
var aut = result.GetJsonAsync<Autorizacion>().Result;
}
}
catch (FlurlHttpException ex)
{
var error = ex.GetResponseJsonAsync<ErrorMessage>();
}

Firstly, prefer using async await instead of blocking Result call. But if you have to go with blocking calls then use GetAwaiter().GetResult() to get the unwrapped exception.

Related

auth0 parseHash can't create property '__enableIdPInitiatedLogin' on hash string

I'm trying to upgrade my React web app from auth0-js 9.6.1 to 9.7.3. After installing the new library, my Slack login flow no longer works, it appears to be breaking in the callback.
TypeError: Cannot create property '__enableIdPInitiatedLogin' on string '#access_token={token string}&token_type=Bearer&state={state string}'
My parseHash call is:
this.auth0.parseHash(hash, (err, authResult) => {
if (authResult && authResult.idToken) {
AuthService.setToken(authResult.idToken); // JWT returned from Auth0;
// Redirect user to content.
const returnUrl = localStorage.getItem(Variables.RETURN_URL_KEY);
localStorage.removeItem(Variables.RETURN_URL_KEY);
returnUrl
? window.location.replace(returnUrl)
: window.location.replace("/");
} else if (err) {
console.log("Error with auth callback", err);
window.location.replace("https://foo.com"); // If auth fails, send user to home page.
}
}
This works fine in 9.6.1, but fails in 9.7.x and I can't find anything about any breaking changes that would cause it to start failing. Any ideas?
I had the same issue as you so I opened a ticket on the Auth0.js library github page.
This is the response I got from the developers:
It was working by accident then (also, the string is being ignored in your case), considering that we expect the first parameter to either be an object or a callback function.
All of our docs mention that:
https://github.com/auth0/auth0.js#api
https://auth0.github.io/auth0.js/global.html#parseHash
https://auth0.com/docs/libraries/auth0js/v9#extract-the-authresult-and-get-user-info
In your case, the simplest fix is to just remove the first parameter and keep only the callback. window.location.hash is already used when there's no options object.
(emphasis on the fix mine)
I tested 9.7.3 with this.auth.auth0.parseHash((err, result) => ... and it worked like a charm.
I hope this'll help!

MVC6 Prevent Redirect on unauthorized

I'm developing an ASP.NET MVC 6 Web API app, with AngularJs frontend.
When I leave a session to decade, or I'm trying to call a Web API action unauthorized, I expect to receive a 401 status code.
Instead, I get a 302, and tries to redirect to the default path for login ("/Account/Login").
So I need to handle this in Angular.
From other forum posts here and googling I found that some people resolved their problems using in startup.cs:
services.Configure<CookieAuthenticationOptions>(options =>
{
options.LoginPath = PathString.Empty;
});
No luck for me.
I use Identity as authentication backend and even adding
services.ConfigureIdentityApplicationCookie(options =>
{
options.LoginPath = PathString.Empty;
});
does not give me the expected result. ASP.NET docs suggest this way to return a 401.
Using 1.0.0-beta7 CLR x86, IIS Express.
EDIT: the solution proposed by #EZI is correct.
Below my answer, which doesn't work on recent release.
Finally! I found the solution!
To be complete, I started with this comment found on source code in aspnet/Identity github.
// If the LoginPath is null or empty, the middleware will not look for 401 Unauthorized status codes, and it will not redirect automatically when a login occurs.
which give me the wrong directions.
Digging with debug on ConfigureIdentityApplicationCookie' options, I found that there is a delegate on "Notifications" property
OnApplyRedirect
Bingo!
Now I can control the redirect.
services.ConfigureIdentityApplicationCookie(options =>
{
options.LoginPath = PathString.Empty;
options.Notifications = new CookieAuthenticationNotifications {
OnApplyRedirect = context => { context.Response.StatusCode = 401; }
};
});
This maybe isn't a good way to handle the problem, but finally I receive a 401 Unauthorized when the web.api action is called without authentication.
For me it worked to just set the AutometicAuthenticate to false.
services.Configure<IdentityOptions>(options =>
{
options.Cookies.ApplicationCookie.AutomaticAuthenticate = false;
options.Cookies.ApplicationCookie.AutomaticChallenge = false;
options.Cookies.ApplicationCookie.LoginPath = PathString.Empty;
});
my solution was similar to #Ezi
Confirmed working for RC2
services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
options.Cookies.ApplicationCookie.AutomaticChallenge = false;
});

How to catch wrong password/username response in angular?

I’m trying to implement authentication in my angularjs app.
I’ve read some articles about doing this properly. Here is one, for instance: https://medium.com/opinionated-angularjs/techniques-for-authentication-in-angularjs-applications-7bbf0346acec
But I can’t realize how to make it respond on wrong username/password pair.
Let’s have a look at this code :
authService.login = function (credentials) {
return $http
.post('/login', credentials)
.then(function (res) {
// populate user info
}
);
};
I’ve tried to add here a second callback to “then” method and use “success”/”error” methods instead of “then” and I’ve tried to response on $http.post request with different error like 400 and 500 via status, but in any case all the errors are handled by the success method and callback.
What am I doing wrong? How to catch wrong password/username response in angular?
It was actually my own fault. My custom Intereptor simply swallowed authenticaion errors.

Using Request/Reply in SAGA NserviceBus

I'm creating a SAGA in NServiceBus. This saga is handling some string which has to be transformed then validated and finally imported. These three actions are separate services. I want the actions as separate handlers in NServiceBus. I'm using the Request/Reply functionality in NServiceBus. Like this:
Bus.Send<TransformRequest>("Backend", m =>
{
m.string = string;
m.MessageId = messageId;
})
.Register(i =>
{
Console.WriteLine("transform finished")
});
The transformationHandler is as follows.
public void Handle(TransformRequest message)
{
var transformationResult = _transformationService.Transform(message.string);
var response = new TransformResponse()
{
string= transformationResult,
messageId = message.messageId,
};
Bus.Reply(response);
}
My question is as follows. When a request is sent to the transformationHandler. A message is sent to the messagequeue. Then hypothetical, the server crashes. The server reboots, the server picks up the TransformationRequest, does it work and wants to do a reply to the Saga, but how? The saga is not alive anymore and can't handle the .Register. How do I handle this problem?
Thank you.
NServiceBus will find the saga instance using a header in the response message automatically for you.
As Sean mentions you need to skip .Register and add a handler for transform result in your saga. The reason is that callbacks using .Register is stored in memory and therefor won't survive a restart

WebClient issue

I am trying to get contents of http://www.yahoo.com using WebClient#DownloadStringAsync(). However as Silverlight doesn't allow cross domain calls i am getting TargetInvocationException. I know we have to put clientaccesspolicy.xml and crossdomain.xml in our web server root but that is possible only if i have control on my services. Currently Google is not under my control ;), so how do i handle it?
I've did a workaround by making a WCF service in my web application and then calling WebClient. This works perfectly but it is rather ineffecient. Is there any other better way than this?
Thanks in advance :)
Silverlight's cross domain restricitions cause many developers to implement workarounds. If you need to display the html page you get back you should look into Silverlight 4 (WebBrowser) control although this only seems to work when running out-of-browser mode.
If you need to parse through the content you can try some of the following:
For a managed code solution the proxy service you have already implemented is your best option.
Write a Java applet that returns this information. Silverlight can interopt to javascript which can interopt into Java applets. This also works in the reverse but a little difficult to setup. (If you need more info on this let me know).
Use javascript XmlHttpRequest to get the data you want from the source. This can be difficult when supporting multiple browsers. This link shows an example of how to do this (you will need to scroll down). Javascript get Html
Code:
var xmlHttpRequestHandler = new Object();
var requestObject;
xmlHttpRequestHandler.createXmlHttpRequest = function(){
var XmlHttpRequestObject;
if(typeof XMLHttpRequest != "undefined")
{
XmlHttpRequestObject = new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
var tryPossibleVersions =["MSXML2.XMLHttp.5.0", "MSXML2.XMLHttp.4.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp","Microsoft.XMLHttp"];
for(i=0;i<tryPossibleVersions.length;i++)
{
try
{
XmlHttpRequestObject = new ActiveXObject(tryPossibleVersions[i]);
break;
}
catch(xmlHttpRequestObjectError)
{
// Ignore Exception
}
}
}
return XmlHttpRequestObject;}
function getHtml(){
var url = document.getElementById('url').value;
if(url.length > 0)
{
requestObject = xmlHttpRequestHandler.createXmlHttpRequest();
requestObject.onreadystatechange=onReadyStateChangeResponse;
requestObject.open("Get",url, true);
requestObject.send(null);
}}
function onReadyStateChangeResponse(){
var ready, status;
try
{
ready = requestObject.readyState;
status = requestObject.status;
}
catch(e) {}
if(ready == 4 && status == 200)
{
alert(requestObject.responseText);
}}

Resources