예제 #1
0
        /// <summary>
        /// 拦截服务请求
        /// </summary>
        public override async Task <TResponse> UnaryServerHandler <TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod <TRequest, TResponse> continuation)
        {
            Endpoint endpoint       = OwinContextReader.Current.GetEndpoint();
            bool     needAuthorize  = AspNetSetting.Authorized;
            bool     allowAnonymous = endpoint.Metadata.GetMetadata <AllowAnonymousAttribute>() != null;

            if (needAuthorize && !allowAnonymous)
            {
                string         headerKey   = SessionKey.PublicKey.ToLower();
                Metadata.Entry headerEntry = context.RequestHeaders.Get(headerKey);
                string         publicKey   = headerEntry?.Value;
                if (string.IsNullOrWhiteSpace(publicKey))
                {
                    string message = "身份认证消息头不存在,请检查程序!";
                    NoPermissionException innerException = new NoPermissionException(message);
                    Status status = new Status(StatusCode.Unauthenticated, message, innerException);
                    throw new RpcException(status);
                }

                LoginInfo loginInfo = CacheMediator.Get <LoginInfo>(publicKey);
                if (loginInfo == null)
                {
                    string message = "身份过期,请重新登录!";
                    NoPermissionException innerException = new NoPermissionException(message);
                    Status status = new Status(StatusCode.Unauthenticated, message, innerException);
                    throw new RpcException(status);
                }

                //通过后,重新设置缓存过期时间
                CacheMediator.Set(publicKey, loginInfo, DateTime.Now.AddMinutes(GlobalSetting.AuthenticationTimeout));
            }

            return(await continuation.Invoke(request, context));
        }
예제 #2
0
        /// <summary>
        /// 请求发送前事件
        /// </summary>
        /// <param name="request">请求消息</param>
        /// <param name="channel">信道</param>
        public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
        {
            if (OperationContext.Current != null)
            {
                //WCF客户端获取公钥处理
                MessageHeaders incomingHeaders = OperationContext.Current.IncomingMessageHeaders;

                #region # 验证消息头

                if (!incomingHeaders.Any(x => x.Name == CommonConstants.WCFAuthenticationHeader && x.Namespace == GlobalSetting.ApplicationId))
                {
                    string message = "身份认证消息头不存在,请检查程序!";
                    NoPermissionException innerException = new NoPermissionException(message);
                    FaultReason           faultReason    = new FaultReason(message);
                    FaultCode             faultCode      = new FaultCode(HttpStatusCode.Unauthorized.ToString());
                    throw new FaultException <NoPermissionException>(innerException, faultReason, faultCode);
                }

                #endregion

                //读取消息头中的公钥
                Guid publicKey = incomingHeaders.GetHeader <Guid>(CommonConstants.WCFAuthenticationHeader, GlobalSetting.ApplicationId);

                //添加消息头
                System.ServiceModel.Channels.MessageHeader outgoingheader = System.ServiceModel.Channels.MessageHeader.CreateHeader(CommonConstants.WCFAuthenticationHeader, GlobalSetting.ApplicationId, publicKey);
                request.Headers.Add(outgoingheader);
            }

            return(null);
        }
예제 #3
0
        /// <summary>
        /// 接收请求后事件
        /// </summary>
        /// <param name="request">请求消息</param>
        /// <param name="channel">信道</param>
        /// <param name="instanceContext">WCF实例上下文</param>
        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            //获取消息头
            MessageHeaders headers = request.Headers;
            string         action  = headers.Action;

            EndpointDispatcher endpointDispatcher  = OperationContext.Current.EndpointDispatcher;
            DispatchOperation  operationDispatcher = endpointDispatcher.DispatchRuntime.Operations.Single(x => x.Action == action);

            /*
             * 通过OperationBehavior设置Impersonation属性,
             * 默认值为ImpersonationOption.NotAllowed,
             * 当ImpersonationOption.NotAllowed时验证身份,
             * 如无需验证身份,则将Impersonation属性赋值为ImpersonationOption.Allowed。
             */
            if (operationDispatcher.Impersonation == ImpersonationOption.NotAllowed)
            {
                #region # 验证消息头

                if (!headers.Any(x => x.Name == CommonConstants.WCFAuthenticationHeader && x.Namespace == GlobalSetting.ApplicationId))
                {
                    string message = "身份认证消息头不存在,请检查程序!";
                    NoPermissionException innerException = new NoPermissionException(message);
                    FaultReason           faultReason    = new FaultReason(message);
                    FaultCode             faultCode      = new FaultCode(HttpStatusCode.Unauthorized.ToString());
                    throw new FaultException <NoPermissionException>(innerException, faultReason, faultCode);
                }

                #endregion

                //读取消息头中的公钥
                Guid publicKey = headers.GetHeader <Guid>(CommonConstants.WCFAuthenticationHeader, GlobalSetting.ApplicationId);

                //认证
                lock (_Sync)
                {
                    //以公钥为键,查询分布式缓存,如果有值则通过,无值则不通过
                    LoginInfo loginInfo = CacheMediator.Get <LoginInfo>(publicKey.ToString());
                    if (loginInfo == null)
                    {
                        string message = "身份过期,请重新登录!";
                        NoPermissionException innerException = new NoPermissionException(message);
                        FaultReason           faultReason    = new FaultReason(message);
                        FaultCode             faultCode      = new FaultCode(HttpStatusCode.Unauthorized.ToString());
                        throw new FaultException <NoPermissionException>(innerException, faultReason, faultCode);
                    }

                    //通过后,重新设置缓存过期时间
                    CacheMediator.Set(publicKey.ToString(), loginInfo, DateTime.Now.AddMinutes(GlobalSetting.AuthenticationTimeout));
                }
            }

            return(null);
        }