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
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:
https://localhost/#/data/values/chart
, I need https://localhost/Account/Login
Every help is highly appreciated.
At the end the solution was very easy - to move handling of 401 response completely from BE to FE, which means to
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
//LoginPath = new PathString("/Account/Login"), <- this line is commented out
});
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);
}
}]);