0

In my ASP.NET MVC 5 I use also AngularJS and my stateProvider contains also these nested states:

$stateProvider
.state("data",
{
    url: "/data",
    templateUrl: "Template/data",
    controller: "dataController"
})
.state("data.values",
{
    url: "/values",
    templateUrl: "Template/Values",
    controller: "valuesController"
})
.state("data.values.chart",
{
    url: "/chart",
    templateUrl: "Template/Chart",
    controller: "chartController"
})

On the BE side I use CookieAuthentication with the following settings:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Account/Login")
});

And an attribute to verify the user against a service

public class AuthorizeAdminUserMvcAttribute : System.Web.Mvc.AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var userService = DependencyResolver.Current.GetService<IUserService>();
        var authenticationManager = DependencyResolver.Current.GetService<IAuthenticationManager>();
        var currentUser = httpContext.User;
        if (string.IsNullOrEmpty(currentUser?.Identity?.Name) || userService.IsUserLockedOrMissing(currentUser?.Identity?.Name))
        {
            authenticationManager.SignOut();
            return false;
        }

        return true;
    }
} 

When I try to access /data/values/chart in the application, three requests are sent to the BE side

  • "Template/data"
  • "Template/Values"
  • "Template/Chart"

and for all three I get the same response: HTML code of the Login page with status 200.

To verify this behaviour I created an interceptor.

app.service("httpInterceptor", ["$q", function ($q) {
    return {
        'request': function (config) {
            // do something on success
            console.log(config);
            return config;
        },
        'requestError': function (rejection) {
            // do something on error
            console.log(rejection);
            return $q.reject(rejection);
        },
        'response': function (response) {
            // do something on success
            console.log(response);
            return response;
        },
        'responseError': function (rejection) {
            // do something on error
            console.log(rejection);
            return $q.reject(rejection);
        }
    };
}]);

There are two consequences, which I need to resolve:

  1. The url is https://localhost/#/data/values/chart, I need https://localhost/Account/Login
  2. Because the complete Login page is returned (including header), the new page seems to have two headers, I need just a single one enter image description here

Every help is highly appreciated.

1 Answer 1

0

At the end the solution was very easy - to move handling of 401 response completely from BE to FE, which means to

  • update BE Cookie settings
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    //LoginPath = new PathString("/Account/Login"), <- this line is commented out
});
  • create an interceptor handling 401 status on FE side, which redirects URL to Account/Login
portalApp.service("authInterceptor", ["$q", "$window", function ($q, $window) {
    this.responseError = function (response) {
        if (response.status === 401) {
            $window.location.href = "account/login";
            return;
        }
        return $q.reject(response);
    }
}]);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.