ASP.NET Web Api身份验证方法

5
我正在尝试为我的Web API实现身份验证。 我阅读了有关不同API身份验证技术的文章,令我最感兴趣的是token技术。
我阅读了许多关于如何在ASP.NET中实现基于token的身份验证的文章,但它们都依赖于不同的库,如OAuth或Owin,这些库也提供了它们自己的数据库交互方法。
问题在于,我已经使用抽象存储库和实体实现了与数据库的交互,并且我想知道如何在不干扰当前设计的情况下轻松简单地实现API身份验证。
(顺便说一下,我的项目是在一个空的web api项目的基础上构建的,因此它并没有所有的引导和身份验证类)。
谢谢。

1
真正帮助我解决这个问题的是Taiseer Joudeh的一系列文章。这里是链接token-based-authentication-asp-net-web-api-2-owin-asp-net-identity,也许对你也有帮助。 - Ronald Rozema
1
@RonaldRozema,问题说他们不想使用Owin。 - codeMonkey
1个回答

1
我看到的一个解决方案是使用.NET的HttpApplicationState类并在appstate中存储令牌;这样你就不会直接干扰Session(这将是一种REST反模式),但你仍然可以跟踪所有当前登录的用户,并使用HttpContext/HttpActionContext在应用程序中交叉引用活动令牌。使用HttpActionContext的好处是它是线程安全的,而HttpContext不是,因此您可以锁定appstate,干扰单个请求的HttpContext,然后解锁appstate以允许其他线程进入。
由于锁定/解锁appstate会占用应用程序,我不确定这个解决方案的可扩展性如何,但无论如何,这里是大体概述:
当用户首次登录时,为他/她生成一个令牌并存储在appstate中。然后,您可以使用自定义属性标记需要身份验证(或需要存储在该用户上的其他信息)的任何API调用,该属性检查appstate中的令牌,在API调用中发送令牌名称作为标头(例如“{token-name:TOKEN}”)。
以下是一个简短的例子:
[在登录时首先激活的控制器方法中:]
CustomUserObject user = new CustomUserObject();

//store user props

string token = Guid.NewGuid().ToString();

//create AppState instance, mine's called _appState
//...
_appState.Lock();
_appState[token] = user;
_appState.UnLock();
//...

【英译中】在 global.asax 文件中:
public class CustomAuthorize : System.Web.Http.AuthorizeAttribute
{
    HttpRequestMessage request = actionContext.ControllerContext.Request;
    string token = string.Empty;

    if (request.Headers.GetValues("token-name") != null)
    {
        token = request.Headers.GetValues("token-name").FirstOrDefault().ToString();

        IAppStateService appService; //<--- I've created a custom service tier class for appstate stuff

        //Get appState instance, however makes sense for you.
        //I'm using repo pattern with UnitOfWork, so mine looks like this...
        //"IContainer ioc = DependencyResolution.IoC.Initialize();"
        //"IAppStateService appService = ioc.GetInstance<IAppStateService>();"
        appService.SetHttpApplicationState(HttpContext.Current.Application);

        bool isAuthorized = appService.CheckTokenAndDoStuff(token);

        //inside that method ^^^ you'll do stuff like
        //"_appState.Lock();"
        //"if (_appState[token] == null) return false" (or whatever)
        //"_appState.Unlock();"
    }

    if (isAuthorized)
    {
        HttpResponseMessage resp = request.CreateResponse(HttpStatusCode.OK);

        resp.Headers.Add("AuthenticationToken", token);
        resp.Headers.Add("WWW-Authenticate", "Basic");
        resp.Headers.Add("AuthenticationStatus", "Authorized");
    }

    return isAuthorized;
}

[然后在Web API中]

[HttpPost]
[CustomAuthorize]
public HttpResponseMessage NameOfMethod(...)...

...这样就可以为您的用户令牌检查应用程序状态了。只需确保在请求头中包括您的令牌,并确保在响应头中包括基本身份验证信息。


看起来是个不错的解决方案,但不包括将令牌保存在应用程序状态中的部分。 也许我应该将它保存在数据库中? - areller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接