怎样在前端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实现特定的授权需求。
时间仓促,写得比较乱,大家凑合着看看吧,欢迎回复交流分享经验!
性能优化部分如果有时间,我会尽力分享,感谢大家的关注。