并排Basic和窗体身份验证使用的ASP.NET Web API [英] Side by side Basic and Forms Authentication with ASP.NET Web API

查看:202
本文介绍了并排Basic和窗体身份验证使用的ASP.NET Web API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

免责声明:让我说,我一般+ JQuery的是新来的MVC4 +网络API + Web服务开始。我可能是在错误的角度攻击这一点。

我想建立在C#中的Web MVC应用程序+的Web API,用于.NET 4部署在Azure上。该网站的API将使用移动客户端(IOS,使用RestKit)。

在Web MVC应用程序也比较简单。我们想用窗体身份验证,并SimpleMembership - 这是我们达到并工作正常。

我们将使用从JQuery的(淘汰赛)脚本的Web API方法来填补的网页作品。因此,我们预计JQuery的使用由表单验证验证相同的身份。

然而,这个想法是,在Web API可通过移动客户端直接调用。没有认证形式为那些。

我们一直在寻找的Thinktecture识别模型(http://nuget.org/packages/Thinktecture.IdentityModel <一处href="https://github.com/thinktecture/Thinktecture.IdentityModel.40">https://github.com/thinktecture/Thinktecture.IdentityModel.40).我们增加了基本验证和AcessKey处理程序的配置和它的作品(见下文code)。

当您尝试访问的WebAPI未经验证的浏览器显示的基本身份验证对话框,按预期工作。

的问题就是,当你已经登录通过窗体身份验证,并尝试调用Web API方法,你仍然可以得到基本身份验证对话框。换句话说,Thinktecture IdentityModel似乎完全忽略了窗体身份验证。

我的问题是:

  1. 是我的期望是否正确?一旦我做了窗体身份验证我不应该做任何事来让JQuery的脚本等,从同一个浏览器的用户会话访问Web API。
  2. 如何解决呢?
  3. 如果我的期望是不正确的;这是如何工作的?即:如何让我的JQuery的脚本验证

我知道有吨的#1类似的问题,老实说,我看了很多了,看到视频等,但无论是我失去了一些东西明显的或者没有关于这些的人新的技术,没有明确的文件。

我AP preciate的帮助。谢谢。

 公共静态AuthenticationConfiguration CreateConfiguration()
{
无功配置=新AuthenticationConfiguration
        {
            DefaultAuthenticationScheme =基本,
            EnableSessionToken = TRUE,
            SetNoRedirectMarker =真
        };

config.AddBasicAuthentication((用户名,密码)=&GT;用户名==密码,retainPassword:假);
config.AddAccessKey(标记=&GT;
        {
            如果(ObfuscatingComparer.IsEqual(令牌accesskey123))
            {
                返回Principal.Create(自定义,
                    新的索赔(客户ID,123),
                    新的索赔(电子邮件,foo@customer.com));
            }

            返回null;
        },AuthenticationOptions.ForQueryString(钥匙));
 

解决方案

下面是对于这个问题,我想出了前面的解决方案。

  

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

我有一个抽象的<一个href="https://github.com/WebAPIDoodle/WebAPIDoodle/blob/dev/src/WebApiDoodle.Web/MessageHandlers/BasicAuthenticationHandler.cs"相对=nofollow>这是一个委托处理程序BasicAuthenticationHandler 类。您可以通过安装最新的稳定 WebAPIDoodle的NuGet包得到这个处理程序。

您可以给一个提示,这个基地基本身份验证处理程序晚饭preSS认证过程中,如果该请求已被验证(例如:通过窗体身份验证)。你需要注册你的自定义处理程序看起来像如下:

 公共类MyApplicationAuthHandler:BasicAuthenticationHandler {

    公共MyApplicationAuthHandler()
        :基地(SUP pressIfAlreadyAuthenticated:真){}

    保护覆盖的IPrincipal authenticateUser的(
        HTT prequestMessage的要求,
        字符串的用户名,
        串密码,
        的CancellationToken的CancellationToken){

        //此方法只被调用,如果请求
        //不authanticated。

        //如果使用窗体身份验证,这将不会被调用
        //你会被窗体身份验证来authed bofore你打这里
        //和Thread.CurrentPrincipal中会被填充。

        //如果你不authed:
        //你权威性这里并发送回一个IPrincipal
        //比如像我这样如下。

        VAR membershipService =(IMembershipService)要求
            .GetDependencyScope()
            .GetService(typeof运算(IMembershipService));

        VAR validUserCtx = membershipService
            .ValidateUser(用户名,密码);

        返回validUserCtx.Principal;
    }

    保护覆盖无效HandleUnauthenticatedRequest(UnauthenticatedRequestContext上下文){

        //这里什么都不做。该Autharization
        //将由AuthorizeAttribute处理。
    }
}
 

作为最后一步,你将需要申请 System.Web.Http.AuthorizeAttribute (而不是 System.Web.Mvc.AuthorizeAttribute )到你的控制器和动作方法给予授权的具体角色和用户。

我希望这可以帮助您解决问题。

Disclaimer: let me start by saying that I am new to MVC4 + Web Api + Web Services in general + JQuery. I might be attacking this on the wrong angle.

I am trying to build a Web MVC App + Web API in C# for .NET 4 to deploy in Azure. The web api will be used by mobile clients (iOS, using RestKit).

The Web MVC App will be relatively simple. We would like to use Forms Authentication for it and SimpleMembership - which we achieved and works fine.

We'll use the Web API methods from JQuery (Knockout) scripts to fill pieces of the web pages. Therefore, we expect the JQuery to use the same identity authenticated by Forms Authentication.

However, the idea is that the Web Api can be called directly by mobile clients. No Forms Authentications for those.

We have been looking at the Thinktecture Identity Model (http://nuget.org/packages/Thinktecture.IdentityModel https://github.com/thinktecture/Thinktecture.IdentityModel.40). We added the BasicAuth and AcessKey handlers to the config and it works (see code below).

When you try to access the webapi without being authenticated the browser displays the basic authentication dialog and works as expected.

The "issue" is that when you ARE already logged in via Forms Authentication and try to call a Web Api method you still get the Basic Authentication dialog. In other words, Thinktecture IdentityModel seems to ignore the Forms Authentication altogether.

My questions are:

  1. Are my expectations correct? that once I have done the forms authentication I shouldn't do anything else to let the JQuery scripts, etc., access the Web API from the same browser user session.
  2. How do I fix it?
  3. If my expectations are not correct; how is this supposed to work? ie: how do I make the JQuery scripts authenticate?

I know there are tons of similar questions in Stackoverflow, I honestly looked a lot of up, saw videos, etc., but either I am missing something obvious or there is no clear documentation about this for somebody new in the technologies.

I appreciate the help. Thanks.

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"));

解决方案

Here is the solution for this problem which I have come up with earlier.

Note: This solution doesn't involve Thinktecture Identity Model.

I have an abstract BasicAuthenticationHandler class which is a delegating handler. You can get this handler by installing the latest stable WebAPIDoodle NuGet package.

You can give a hint to this base basic authentication handler to suppress the authentication process if the request has been already authentication (e.g: by forms auth). Your custom handler that you need to register would look like as below:

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.
    }
}

As a final step, you will need to apply System.Web.Http.AuthorizeAttribute (not System.Web.Mvc.AuthorizeAttribute) to your controllers and action methods to give authorization for the specific roles and users.

I hope this helps to solve your problem.

这篇关于并排Basic和窗体身份验证使用的ASP.NET Web API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