ASP.Net MVC自定义身份验证

Bon*_*nyT 3 asp.net ajax asp.net-mvc forms-authentication

我有一个Asp.Net MVC webapplication坐在一个仍然主要由delphi管理的网站中.安全性目前由delphi管理,它创建cookie.

已经决定通过提取cookie详细信息并将它们传递给导入的Delphi DLL来验证ASP.Net应用程序中的用户,该DLL根据用户是否有效返回true或false.

我的计划是使用Forms身份验证,但不是将用户重定向到表单而是调用delphi包装器,如果成功,则将用户重定向到原始URL.这样做的好处是,当安全性迁移到.Net时,身份验证框架已经存在,只需要实现更改即可.

public ActionResult LogOn(SecurityCookies model, string returnUrl)
    {
        try
        {
            if (model != null)
            {
                Log.DebugFormat("User login: Id:{0}, Key:{1}", model.UserId, model.Key);
                if (authenticator.UserValid(model.UserId, model.Key, 0))
                {
                    FormsService.SignIn(model.UserId, false);
                    return Redirect(returnUrl);
                }
            }
...
Run Code Online (Sandbox Code Playgroud)

请注意,SecurityCookies是由delphi生成的cookie中的自定义绑定类生成的 - 这很有效.

对delphi dll的调用也可以.

我必须克服的问题是几乎所有对.Net应用程序的调用都是ajax请求.但是,当用户未登录时,浏览器会因重定向而进行3次调用:1)原始ajax请求2)重定向到〜/ Account/Logon(上面的代码)3)重定向回原来的ajax请求

虽然跟踪回发给客户端的响应,但显示步骤3返回正确的数据,整个过程因尚未确定的原因而失败.只需单击客户端上的刷新即可,因为现在用户已通过身份验证,并且不会重定向到〜/ account/Logon.

注意我的客户端jQuery代码如下:$ .getJSON(requestString,function(data){//对数据执行某些操作});

有没有办法更改窗体身份验证过程,以便在用户未经过身份验证时,而不是重定向到Url,我可以运行其他一些代码?我希望身份验证已经发生在用户的浏览器中完全不可见.

nic*_*ane 8

如果要对请求进行身份验证,则可以通过定义Application_AuthenticateRequest方法在global.asax.cs中执行此操作.在这里,您可以使用导入的delphi dll读出自定义cookie并设置Context.User.asp.net中的所有授权都基于HttpContext中设置的用户.Application_AuthenticateRequest方法的实现示例:

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
    if(authCookie != null)
    {
        //Extract the forms authentication cookie
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
        // Create an Identity object
        //CustomIdentity implements System.Web.Security.IIdentity
        CustomIdentity id = GetUserIdentity(authTicket.Name);
        //CustomPrincipal implements System.Web.Security.IPrincipal
        CustomPrincipal newUser = new CustomPrincipal();
        Context.User = newUser;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果cookie无效,那么您将不会在上下文中设置用户.

然后,您可以创建一个BaseController,如果上下文中提供的用户经过身份验证,则所有控制器都将从该检查继承.如果用户未经过身份验证,则可以返回HttpUnauthorizedResult.

public class BaseController : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (User == null || (User != null && !User.Identity.IsAuthenticated))
        {
           filterContext.Result = new HttpUnauthorizedResult();
        }
        else
        {
            // Call the base
            base.OnActionExecuting(filterContext);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在你的web.config中:

<authentication mode="None"/>
Run Code Online (Sandbox Code Playgroud)

因为您不希望将请求重定向到登录页面.