/// <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)); }
/// <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); }
/// <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); }