2010-03-30 48 views
1

这可能吗?从应用程序外调用正在使用ASP.NET MVC [Authorize]的动作

我想公开一个URL(动作),如http://mysever/myapp/UpdateHeartbeat/

在我的MVC应用程序,它看起来像

[Authorize] 
[AcceptsVerbs(HttpVerbs.Post)] 
public ActionResult UpdateHeartbeat() 
{ 
    // update date in DB to DateTime.Now 
} 

现在,在我的MVC应用程序的用户通过窗体身份验证登录,他们可以执行行动,他们的心的内容。

我想做什么,是从控制台应用程序中击中URL,并且能够进行身份验证(作为我希望构建的API的一部分) - 有没有一种方法可以在不移除[授权]属性并将用户名/密码作为参数添加到POST?

回答

0

Authorize过滤器实际上从当前上下文获取用户的IPrincipal,所以这是不可能的。您需要为该方法提供另一种形式的身份验证。

快速谷歌搜索提供了一个链接到下面的博客贴子,可能是有用的:

http://davidhayden.com/blog/dave/archive/2009/04/09/CustomAuthorizationASPNETMVCFrameworkAuthorizeAttribute.aspx

+0

所以,我会再使用基本的HTTP认证(通过HTTPS/SSL明显),并检查在覆盖这些凭据' AuthorizeCore();'方法?? – Nate 2010-03-30 19:42:15

+0

当然。你正在编写覆盖的逻辑,所以你可以做任何你想让它返回true或false的东西。 – 2010-03-30 20:05:53

+0

我知道,我想我的问题是,这样做有什么意义,我可能不知道?它安全吗?假设URI是HTTPs和ssl加密的,那么凭证是否也加密? – Nate 2010-03-30 20:11:39

2

相信这是可能的。这一直在单元测试中完成。我个人使用RhinoMocksMVCContrib.TestHelper来调用我的控制器动作,既有身份验证又没有身份验证。这里是一个代码示例一块,我用它来测试我的控制器:

private MockRepository _mocks = new MockRepository(); 

    public ControllerTestBase() 
    { 
    } 

    public static T GetController<T>() 
    { 
     return this.GetController<T>(null); 
    } 

    public T GetController<T>(BPUser authenticatedUser) 
    {    
     TestControllerBuilder testContBuilder = new TestControllerBuilder(); 

     if (authenticatedUser != null) 
     {    
      var identity = _mocks.DynamicMock<IIdentity>();     

      SetupResult.For(identity.IsAuthenticated).Return(true); 
      SetupResult.For(identity.Name).Return(authenticatedUser.ID.ToString()); 
      _mocks.Replay(identity); 

      var pAttrs = new System.Collections.Hashtable(); 
      pAttrs["UserID"] = authenticatedUser.ID.ToString(); 
      pAttrs["UserName"] = authenticatedUser.UserName; 
      testContBuilder.HttpContext.User = new UserPrinciple(identity, new string[] { }, pAttrs); 
     } 

     return testContBuilder.CreateController<T>(); 
    } 

书中有我的执行IPrinciple有点定制的东西,但我希望这是一个开始。

编辑 - 使用示例 这里是你将如何使用这个:

var authenticatedUser = SomeCodeToGetMyUser(); 
var controller = ControllerTestBase.GetController<YourController>(authenticatedUser); 
controller.UpdateHeartbeat(); 
+0

这不是用于测试,这是为了构建一个将被非.NET客户端访问的API,但它仍然需要安全。 – Nate 2010-03-30 19:54:47

+0

我明白这一点。但是,相同的原则适用于您要求调用需要表单身份验证的控制器操作。此代码嘲笑表单身份验证。您仍然有能力通过您的API以任何方式对用户进行身份验证,然后传入“已通过身份验证”的用户身份。 – Luke 2010-03-30 20:00:38

+0

对不起,我错过了你提到的有关添加用户名/密码作为帖子一部分的部分。如果是这种情况,我会亲自创建一个单独的操作,将用户名/密码作为参数,进行身份验证,然后重定向到UpdateHeartbeat()操作。 – Luke 2010-03-30 20:05:49

相关问题