我正在尝试在我的 MVC 应用程序中提供 iCalendar 文件 (.ics)。
到目前为止,它工作正常。我有一部 iPhone 订阅了日历的 URL,但现在我需要为每个用户提供个性化的日历。
在 iPhone 上订阅日历时,我可以输入用户名和密码,但我不知道如何在我的 MVC 应用程序中访问它们。
我在哪里可以找到有关身份验证如何工作以及如何实施的详细信息?
我正在尝试在我的 MVC 应用程序中提供 iCalendar 文件 (.ics)。
到目前为止,它工作正常。我有一部 iPhone 订阅了日历的 URL,但现在我需要为每个用户提供个性化的日历。
在 iPhone 上订阅日历时,我可以输入用户名和密码,但我不知道如何在我的 MVC 应用程序中访问它们。
我在哪里可以找到有关身份验证如何工作以及如何实施的详细信息?
事实证明,基本身份验证是必需的。我有一半的工作,但我的 IIS 配置妨碍了。因此,在没有 Authorization 标头时简单地返回 401 响应会导致客户端(例如 iPhone)需要用户名/密码来订阅日历。
在有 Authorization 请求标头的请求的授权上,可以处理基本身份验证,从 base 64 编码字符串中检索用户名和密码。
下面是一些对 MVC 有用的代码:
public class BasicAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
var auth = filterContext.HttpContext.Request.Headers["Authorization"];
if (!String.IsNullOrEmpty(auth))
{
var encodedDataAsBytes = Convert.FromBase64String(auth.Replace("Basic ", ""));
var value = Encoding.ASCII.GetString(encodedDataAsBytes);
var username = value.Substring(0, value.IndexOf(':'));
var password = value.Substring(value.IndexOf(':') + 1);
if (MembershipService.ValidateUser(username, password))
{
filterContext.HttpContext.User = new GenericPrincipal(new GenericIdentity(username), null);
}
else
{
filterContext.Result = new HttpStatusCodeResult(401);
}
}
else
{
if (AuthorizeCore(filterContext.HttpContext))
{
var cachePolicy = filterContext.HttpContext.Response.Cache;
cachePolicy.SetProxyMaxAge(new TimeSpan(0));
cachePolicy.AddValidationCallback(CacheValidateHandler, null);
}
else
{
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusDescription = "Unauthorized";
filterContext.HttpContext.Response.AddHeader("WWW-Authenticate", "Basic realm=\"Secure Calendar\"");
filterContext.HttpContext.Response.Write("401, please authenticate");
filterContext.HttpContext.Response.StatusCode = 401;
filterContext.Result = new EmptyResult();
filterContext.HttpContext.Response.End();
}
}
}
private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
{
validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
}
}
然后,我的控制器操作如下所示:
[BasicAuthorize]
public ActionResult Calendar()
{
var userName = HttpContext.User.Identity.Name;
var appointments = GetAppointments(userName);
return new CalendarResult(appointments, "Appointments.ics");
}
我发现这真的很有帮助,但是我在开发过程中遇到了一些问题,我想我会分享其中的一些来帮助其他人节省一些时间。
我正在寻找从我的 web 应用程序获取数据到 android 设备的日历中,并且我正在使用 discountasp 作为托管服务。
我遇到的第一个问题是验证在上传到服务器时不起作用,奇怪的是它接受了我的控制面板登录为 discountasp,但不接受我的表单登录。
对此的答案是关闭 IIS 管理器中的基本身份验证。这解决了这个问题。
其次,我用来将日历同步到 android 设备的应用程序称为 iCalSync2 - 它是一个不错的应用程序,并且运行良好。但是我发现它只有在文件作为 .ics 交付时才能正常工作(出于某种原因,我把它作为 .ical .. 它一定是迟到了)而且我还必须选择 webcal 选项
最后我发现我必须在我的网址的开头添加 webcal:// 而不是 http://
还要小心,因为上面发布的代码忽略了角色输入变量并且始终不传递任何内容,因此您可能需要在日历例程中进行一些基于角色的检查,或者修改上面的代码以处理角色变量。