/// <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> /// <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); }
public void TestSetAndGetCacheParallel() { Parallel.For(0, 1000, index => { string cacheKey = Guid.NewGuid().ToString(); string cacheValue = Guid.NewGuid().ToString(); CacheMediator.Set(cacheKey, cacheValue); string value = CacheMediator.Get <string>(cacheKey); Assert.IsTrue(value == cacheValue); }); }
public void TestSetAndGetCache() { for (int index = 0; index < 1000; index++) { string cacheKey = Guid.NewGuid().ToString(); string cacheValue = Guid.NewGuid().ToString(); CacheMediator.Set(cacheKey, cacheValue); string value = CacheMediator.Get <string>(cacheKey); Assert.IsTrue(value == cacheValue); } }
public void TestRemoveCache() { string cacheKey = "key"; string cacheValue = "value"; CacheMediator.Set(cacheKey, cacheValue); //移除 CacheMediator.Remove(cacheKey); string value = CacheMediator.Get <string>(cacheKey); Assert.IsNull(value); }
/// <summary> /// 获取登录信息 /// </summary> /// <returns>登录信息</returns> public LoginInfo GetLoginInfo() { HttpContext httpContext = OwinContextReader.Current; if (httpContext != null && httpContext.Request.Headers.TryGetValue(SessionKey.PublicKey, out StringValues header)) { Guid publicKey = new Guid(header.ToString()); LoginInfo loginInfo = CacheMediator.Get <LoginInfo>(publicKey.ToString()); return(loginInfo); } return(null); }
//Implements #region # 执行授权过滤器事件 —— void OnAuthorization(AuthorizationFilterContext context) /// <summary> /// 执行授权过滤器事件 /// </summary> public void OnAuthorization(AuthorizationFilterContext context) { //判断是否是ApiController if (context.ActionDescriptor is ControllerActionDescriptor actionDescriptor && actionDescriptor.ControllerTypeInfo.IsDefined(typeof(ApiControllerAttribute), true)) { bool needAuthorize = AspNetSetting.Authorized; bool allowAnonymous = this.HasAttr <AllowAnonymousAttribute>(context.ActionDescriptor); if (needAuthorize && !allowAnonymous) { if (!context.HttpContext.Request.Headers.TryGetValue(SessionKey.PublicKey, out StringValues header)) { ObjectResult response = new ObjectResult("身份认证消息头不存在,请检查程序!") { StatusCode = (int)HttpStatusCode.Unauthorized }; context.Result = response; } else { //读取消息头中的公钥 Guid publicKey = new Guid(header.ToString()); //认证 lock (_Sync) { //以公钥为键,查询分布式缓存,如果有值则通过,无值则不通过 LoginInfo loginInfo = CacheMediator.Get <LoginInfo>(publicKey.ToString()); if (loginInfo == null) { ObjectResult response = new ObjectResult("身份过期,请重新登录!") { StatusCode = (int)HttpStatusCode.Unauthorized }; context.Result = response; } else { //通过后,重新设置缓存过期时间 CacheMediator.Set(publicKey.ToString(), loginInfo, DateTime.Now.AddMinutes(GlobalSetting.AuthenticationTimeout)); } } } } } }
/// <summary> /// 获取登录信息 /// </summary> /// <returns>登录信息</returns> public LoginInfo GetLoginInfo() { if (OperationContext.Current != null) { //获取消息头 MessageHeaders headers = OperationContext.Current.IncomingMessageHeaders; if (!headers.Any(x => x.Name == CommonConstants.WCFAuthenticationHeader && x.Namespace == GlobalSetting.ApplicationId)) { return(null); } Guid publicKey = headers.GetHeader <Guid>(CommonConstants.WCFAuthenticationHeader, GlobalSetting.ApplicationId); LoginInfo loginInfo = CacheMediator.Get <LoginInfo>(publicKey.ToString()); return(loginInfo); } return(null); }
/// <summary> /// 执行中间件 /// </summary> public async Task Invoke(HttpContext context) { if (AspNetSetting.Authorized) { //读Header string publicKey = context.Request.Headers[SessionKey.PublicKey]; if (string.IsNullOrWhiteSpace(publicKey)) { //读QueryString publicKey = context.Request.Query[SessionKey.PublicKey]; } if (string.IsNullOrWhiteSpace(publicKey)) { context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; context.Response.Headers.Append("ErrorMessage", "Public key not found"); await this._next.Invoke(context); } else { LoginInfo loginInfo = CacheMediator.Get <LoginInfo>(publicKey); if (loginInfo == null) { context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; context.Response.Headers.Append("ErrorMessage", "Login info expired"); await this._next.Invoke(context); } else { IIdentity identity = new GenericIdentity(loginInfo.LoginId); context.User = new GenericPrincipal(identity, null); await this._next.Invoke(context); } } } else { await this._next.Invoke(context); } }
/// <summary> /// 执行授权过滤器事件 /// </summary> public async Task <HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext context, CancellationToken cancellationToken, Func <Task <HttpResponseMessage> > continuation) { if (AspNetSetting.Authorized && !this.HasAttr <AllowAnonymousAttribute>(context.ActionDescriptor)) { if (!context.Request.Headers.TryGetValues(SessionKey.PublicKey, out IEnumerable <string> headers)) { HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.Unauthorized) { Content = new StringContent("身份认证消息头不存在,请检查程序!") }; return(httpResponseMessage); } //读取消息头中的公钥 Guid publicKey = new Guid(headers.Single()); //认证 lock (_Sync) { //以公钥为键,查询分布式缓存,如果有值则通过,无值则不通过 LoginInfo loginInfo = CacheMediator.Get <LoginInfo>(publicKey.ToString()); if (loginInfo == null) { HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.Unauthorized) { Content = new StringContent("身份过期,请重新登录!") }; return(httpResponseMessage); } //通过后,重新设置缓存过期时间 CacheMediator.Set(publicKey.ToString(), loginInfo, DateTime.Now.AddMinutes(GlobalSetting.AuthenticationTimeout)); return(continuation().Result); } } return(await continuation()); }
/// <summary> /// 接收请求后事件 /// </summary> /// <param name="request">请求消息</param> /// <param name="channel">信道</param> /// <param name="instanceContext">WCF实例上下文</param> /// <returns></returns> public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { //如果是身份认证接口,无需认证 if (OperationContext.Current.EndpointDispatcher.ContractName != "IAuthenticationContract") { //获取消息头 MessageHeaders headers = OperationContext.Current.IncomingMessageHeaders; #region # 验证消息头 if (!headers.Any(x => x.Name == CommonConstants.WcfAuthHeaderName && x.Namespace == CommonConstants.WcfAuthHeaderNamespace)) { throw new NullReferenceException("身份认证消息头不存在,请检查程序!"); } #endregion //读取消息头中的公钥 Guid publicKey = headers.GetHeader <Guid>(CommonConstants.WcfAuthHeaderName, CommonConstants.WcfAuthHeaderNamespace); //认证 lock (_Sync) { //以公钥为键,查询分布式缓存,如果有值则通过,无值则不通过 LoginInfo loginInfo = CacheMediator.Get <LoginInfo>(publicKey.ToString()); if (loginInfo == null) { throw new NoPermissionException("身份过期,请重新登录!"); } //通过后,重新设置缓存过期时间 CacheMediator.Set(publicKey.ToString(), loginInfo, DateTime.Now.AddMinutes(_Timeout)); } } return(null); }
//Private #region # 方法进入事件 —— bool OnEntry(MethodAdviceContext context) /// <summary> /// 方法进入事件 /// </summary> /// <param name="context">方法元数据</param> private bool OnEntry(MethodAdviceContext context) { bool hasCache = false; string cacheKey = this.BuildCacheKey(context); object returnValue = CacheMediator.Get <object>(cacheKey); if (returnValue != null) { if (this._expiredSpan.HasValue) { CacheMediator.Set(cacheKey, returnValue, DateTime.Now.Add(this._expiredSpan.Value)); } else { CacheMediator.Set(cacheKey, returnValue); } context.ReturnValue = returnValue; hasCache = true; } return(hasCache); }