None
None

Reputation: 5670

Show views based on authentication status in asp.net mvc

If user is logged in I want to show my department view, if not logged in want to show login page. I have tried something like this inside my RouteConfig

  public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
          if (HttpContext.Current.User==null)
        {
            routes.MapRoute(
              name: "Default",
              url: "{controller}/{action}/{id}",
              defaults: new { controller = "Account", action = "Login", id = UrlParameter.Optional }
                );
        }
        else
        {
            routes.MapRoute(
             name: "Default",
             url: "{controller}/{action}/{id}",
             defaults: new { controller = "Department", action = "Index", id = UrlParameter.Optional }
               );
        }

    }

But this one always loads login page at startup.Can anyone point out what I am doing wrong here? Note: I am using Asp.net Identity for this application

Upvotes: 3

Views: 2690

Answers (3)

Alex
Alex

Reputation: 38529

Your HttpContext.Current.User==null logic would go in the controller, not your route registration

Note- the correct call is Request.IsAuthenticated

Assuming you have an action method like this:

public ViewResult Index()
{
  if(Request.IsAuthenticated)
    return new RedirectResult("toLoginPage")
  else
    return new View("loggedInView");
}

However, I believe the [Authorize] attribute could be what you want in your use case: (note - having re-read the question, this may not be accurate, as you want to return a different view based on login status)

[Authorize]
public ViewResult ShowPerson(int id)
{
    return new View("loggedInView");
}

And in your web.config, something like

<system.web>
<authentication mode="Forms">
  <forms loginUrl="~/Account/Login" />
</authentication>
</system.web>

In this particular instance, with the [Authorize] attribute above the action method, if the user is not logged in, they'd be redirected to log in.

Upvotes: 6

George Polevoy
George Polevoy

Reputation: 7681

You can achieve this with route constraints:

public class DelegateConstraint : IRouteConstraint
{
    private readonly Func<HttpContextBase, bool> _isMatch;

    public DelegateConstraint(Func<HttpContextBase, bool> isMatch)
    {
        _isMatch = isMatch;
    }

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        return _isMatch(httpContext);
    }
}

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "CustomAuth1",
            url: "AuthArea/{action}/{id}",
            defaults: new { controller = "Department", action = "Index", id = UrlParameter.Optional },
            constraints: new { auth = new DelegateConstraint(httpContext => !httpContext.Request.IsAuthenticated) }
            );

        routes.MapRoute(
            name: "CustomAuth2",
            url: "AuthArea/{action}/{id}",
            defaults: new { controller = "Account", action = "Index", id = UrlParameter.Optional },
            constraints: new { auth = new DelegateConstraint(httpContext => httpContext.Request.IsAuthenticated) }
            );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

In this example the ~/AuthArea url will be resolved by Account or Department controller depending on the Request.IsAuthenticated property.

UPDATE: This way you get a complete routing capability, but still need to specify the correct controller:

@Html.ActionLink("Context dependent link", "Index", @Request.IsAuthenticated ? "Account" : "Department")

This link would always be rendered as:

<a href="/AuthArea">Context dependent link</a>

Upvotes: 2

nik0lai
nik0lai

Reputation: 2655

Create your own Authorization attribute:

public class CustomAuthorize: AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if(filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
        else
        {
            filterContext.Result = new RedirectToRouteResult(new
            RouteValueDictionary(new{ controller = "Error", action = "AccessDenied" }));
        }
    }
}

Then add [CustomAuthorize] to your controller and change the route it points to.

This was taken from here

Upvotes: 2

Related Questions