nara
nara

Reputation: 21

Authentication.Challenge not working with ApiController

With ApiController, Authentication.Challenge not prompting Microsoft login for SSO. it executes SignIn action method, with out any errors. If I change from ApiController to Controller then it's prompting. does any one know how to prompt for Microsoft login using ApiController?

public class ValuesController : ApiController
{
    [System.Web.Http.Route("api/values/signin")]
    [System.Web.Http.HttpGet]
    public void SignIn()
    {
        if (!System.Web.HttpContext.Current.Request.IsAuthenticated)
        {
            HttpContext.Current.GetOwinContext().Authentication.Challenge(
                new AuthenticationProperties { RedirectUri = "/" },
                OpenIdConnectAuthenticationDefaults.AuthenticationType);
        }
    }
}  


public class ValuesController : Controller
{
    public void SignIn()
    {
        if (!System.Web.HttpContext.Current.Request.IsAuthenticated)
        {
            HttpContext.Current.GetOwinContext().Authentication.Challenge(
                new AuthenticationProperties { RedirectUri = "/" },
                OpenIdConnectAuthenticationDefaults.AuthenticationType);
        }
    }
}  

Upvotes: 2

Views: 1972

Answers (1)

Alexander Lysenko
Alexander Lysenko

Reputation: 166

We also faced a similar problem on our product.

The issue was the following: Challenge sets 401 status code for current response, which is later handled by a responsible OWIN Middleware, so if status code is not 401 the middleware won't handle the response and won't trigger the redirect.

But the default behavior of void action of ApiController sets 204 response status code. Therefore 401 is overwritten with 204, as a result nothing happens.

So there are several solutions:

  1. Don't use ApiController if you can
  2. Use ApiController but not void action. Use for example something like this
public ActionResult SignIn()
{
    HttpContext.Current.GetOwinContext().Authentication.Challenge(...);
    return new HttpStatusCodeResult(HttpContext.GetOwinContext().Response.StatusCode);
}
  1. If you have to use a void method and ApiController then you can end the response and then the status code won't be modified.
public void SignIn()
{
    HttpContext.Current.GetOwinContext().Authentication.Challenge(...);
    System.Web.HttpContext.Current.Response.End();
}

Upvotes: 0

Related Questions