Developer forum

Forum » Development » ExtranetLogin throws exception: Thread was being aborted

ExtranetLogin throws exception: Thread was being aborted

Theis Nickelsen
Reply

Hi, 

I'm trying to login. To do this I'm using the following code, which throws an exception:

   Dynamicweb.Security sec = new Dynamicweb.Security();
   sec.ExtranetLogin(username, password, true);

Exception: 

   Thread was being aborted.

Stacktrace:

      at System.Threading.Thread.AbortInternal()
   at System.Threading.Thread.Abort(Object stateInfo)
   at --------.Classes.Login.OnExtranetLoginObserver.OnNotify(String notification, NotificationArgs args) in C:\Repositories\--------\--------.Web\Classes\Login\OnExtranetLoginObserver.cs:line 21
   at Dynamicweb.Extensibility.NotificationManager.Notify(String notification, Object[] args)
   at Dynamicweb.Extensibility.NotificationManager.Notify(String notification, Object eventArgs)
   at Dynamicweb.Security.ExtranetLogin(String username, String password, Boolean onlyActive, Boolean impersonateUser, Int32 impersonateUserID, Boolean loginIfPwdEncrypted)
   at Dynamicweb.Security.ExtranetLogin(String username, String password, Boolean onlyActive)
   at ----------.SingleSignOn.Security.Authentication.Login(String username, String password) in C:\Repositories\---------\----------.SingleSignOn\Security\Authentication.cs:line 14


Dynamicweb version: 8.9.2.6

What am I doing wrong?

Thanks,

Theis


Replies

 
Nicolai Pedersen
Reply

Can we see your entire code?

System.Threading.Thread.Abort is usually thrown when a redirect happens. So you might have a redirect in your code or you try to login a user that has a redirect set on him. A user can have a "page after login" set somewhere - or the page he logs into, have a redirect set. So take a look the response header on the login action and see what that can be.

BR Nicolai

 
Theis Nickelsen
Reply

The entire code is long but besically what happends is that I have an AuthenticationHandler, which creates and persists token for SSO, which, at the end, redirects to login with a tokenId as parameter. The LoginHandler then login by loading the token and calling the above code. So a redirect does happend. 

Is there anyway to unset redirct on the user from the LoginHandler?

 
Nicolai Pedersen
Reply

Hi Theis

Not sure I understand your last question...

If you do a post to the login page of Dynamicweb and send ?redirect=false, the Dynamicweb login procedure will not do a redirect. If your own code makes a redirect, it will of course still do that.

 
Theis Nickelsen
Reply

Here is some more code:
 

public class AuthenticationHttpHandler : IHttpHandler, IRequiresSessionState
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.Clear();

            // dynamicweb 9 requires page view to access LoginHandler
            // check if has page view
            new PageView().Load();

            // determine api key based on endpoint
            var partnerName = context.Request.QueryString["partner"];

            var resolver = new AuthenticationHandlerResolver();
            var handler = resolver.Get(context, partnerName);
            var response = handler.Resolve(context);

            if (response.Code == (int) ResponseCode.REDIRECT && handler.Type == HandlerType.OCI)
            {
                context.Response.Redirect(response.Message);

            } else if (response.Code != (int)ResponseCode.OK)
            {
                context.Response.TrySkipIisCustomErrors = true;
            }
            context.Response.ContentType = response.ContentType;
            context.Response.StatusCode = response.Code;
            context.Response.Write(response.Message);
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }

 

In handler.Resolve(context); we do:


                        var tokenCreated = tokenService.Create(token);

                        // return xml response
                        if (tokenCreated)
                        {
                            var loginUrl = this.GetLoginUrl(tokenGuid);
                            response = GenericResponse.Redirect(loginUrl);
                        }

 

Which redirects to here:

    public class LoginHttpHandler : IHttpHandler, IRequiresSessionState
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.Clear();

            // dynamicweb 9 requires page view to access LoginHandler
            // check if has page view
            new PageView().Load();
            
            var resolver = new LoginHandlerResolver();
            var handler = resolver.Get(context);
            var response = handler.Resolve(context);

            if (response.Code == (int)ResponseCode.REDIRECT)
            {
                context.Response.RedirectLocation = response.Message;
            }
            else if (response.Code != (int)ResponseCode.OK)
            {
                context.Response.TrySkipIisCustomErrors = true;
            }

            context.Response.ContentType = response.ContentType;
            context.Response.StatusCode = response.Code;
            context.Response.Write(response.Message);
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }

