0

When I first started developing my MVC app (which requires authorization, to selectively render a SPA, which in turn does it's own authorization via ADAL.js) I simply decorated the HomeController's Index method with [Authorize] like thus,

    [Authorize]
    public ActionResult Index(bool ok = false)
    {
        return View();
    }

and everything works fine.

However, sometimes I want users to share URLs with each other. My SPA uses hash-based routing to render various states. As long as both users are logged in already, they can share links with each other and everything magically works ok.

But, if the user clicking a link is yet-to-login, we lose the state communicated in the URL.. everything after the hash.. e.g. if user A sends unauthenticated user B this URL: http://mycorp.com/#/orders/85/edit the HomeController's going to notice user B is unauthenticated, and the middleware is going to kick user B over to our Microsoft login page.. and when he redirects back, the critical #/orders/85/edit portion of the URL in is gone.

My solution was to remove the [Authorize] attribute from the Index action, and instead do something like this:

 public ActionResult Index(bool ok=false)
 {
     if (!User.Identity.IsAuthenticated)
     {
         if (!ok)
             return View("SetCookie_Then_RedirectWith_OK_InQueryString");
         if (ok)
             //how do I do this part?
             return new RedirectResult(Microsoft.Owin.Security.OpenIdConnect.Url);
     }
     else
         //now we're authenticated, 
         //let JS resume by looking for cookie set previously
         return View("Index");
 }

Notice the how do I do this part comment above. That's my question.

+++++++++ FWIW ++++++++++

My app features a Startup.Auth.cs file with the familiar middleware declared...

        app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions
            {
             ...blah...
            }
        );

I presume I can do something fancy here in Startup.Auth.cs w/Notification Handlers but, I was hoping to directly call the middleware into action from the Index method.

bkwdesign
  • 1,953
  • 2
  • 28
  • 50
  • Since you're using hash-based routing, am I correct in assuming you're using Angular 1.x? If so, would you be open to using html5Mode routing? Check out: https://scotch.io/quick-tips/pretty-urls-in-angularjs-removing-the-hashtag This would remove the hash and therefore your redirect would be what you're looking for – brandon-barnett Aug 25 '17 at 17:48
  • My SPA is fairly home grown.. I'm using [Flatiron's Director](https://github.com/flatiron/director) for routing – bkwdesign Aug 25 '17 at 17:50
  • Have you tried using HTML5 History API from Director? https://github.com/flatiron/director#history-api Wonder if that would solve your issue...primarily I just don't think you want the hash routing if you're attempting to do anything server-side – brandon-barnett Aug 28 '17 at 17:55
  • Another option - I *think* if I remember correctly, if you return a 403 result, Owin will kick in automatically to do the authentication. If I'm remembering enough MVC, that'd just be `return StatusCode(403);`. – Jonathan Rupp Aug 28 '17 at 18:18

0 Answers0