Search code examples
asp.net-mvcfederated-identitywif

Handle WIF SignInResponseMessage (Post) when user requests action method with both [HttpGet] & [HttpPost] overloads]


I thought the solution to this would occur to me as I've sat on this problem for many months - but my brain has not flags the obvious best approach.

I have two controller methods say "Edit" that are protected with an action filter that causes passive authentication to an STS.

[HttpGet]
public ActionResult Edit(Guid id) { [do stuff] }

[HttpPost]
public ActionResult Edit(Guid id, EditViewModel model) { [do stuff] }

The problem is, mvc receives the SignInResponseMessage and then fires the HttpPost which is not what I want... Anyone out there approached this issue and feel they've got a nice solution?

I guess I could uniquely name all my action methods if worst comes to worse i.e. the good old mvc1 Edit() vs Update() / New() vs Create() etc..


Solution

  • I have a solution...

    Instead of allowing the STS to post to any url (and hit any action in the application), I use a setting in my STS to post to one url which has an action method that looks like this:

    public ActionResult Index() {
    
        if (MyIdentity.IsAuthenticated) {
            if (ControllerContext.HttpContext.Request["wreply"] != null)
            {
                var returnUrl = ControllerContext.HttpContext.Request["wreply"];
                if (returnUrl.StartsWith(Stgs.WebRt)) { return Redirect(returnUrl); } //make sure the wreply is actually for this application and not a random url
            }
    
            return Redirect("/"); 
        }
    
        return View(); 
    }
    

    Then in the STS when I'm building the SignOutResponseMessage I add the line:

    response.SetParameter("wreply", message.Reply);
    

    where "reponse" is a Microsoft.IdentityModel.Protocols.WSFederation.SignInReponseMessage and "message" is a is a Microsoft.IdentityModel.Protocols.WSFederation.SignInRequestMessage. This basically adds the wreply as a form input that is posted to the relying party. Hence making the controller action code above work as expected.