In handler.Resolve(context); Login is called (which is where the exception occurs):

 public static bool Login(string username, string password)
        {
            try
            {
                Dynamicweb.Security _sec = new Dynamicweb.Security();
                _sec.ExtranetLogin(username, password, true);

                return _sec.UserLoggedIn;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

 

I understand you can set redirects on the user from the /Admin entrance of DynamicWeb but that is not the redirects you are referring to here, right? From what I understand from what you write, the exception occurs because Dynamicweb detects a redirect from Auth to Login before the login attempt. Correct? 

How do I solve this and still have that redirect from Auth to Login?
We got this working on a different solution.

 
Nicolai Pedersen
Reply

Hi Theis

Response.Redirect in System.Web will throw a ThreadAbortedException when you do the redirect. See this: https://stackoverflow.com/questions/2777105/why-response-redirect-causes-system-threading-threadabortexception

So it is not Dynamicweb that does anything - it is your own code when you do the redirect. Maybe inside your GenericResponse class?

BR Nicolai

 
Theis Nickelsen
Reply

But it's Dynamicweb that throws the exception when trying to log in? So Dynamicweb loses the context after the redirect or what happends?

Here's the GenericResponse class:

 

 public enum ResponseCode
    {
        OK = 200,
        NOTFOUND = 404,
        BADREQUEST = 400,
        FAILURE = 500,
        REDIRECT = 302
    }

    public class GenericResponse : IGenericResponse
    {
        public ResponseCode ResponseCode { get; set; }
        public int Code
        {
            get
            {
                return Convert.ToInt32(ResponseCode);
            }
        }

        public string ContentType { get; set; }

        public string Message { get; set; }

        public static IGenericResponse Success(string message)
        {
            return new GenericResponse()
            {
                Message = message,
                ResponseCode = ResponseCode.OK
            };
        }
        public static IGenericResponse BadRequest(string message)
        {
            return new GenericResponse()
            {
                Message = message,
                ResponseCode = ResponseCode.BADREQUEST
            };
        }
        public static IGenericResponse NotFound(string message)
        {
            return new GenericResponse()
            {
                Message = message,
                ResponseCode = ResponseCode.NOTFOUND
            };
        }
        public static IGenericResponse Failure(string message)
        {
            return new GenericResponse()
            {
                Message = message,
                ResponseCode = ResponseCode.FAILURE
            };
        }
        public static IGenericResponse Redirect(string location)
        {
            return new GenericResponse()
            {
                Message = location,
                ResponseCode = ResponseCode.REDIRECT
            };
        }

    }

 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply

Hi all,

Sorry for getting in the middle of this, but I'd be interested in knowing what's on line 14 of Authentication.cs and line 21 in OnExtranetLoginObserver.cs.

From what I can tell from the stacktrace, your call to Security.ExtranetLogin happens in Authentication.cs on line 14. But you also have a NotificationSubscriber, OnExtranetLoginObserver, which actually throws the exception on line 21.

- Jeppe

 
Theis Nickelsen
Reply

Yes, ExtranetLogin happends on Authentication.cs line 14. Here is the code for OnExtranetLoginObserver (line 21 is the last line):
 

[Dynamicweb.Extensibility.Subscribe(Dynamicweb.Notifications.Standard.User.OnExtranetLogin)]
    public class OnExtranetLoginObserver : Dynamicweb.Extensibility.NotificationSubscriber
    {
        public override void OnNotify(string notification, Dynamicweb.Extensibility.NotificationArgs args)
        {
            if (args == null)
                return;

            if (!(args is Dynamicweb.Notifications.Standard.User.OnExtranetLoginArgs))
                return;

            Dynamicweb.Notifications.Standard.User.OnExtranetLoginArgs item = (Dynamicweb.Notifications.Standard.User.OnExtranetLoginArgs)args;
            var currentQuery = HttpContext.Current.Request.Url.Query;
            HttpContext.Current.Response.Redirect(currentQuery != ""
                ? HttpContext.Current.Request.Url.AbsoluteUri.Replace(currentQuery, String.Empty)
                : HttpContext.Current.Request.Url.AbsoluteUri);
        }
    }

 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply

Hi Theis,

That's it. On line 21, you have a Response.Redirect. That's the cause of the ThreadAbortException. As Nicolai pointed out earlier in the thread, Response.Redirect will throw a ThreadAbortException by design.

- Jeppe

 
Theis Nickelsen
Reply

Hi Jeppe,

Thanks - that was the issue. Old unrelated code written by someone else :) 

Thank you for your help.

Theis

 

You must be logged in to post in the forum