簡體   English   中英

使用ASP.NET Web API並排進行基本和表單身份驗證

[英]Side by side Basic and Forms Authentication with ASP.NET Web API

免責聲明:首先我要說的是我對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 Authentication驗證的相同身份。

但是,我們的想法是Web Api可以由移動客戶端直接調用。 沒有表格認證。

我們一直在研究Thinktecture身份模型( http://nuget.org/packages/Thinktecture.IdentityModel https://github.com/thinktecture/Thinktecture.IdentityModel.40 )。 我們將BasicAuth和AcessKey處理程序添加到配置中並且它可以工作(請參閱下面的代碼)。

當您嘗試訪問webapi而未經過身份驗證時,瀏覽器將顯示基本身份驗證對話框並按預期工作。

“問題”是,當您已經通過表單身份驗證登錄並嘗試調用Web Api方法時,您仍然可以獲得“基本身份驗證”對話框。 換句話說,Thinktecture IdentityModel似乎完全忽略了Forms身份驗證。

我的問題是:

  1. 我的期望是否正確? 一旦我完成了表單身份驗證,我就不應該做任何其他事情讓JQuery腳本等從同一個瀏覽器用戶會話訪問Web API。
  2. 我如何解決它?
  3. 如果我的期望不正確; 這應該怎么樣? 即:如何使JQuery腳本進行身份驗證?

我知道在Stackoverflow中有很多類似的問題,我老實地看了很多,看過視頻等等,但要么我缺少一些明顯的東西,要么對於技術新手沒有明確的文檔。

我很感激幫助。 謝謝。

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包來獲得此處理程序

如果請求已經過身份驗證(例如:通過表單身份驗證),您可以提示此基本身份驗證處理程序以禁止身份驗證過程。 您需要注冊的自定義處理程序如下所示:

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 )應用於控制器和操作方法,以便為特定角色和用戶授予權限。

我希望這有助於解決您的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM