zoukankan      html  css  js  c++  java
  • 怎样在前端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实现特定的授权需求。

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

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

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

  • 相关阅读:
    [转]在Ubuntu 下安装Redis 并使用init 脚本启动
    [资源]PHP使用消息队列
    [转]reids客户端 redis-cli用法
    [转]redis.conf的配置解析
    【转】微信公共号开发,提示“该公众号暂时无法提供服务,请稍后再试”,如何解决?
    [转]php 解决json_encode中文UNICODE转码问题
    [资料]Keychain 获取设备唯一
    [转]PHP 获取服务器详细信息代码
    crontab任务取消发送邮件
    [转]php返回json数据中文显示的问题
  • 原文地址:https://www.cnblogs.com/robot/p/2451118.html
Copyright © 2011-2022 走看看