怎样在前端Javascript中调用C#方法(4)验证授权

抱歉让大家久等了,最近有点忙,所以一直没时间更新博客。

上篇文章中我们已经解决ajax请求调用业务类方法带参数的问题,但很多业务类的方法我们肯定是不希望暴露给ajax请求的,这篇文章我们就来解决请求方法授权的问题。

上篇中我们已经用到了特性Attribute给方法参数定义取值,那授权我们是不是也可以通过Attribute来实现呢,当然是可以的。WebService相信大家都用过,WebService的方法都带了一个WebMethod,我们也定义一个类似的特性类AjaxMethod:

[AttributeUsage(AttributeTargets.Method)]
public class AjaxMethod:Attribute {
    public static bool IsAjaxMethod(System.Reflection.MethodInfo method) {
        return Attribute.IsDefined(method, typeof(AjaxMethod));
    }
}

 

 

仅仅是定义一个类而已,附带了一个静态方法,其它的什么都不用做,因为它仅用来给我们的业务方法作标识。

 

 

那判定某个方法是不是可以响应就很简单了,我们在之前的代码中已经通过反射取得了要调用的方法信息,这时只要调用AjaxMethodAttribute的方法就可以知道是否允许Ajax调用,不允许则直接返回,不执行反射取得的方法。

相信不少业务类中的方法都是需要用户登录后才能使用的,如果不解决这个问题,我们每个方法都需要去验证用户是否已经登录,比较麻烦,既然已经讲到了授权,我们就顺带把这个问题解决了。

还是使用特性,我们定义一个AuthorizationAttribute特性类:

[AttributeUsage(AttributeTargets.Method)]
public abstract class AuthorizationAttribute : Attribute {
    public abstract bool Validate(System.Web.HttpContext context);
}

 

为了方便扩展,我们把这个类定义成一个抽象类,并加上一个抽象方法来验证授权,那我们就可以随意给方法定义授权了,如:IsUserAttribute,IsAdministratorAttribute。我们随便定义一个IsUserAttribute类看看:

public class IsUserAttribute : AuthorizationAttribute {
    public override bool Validate(System.Web.HttpContext context) {
        var cookie = context.Request.Cookies["user"];
        return cookie != null && cookie.Value == "1";
    }
}

 

接下来我们原来的Factory.Execute方法需要作出些修改以验证授权:

void Execute(HttpContext context) {
    //根据请求的Url,通过反射取得处理该请求的类
    string url = context.Request.Url.AbsolutePath;
    string[] array = url.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
    string typename = "Biz";
    for (int x = 1; x < array.Length - 1; x++) {
        typename += "." + array[x];
    }
    Type type = this.GetType().Assembly.GetType(typename, false, true);
    if (type != null) {
        //取得类的无参数构造函数
        var constructor = type.GetConstructor(new Type[0]);
        //调用构造函数取得类的实例
        var obj = constructor.Invoke(null);
        //查找请求的方法
        var method = type.GetMethod(System.IO.Path.GetFileNameWithoutExtension(url));
        if (method != null && AjaxMethod.IsAjaxMethod(method)) {
            var attrList = Attribute.GetCustomAttributes(method, typeof(AuthorizationAttribute));
            if (attrList != null && attrList.Length > 0) {
                bool flag = false;
                foreach (AuthorizationAttribute item in attrList) {
                    if (item.Validate(context)) {
                        flag = true;
                        break;
                    }
                }
                if (!flag) {
                    return;
                }
            }
            var parameters = method.GetParameters();
            object[] args = null;
            if (parameters.Length > 0) {
                args = new object[parameters.Length];
                for (int x = 0; x < parameters.Length; x++) {
                    var parameterAttr = (Attribute.GetCustomAttribute(parameters[x], typeof(ParameterAttribute)) as ParameterAttribute) ?? new FormAttribute();
                    parameterAttr.Name = parameterAttr.Name ?? parameters[x].Name;
                    args[x] = parameterAttr.GetValue(context, parameters[x].ParameterType);
                }
            }
            //执行方法并输出响应结果
            method.Invoke(obj, args);
            //context.Response.Write(method.Invoke(obj, args));
        }
    }
}

 

至此,我们对方法访问授权的问题已经解决,未标识AjaxMethod的方法将不能通过Ajax调用,标识了AuthorizationAttribute特性的类需要通过指定的授权才能访问,后期也可以根据需要继承AuthorizationAttribute实现特定的授权需求。

 

时间仓促,写得比较乱,大家凑合着看看吧,欢迎回复交流分享经验!

示例源码下载(部分源码未经测试)

性能优化部分如果有时间,我会尽力分享,感谢大家的关注。

 

posted @ 2012-04-16 01:48  I,Robot  Views(2618)  Comments(5Edit  收藏  举报