我正在构建一个可以在 Web 和 JQuery 移动设备中运行的 ASP.Net MVC 应用程序。所以我正在为 Web 和 JQuery 移动应用程序创建一个单独的视图。我已将所有主要业务逻辑服务作为 Web Api 调用,由两个客户端使用 AngularJs 调用,到目前为止运行良好。
现在我希望将安全性引入应用程序,并意识到基本身份验证是最快的方法,当我环顾四周时,我发现了非常好的帖子,帮助我以最小的努力构建了相同的。以下是我主要使用的 3 个链接:
对于客户端
- HTTP Auth Interceptor Module :寻找 401 错误并打开登录页面的好方法,然后从您遗漏的地方继续。
- 在 AngularJS 中为 HTTP 请求实现基本 HTTP 身份验证:这是确保我能够在后续请求中重用用户凭据所必需的。这是在 $http 中捕获的。
在服务器端:
到目前为止一切顺利,我所有的 WebApi 调用都按预期工作,
但是当我必须调用 MVC 控制器时,问题就开始了,
如果我尝试[Authorize]
使用方法/控制器,即使 API 已经设置了身份验证标头,它也会在 MVC 上再次抛出表单身份验证视图。
所以我有2个问题:
我们可以让 WebApi 和 MVC 在标头中共享相同的数据吗?在 AngularJS 中有一种方法,我可以进行 MVC 控制器调用,该调用可以使用$http中设置的授权块传递相同的标头信息,并在服务器端对其进行解码以生成我自己的身份验证并设置自定义。
如果上述情况不可行,我试图调用 WebApi 控制器以重定向到正确的视图,然后使用一堆 WebApi 调用加载数据,这样就不会要求用户再次输入详细信息。
我用以下属性“ [ActionName("MyWorkspace")] [HttpGet]
”装饰了它
public HttpResponseMessage GotoMyWorkspace(string data)
{
var redirectUrl = "/";
if (System.Threading.Thread.CurrentPrincipal.IsInRole("shipper"))
{
redirectUrl = "/shipper";
}
else if (System.Threading.Thread.CurrentPrincipal.IsInRole("transporter"))
{
redirectUrl = "/transporter";
}
var response = Request.CreateResponse(HttpStatusCode.MovedPermanently);
string fullyQualifiedUrl = redirectUrl;
response.Headers.Location = new Uri(fullyQualifiedUrl, UriKind.Relative);
return response;
}
并且在我的点击中我调用了一个角度 JS 函数
$scope.enterWorkspace = function(){
$http.get('/api/execute/Registration/MyWorkspace?data=""')
.then(
// success callback
function(response) {
console.log('redirect Route Received:', response);
},
// error callback
function(response) {
console.log('Error retrieving the Redirect path:',response);
}
);
}
我在 chrome 开发人员工具中看到它被重定向并获得 200 OK 状态,但视图未刷新。
如果无法共享 WebApi 和 MVC 身份验证,我们有什么办法至少可以让这个重定向工作。
编辑
遵循 Kaido 的建议,发现另一个博客解释了如何创建自定义 CustomBasicAuthorizeAttribute。
现在我可以在下面的 Home 控制器上调用该方法: 用 '[HttpPost][CustomBasicAuthorize]' 装饰
public ActionResult MyWorkspace()
{
var redirectUrl = "/";
if (System.Threading.Thread.CurrentPrincipal.IsInRole("shipper"))
{
redirectUrl = "/shipper/";
}
else if(System.Threading.Thread.CurrentPrincipal.IsInRole("transporter"))
{
redirectUrl = "/transporter/";
}
return RedirectToLocal(redirectUrl);
}
同样,它在一定程度上起作用,也就是说,当第一次调用时,它会进入我上面的重定向方法,但是当重定向调用返回时,它再次丢失了标题!
我能做些什么来确保重定向的呼叫也获得正确的标头集吗?
顺便说一句,现在我的菜单点击如下所示:
$scope.enterMyWorkspace = function(){
$http.post('/Home/MyWorkspace')
.then(
// success callback
function(response) {
console.log('redirect Route Received:', response);
},
// error callback
function(response) {
console.log('Error retrieving the Redirect path:',response);
}
);
}
这最终解决了以下 URL:http://127.0.0.1:81/Account/Login?ReturnUrl=%2fshipper%2f
问候基兰