在使用 MVC 5、Web API 2.0 和 EF Core 1.0 的 Azure 移动应用服务服务器端应用程序上,可以像这样装饰控制器以实现基于令牌的身份验证:
// Server-side EF Core 1.0 / Web API 2 REST API
[Authorize]
public class TodoItemController : TableController<TodoItem>
{
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
DomainManager = new EntityDomainManager<TodoItem>(context, Request);
}
// GET tables/TodoItem
public IQueryable<TodoItem> GetAllTodoItems()
{
return Query();
}
...
}
我希望能够在客户端做类似的事情,我用上面的 [Authorize] 之类的东西装饰一个方法,也许用下面的 [Secured] 装饰:
public class TodoItem
{
string id;
string name;
bool done;
[JsonProperty(PropertyName = "id")]
public string Id
{
get { return id; }
set { id = value;}
}
[JsonProperty(PropertyName = "text")]
public string Name
{
get { return name; }
set { name = value;}
}
[JsonProperty(PropertyName = "complete")]
public bool Done
{
get { return done; }
set { done = value;}
}
[Version]
public string Version { get; set; }
}
// Client side code calling GetAllTodoItems from above
[Secured]
public async Task<ObservableCollection<TodoItem>> GetTodoItemsAsync()
{
try
{
IEnumerable<TodoItem> items = await todoTable
.Where(todoItem => !todoItem.Done)
.ToEnumerableAsync();
return new ObservableCollection<TodoItem>(items);
}
catch (MobileServiceInvalidOperationException msioe)
{
Debug.WriteLine(@"Invalid sync operation: {0}", msioe.
}
catch (Exception e)
{
Debug.WriteLine(@"Sync error: {0}", e.Message);
}
return null;
}
其中 [Secured] 可能被定义为:
public class SecuredFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Check if user is logged in, if not, redirect to the login page.
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
// Check some globally accessible member to see if user is logged out.
}
}
不幸的是,上述代码仅适用于 MVC 1.0 应用程序及更高版本中的控制器,根据 Microsoft 关于“创建自定义操作过滤器”的文章: https://msdn.microsoft.com/en-us/library/dd381609(v=vs. 100).aspx
如何实现类似于“自定义操作过滤器”的功能,允许我在移动应用服务客户端而不是服务器中使用“[Secured]”装饰?答案将帮助我从客户端创建自定义身份验证并将代码保存在一个位置而不会使实现复杂化,即,它是一个横切关注点,如性能指标、重复尝试的自定义执行计划、日志记录等。
使场景复杂化的是,客户端还实现了适用于 iOS 的 Xamarin.Forms,并且由于 iOS 对本机代码的要求,它必须是功能性的 Ahead of Time 模式,JIT 尚不可能。