使用ASP.NET Web API并排进行基本和表单身份validation

免责声明:首先我要说的是我对MVC4 + Web Api + Web服务+ JQuery的新手。 我可能会以错误的角度攻击这个。

我正在尝试使用C#for .NET 4构建Web MVC App + Web API以在Azure中部署。 web api将由移动客户端(iOS,使用RestKit)使用。

Web MVC应用程序将相对简单。 我们想使用Forms Authentication和SimpleMembership – 我们已经实现并且工作正常。

我们将使用JQuery(Knockout)脚本中的Web API方法来填充网页的各个部分。 因此,我们希望JQuery使用由Forms Authenticationvalidation的相同身份。

但是,我们的想法是Web Api可以由移动客户端直接调用。 没有表格认证。

我们一直在研究Thinktecture身份模型( http://nuget.org/packages/Thinktecture.IdentityModel https://github.com/thinktecture/Thinktecture.IdentityModel.40 )。 我们将BasicAuth和AcessKey处理程序添加到配置中并且它可以工作(请参阅下面的代码)。

当您尝试访问webapi而未经过身份validation时,浏览器将显示基本身份validation对话框并按预期工作。

“问题”是,当您已经通过表单身份validation登录并尝试调用Web Api方法时,您仍然可以获得“基本身份validation”对话框。 换句话说,Thinktecture IdentityModel似乎完全忽略了Forms身份validation。

我的问题是:

  1. 我的期望是否正确? 一旦我完成了表单身份validation,我就不应该做任何其他事情让JQuery脚本等从同一个浏览器用户会话访问Web API。
  2. 我如何解决它?
  3. 如果我的期望不正确; 这应该怎么样? 即:如何使JQuery脚本进行身份validation?

我知道在Stackoverflow中有很多类似的问题,我老实地看了很多,看过video等,但要么我缺少一些明显的东西,要么对于技术新手没有明确的文档。

我很感激帮助。 谢谢。

public static AuthenticationConfiguration CreateConfiguration() { var config = new AuthenticationConfiguration { DefaultAuthenticationScheme = "Basic", EnableSessionToken = true, SetNoRedirectMarker = true }; config.AddBasicAuthentication((userName, password) => userName == password, retainPassword: false); config.AddAccessKey(token => { if (ObfuscatingComparer.IsEqual(token, "accesskey123")) { return Principal.Create("Custom", new Claim("customerid", "123"), new Claim("email", "foo@customer.com")); } return null; }, AuthenticationOptions.ForQueryString("key")); 

这是我之前提出的这个问题的解决方案。

注意:此解决方案不涉及Thinktecture身份模型。

我有一个抽象的BasicAuthenticationHandler类,它是一个委托处理程序。 您可以通过安装最新的稳定WebAPIDoodle NuGet包来获取此处理程序 。

如果请求已经过身份validation,您可以提示此基本身份validation处理程序以禁止身份validation过程(例如:通过表单身份validation)。 您需要注册的自定义处理程序如下所示:

 public class MyApplicationAuthHandler : BasicAuthenticationHandler { public MyApplicationAuthHandler() : base(suppressIfAlreadyAuthenticated: true) { } protected override IPrincipal AuthenticateUser( HttpRequestMessage request, string username, string password, CancellationToken cancellationToken) { //this method will be called only if the request //is not authanticated. //If you are using forms auth, this won't be called //as you will be authed by the forms auth bofore you hit here //and Thread.CurrentPrincipal would be populated. //If you aren't authed: //Do you auth here and send back an IPrincipal //instance as I do below. var membershipService = (IMembershipService)request .GetDependencyScope() .GetService(typeof(IMembershipService)); var validUserCtx = membershipService .ValidateUser(username, password); return validUserCtx.Principal; } protected override void HandleUnauthenticatedRequest(UnauthenticatedRequestContext context) { // Do nothing here. The Autharization // will be handled by the AuthorizeAttribute. } } 

最后一步,您需要将System.Web.Http.AuthorizeAttribute (而不是System.Web.Mvc.AuthorizeAttribute )应用于控制器和操作方法,以便为特定角色和用户授予权限。

我希望这有助于解决您的问题。