最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

AngularJs + ASP.NET MVC 5 - Handle BE redirection (HTTP code 302) - Stack Overflow

programmeradmin2浏览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

Every help is highly appreciated.

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

Every help is highly appreciated.

Share Improve this question asked Mar 17 at 16:06 FrimlikFrimlik 4497 silver badges20 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 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);
    }
}]);
发布评论

评论列表(0)

  1. 暂无评论