1)
I am using MVC Form Authentication to manage my application
2)
In client Angular is being used , so I am using
$http service heavily from all pages
3)
Redirection URL for Unauthorized user is defined
in config file in which is tradition way of implantation.
So, this is my implantation and my problem starts here. When
user’s session is time out ASP.NET redirects user to particular page which I
have defined in config file in Form Authentication tag. When user is posting
back that’s working as expectd.
But when It’s AJAX call using $http service in Angular ,ASP.NET
is processing the login page and returning with 200 status when user is not
authenticated.
That’s the root cause of problem. Success callback of $http
service is taking this as good response and showing content of login page in
client.
If user is not authenticated when we should expect 401
rather than 200 in client If this is an AJAX call. I did little Search in
Google and tried to intercept the HTTP request but no luck which worked fine
with $.ajax of JQury.
Please let me know If
you have code to check 401 when Form Authentication is in server and AngularJS $http
is in client by using HTTP interceptor.
So, I have implanted this in little different way and I believe
this is not much hacky J
. If you have better suggesting, please let me know.
First of all I have implanted
custom Authorization filter where I am checking whether the call is AJAX call
or not?
public class myAuthorization : System.Web.Mvc.AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
{
base.HandleUnauthorizedRequest(filterContext);
}
else
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = 401;
filterContext.HttpContext.Response.End();
}
}
base.OnAuthorization(filterContext);
}
}
Action is decorated with custom authentication
filter
[myAuthorization]
public string Data()
{
return "data";
}
In angular module I am detecting 401 response using
Intercptor.
var app = angular.module("myApp", [])
.factory('authHttpResponseInterceptor',['$q','$location',function($q,$location){
return {
response: function (response) {
if (response.status === 401) {
}
return response ||
$q.when(response);
},
responseError: function(rejection) {
if (rejection.status === 401) {
console.log("Response Error 401",rejection);
$location.path('/login').search('returnTo', $location.path());
}
return
$q.reject(rejection);
}
}
}]).
Here
is code to set header to know ASP.NET that this call is AJAX call
config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.headers.common["X-Requested-With"]
= 'XMLHttpRequest';
}])
It’s
time topush the interceptor in $httpProvider service.
.config(['$httpProvider',function($httpProvider) {
$httpProvider.interceptors.push('authHttpResponseInterceptor');
}]);
At last controller is to make AJAX in $http call.
app.controller("myController", function ($http, $scope) {
$http({ method: 'GET', url: '/Home/Data' }).
success(function (data, status,
headers, config) {
alert(data);
});
});
And the problem solved.
Now If user post back then Form authentication will return
page from server and If user make AJAX call then custom authentication filter
will end response with 401 status code and Angular’s interceptor will handle
the response.
No comments:
Post a Comment