2012-06-11 26 views
2

我试图在我的MVC应用程序中提供iCalendar文件(.ics)。在ASPNET MVC中使用身份验证服务iCalendar文件

到目前为止它工作正常。我有一个iPhone订阅日历的URL,但现在我需要为每个用户提供个性化日历。

订阅iPhone上的日历时,我可以输入用户名和密码,但我不知道如何在我的MVC应用程序中访问这些日历。

我在哪里可以找到身份验证如何工作以及如何实现的详细信息?

回答

2

事实证明,基本认证是必需的。我有一半工作,但我的IIS配置阻碍了。所以,当没有授权标题时,仅仅返回401响应会导致客户端(例如iPhone)需要用户名/密码来订阅日历。

在有授权请求头的请求的授权中,可以处理基本认证,从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"); 
} 
0

我发现这真的帮助很大,但我在开发过程中打了几个问题和我想我会分享他们中的一些来帮助拯救其他人一段时间。

我正在寻找从我的web应用程序中获取数据到Android设备的日历中,并且我使用的是discountasp作为托管服务。

我碰到的第一个问题是验证在上传到服务器时无法正常工作,足够接受我的控制面板登录为discountasp而不是我的表单登录。

答案是关闭IIS管理器中的基本身份验证。这解决了这个问题。

其次,我用来将日历同步到android设备的应用程序被称为iCalSync2 - 它是一个不错的应用程序,运行良好。但我发现只有当文件以.ics格式(因为某些原因,我把它作为一个.ical ..它一定是迟了)交付文件才能正常工作,而且我还必须选择webcal选项

最后,我发现我必须添加webcal://,而不是http://

也要小心,因为上面的代码忽略了输入变量的角色,并且始终没有通过任何内容,因此您可能需要执行日历例程中的一些基于角色的检查或修改上面的代码以处理角色变量。