/// <summary> /// Gets store host location /// </summary> /// <param name="useSsl">Whether to get SSL secured URL</param> /// <returns>Store host location</returns> public virtual string GetStoreHost(bool useSsl) { var result = string.Empty; //try to get host from the request HOST header var hostHeader = _httpContextAccessor.HttpContext.Request.Headers[HeaderNames.Host]; if (!StringValues.IsNullOrEmpty(hostHeader)) { result = $"{_httpContextAccessor.HttpContext.Request.Scheme}://" + hostHeader.FirstOrDefault(); } //whether database is installed if (DataSettingsHelper.DatabaseIsInstalled()) { //get current store (do not inject IWorkContext via constructor because it'll cause circular references) var currentStore = EngineContext.Current.Resolve <IStoreContext>().CurrentStore; if (currentStore == null) { throw new Exception("Current store cannot be loaded"); } if (string.IsNullOrEmpty(result)) { //HOST header is not available, it is possible only when HttpContext is not available (for example, running in a schedule task) //in this case use URL of a store entity configured in admin area result = currentStore.Url; } if (!result.StartsWith("https")) { if (useSsl) { //if secure URL specified let's use this URL, otherwise a store owner wants it to be detected automatically result = !string.IsNullOrWhiteSpace(currentStore.SecureUrl) ? currentStore.SecureUrl : result.Replace("http://", "https://"); } else { if (currentStore.SslEnabled && !string.IsNullOrWhiteSpace(currentStore.SecureUrl)) { //SSL is enabled in this store and secure URL is specified, so a store owner don't want it to be detected automatically. //in this case let's use the specified non-secure URL result = currentStore.Url; } } } } else { if (!string.IsNullOrEmpty(result) && useSsl) { //use secure connection result = result.Replace("http://", "https://"); } } if (!result.EndsWith("/")) { result += "/"; } return(result); }
/// <summary> /// 处理远端认证结果(阿里钉钉认证服务器认证结果) /// </summary> /// <returns></returns> protected override async Task <HandleRequestResult> HandleRemoteAuthenticateAsync() { #region 步骤1,验证会话是否一致 // 用于存储有关身份验证会话的状态值对象 AuthenticationProperties properties = null; var query = Request.Query; // 阿里钉钉授权后会在redirectUri添加参数:redirect_url?auth_code=xxx var code = query["code"]; //用户授权给钉钉开放应用的免登授权码,第一步中获取的code var state = query["state"]; //状态码 properties = Options.StateDataFormat.Unprotect(state); if (properties == null) { return(HandleRequestResult.Fail("The oauth state was missing or invalid.")); } // OAuth2 10.12 CSRF if (!ValidateCorrelationId(properties)) { return(HandleRequestResult.Fail("Correlation failed.")); } if (StringValues.IsNullOrEmpty(code)) { return(HandleRequestResult.Fail("Code was not found.")); } #endregion #region 步骤2,通过appid,appsecret换取access_token地址。 var codeExchangeContext = new OAuthCodeExchangeContext(properties, code, BuildRedirectUri(Options.CallbackPath)); var tokens = await ExchangeCodeAsync(codeExchangeContext); if (tokens.Error != null) { return(HandleRequestResult.Fail(tokens.Error)); } //tokens.AccessToken = tokens.Response["provider_access_token"]?.ToString(); //tokens.ExpiresIn = tokens.Response["expires_in"]?.ToString(); if (string.IsNullOrEmpty(tokens.AccessToken)) { return(HandleRequestResult.Fail("Failed to retrieve access token.")); } #endregion // 初始化一个Identity。有了auth_code和provider_access_token,下一步就是取用户基本信息。ClaimsIssuer:声明发行者 var identity = new ClaimsIdentity(ClaimsIssuer); // 是否保存Token到用户身份验证会话中。 if (Options.SaveTokens) { var authTokens = new List <AuthenticationToken>(); authTokens.Add(new AuthenticationToken { Name = "access_token", Value = tokens.AccessToken }); if (!string.IsNullOrEmpty(tokens.RefreshToken)) { authTokens.Add(new AuthenticationToken { Name = "refresh_token", Value = tokens.RefreshToken }); } if (!string.IsNullOrEmpty(tokens.TokenType)) { authTokens.Add(new AuthenticationToken { Name = "token_type", Value = tokens.TokenType }); } if (!string.IsNullOrEmpty(tokens.ExpiresIn)) { int value; if (int.TryParse(tokens.ExpiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out value)) { // https://www.w3.org/TR/xmlschema-2/#dateTime // https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx var expiresAt = Clock.UtcNow + TimeSpan.FromSeconds(value); authTokens.Add(new AuthenticationToken { Name = "expires_at", Value = expiresAt.ToString("o", CultureInfo.InvariantCulture) }); } } properties.StoreTokens(authTokens); } #region 步骤3,创建认证票据 var ticket = await CreateTicketAsync(identity, properties, tokens); if (ticket != null) { //返回成功认证 return(HandleRequestResult.Success(ticket)); } else { //返回失败认证 return(HandleRequestResult.Fail("Failed to retrieve user information from remote server.")); } #endregion }
protected virtual async Task ProcessRequestAsync() { var action = "DIRLIST"; try { if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.HtmlEditorManagePictures)) { throw new Exception("You don't have required permission"); } if (!StringValues.IsNullOrEmpty(HttpContext.Request.Query["a"])) { action = HttpContext.Request.Query["a"]; } switch (action.ToUpperInvariant()) { case "DIRLIST": await _roxyFilemanService.GetDirectoriesAsync(HttpContext.Request.Query["type"]); break; case "FILESLIST": await _roxyFilemanService.GetFilesAsync(HttpContext.Request.Query["d"], HttpContext.Request.Query["type"]); break; case "COPYDIR": await _roxyFilemanService.CopyDirectoryAsync(HttpContext.Request.Query["d"], HttpContext.Request.Query["n"]); break; case "COPYFILE": await _roxyFilemanService.CopyFileAsync(HttpContext.Request.Query["f"], HttpContext.Request.Query["n"]); break; case "CREATEDIR": await _roxyFilemanService.CreateDirectoryAsync(HttpContext.Request.Query["d"], HttpContext.Request.Query["n"]); break; case "DELETEDIR": await _roxyFilemanService.DeleteDirectoryAsync(HttpContext.Request.Query["d"]); break; case "DELETEFILE": await _roxyFilemanService.DeleteFileAsync(HttpContext.Request.Query["f"]); break; case "DOWNLOAD": await _roxyFilemanService.DownloadFileAsync(HttpContext.Request.Query["f"]); break; case "DOWNLOADDIR": await _roxyFilemanService.DownloadDirectoryAsync(HttpContext.Request.Query["d"]); break; case "MOVEDIR": await _roxyFilemanService.MoveDirectoryAsync(HttpContext.Request.Query["d"], HttpContext.Request.Query["n"]); break; case "MOVEFILE": await _roxyFilemanService.MoveFileAsync(HttpContext.Request.Query["f"], HttpContext.Request.Query["n"]); break; case "RENAMEDIR": await _roxyFilemanService.RenameDirectoryAsync(HttpContext.Request.Query["d"], HttpContext.Request.Query["n"]); break; case "RENAMEFILE": await _roxyFilemanService.RenameFileAsync(HttpContext.Request.Query["f"], HttpContext.Request.Query["n"]); break; case "GENERATETHUMB": await _roxyFilemanService.CreateImageThumbnailAsync(HttpContext.Request.Query["f"]); break; case "UPLOAD": await _roxyFilemanService.UploadFilesAsync(HttpContext.Request.Form["d"]); break; default: await HttpContext.Response.WriteAsync(_roxyFilemanService.GetErrorResponse("This action is not implemented.")); break; } } catch (Exception ex) { if (action == "UPLOAD" && !_roxyFilemanService.IsAjaxRequest()) { await HttpContext.Response.WriteAsync($"<script>parent.fileUploaded({_roxyFilemanService.GetErrorResponse(await _roxyFilemanService.GetLanguageResourceAsync("E_UploadNoFiles"))});</script>"); } else { await HttpContext.Response.WriteAsync(_roxyFilemanService.GetErrorResponse(ex.Message)); } } }
protected override async Task <HandleRequestResult> HandleRemoteAuthenticateAsync() { var query = Request.Query; var state = query["state"]; var properties = Options.StateDataFormat.Unprotect(state); if (properties == null) { return(HandleRequestResult.Fail("The oauth state was missing or invalid.")); } // OAuth2 10.12 CSRF if (!ValidateCorrelationId(properties)) { return(HandleRequestResult.Fail("Correlation failed.", properties)); } var error = query["error"]; if (!StringValues.IsNullOrEmpty(error)) { // Note: access_denied errors are special protocol errors indicating the user didn't // approve the authorization demand requested by the remote authorization server. // Since it's a frequent scenario (that is not caused by incorrect configuration), // denied errors are handled differently using HandleAccessDeniedErrorAsync(). // Visit https://tools.ietf.org/html/rfc6749#section-4.1.2.1 for more information. var errorDescription = query["error_description"]; var errorUri = query["error_uri"]; if (StringValues.Equals(error, "access_denied")) { var result = await HandleAccessDeniedErrorAsync(properties); if (!result.None) { return(result); } var deniedEx = new Exception("Access was denied by the resource owner or by the remote server."); deniedEx.Data["error"] = error.ToString(); deniedEx.Data["error_description"] = errorDescription.ToString(); deniedEx.Data["error_uri"] = errorUri.ToString(); return(HandleRequestResult.Fail(deniedEx, properties)); } var failureMessage = new StringBuilder(); failureMessage.Append(error); if (!StringValues.IsNullOrEmpty(errorDescription)) { failureMessage.Append(";Description=").Append(errorDescription); } if (!StringValues.IsNullOrEmpty(errorUri)) { failureMessage.Append(";Uri=").Append(errorUri); } var ex = new Exception(failureMessage.ToString()); ex.Data["error"] = error.ToString(); ex.Data["error_description"] = errorDescription.ToString(); ex.Data["error_uri"] = errorUri.ToString(); return(HandleRequestResult.Fail(ex, properties)); } var code = query["code"]; if (StringValues.IsNullOrEmpty(code)) { return(HandleRequestResult.Fail("Code was not found.", properties)); } var codeExchangeContext = new OAuthCodeExchangeContext(properties, code, BuildRedirectUri(Options.CallbackPath)); using var tokens = await ExchangeCodeAsync(codeExchangeContext); if (tokens.Error != null) { return(HandleRequestResult.Fail(tokens.Error, properties)); } if (string.IsNullOrEmpty(tokens.AccessToken)) { return(HandleRequestResult.Fail("Failed to retrieve access token.", properties)); } var identity = new ClaimsIdentity(ClaimsIssuer); if (Options.SaveTokens) { var authTokens = new List <AuthenticationToken>(); authTokens.Add(new AuthenticationToken { Name = "access_token", Value = tokens.AccessToken }); if (!string.IsNullOrEmpty(tokens.RefreshToken)) { authTokens.Add(new AuthenticationToken { Name = "refresh_token", Value = tokens.RefreshToken }); } if (!string.IsNullOrEmpty(tokens.TokenType)) { authTokens.Add(new AuthenticationToken { Name = "token_type", Value = tokens.TokenType }); } if (!string.IsNullOrEmpty(tokens.ExpiresIn)) { int value; if (int.TryParse(tokens.ExpiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out value)) { // https://www.w3.org/TR/xmlschema-2/#dateTime // https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx var expiresAt = Clock.UtcNow + TimeSpan.FromSeconds(value); authTokens.Add(new AuthenticationToken { Name = "expires_at", Value = expiresAt.ToString("o", CultureInfo.InvariantCulture) }); } } properties.StoreTokens(authTokens); } var ticket = await CreateTicketAsync(identity, properties, tokens); if (ticket != null) { return(HandleRequestResult.Success(ticket)); } else { return(HandleRequestResult.Fail("Failed to retrieve user information from remote server.", properties)); } }
public virtual bool IsResponseCacheable(ResponseCachingContext context) { var responseCacheControlHeader = context.HttpContext.Response.Headers[HeaderNames.CacheControl]; // Only cache pages explicitly marked with public if (!HeaderUtilities.ContainsCacheDirective(responseCacheControlHeader, CacheControlHeaderValue.PublicString)) { context.Logger.LogResponseWithoutPublicNotCacheable(); return(false); } // Check response no-store if (HeaderUtilities.ContainsCacheDirective(responseCacheControlHeader, CacheControlHeaderValue.NoStoreString)) { context.Logger.LogResponseWithNoStoreNotCacheable(); return(false); } // Check no-cache if (HeaderUtilities.ContainsCacheDirective(responseCacheControlHeader, CacheControlHeaderValue.NoCacheString)) { context.Logger.LogResponseWithNoCacheNotCacheable(); return(false); } var response = context.HttpContext.Response; // Do not cache responses with Set-Cookie headers if (!StringValues.IsNullOrEmpty(response.Headers[HeaderNames.SetCookie])) { context.Logger.LogResponseWithSetCookieNotCacheable(); return(false); } // Do not cache responses varying by * var varyHeader = response.Headers[HeaderNames.Vary]; if (varyHeader.Count == 1 && string.Equals(varyHeader, "*", StringComparison.OrdinalIgnoreCase)) { context.Logger.LogResponseWithVaryStarNotCacheable(); return(false); } // Check private if (HeaderUtilities.ContainsCacheDirective(responseCacheControlHeader, CacheControlHeaderValue.PrivateString)) { context.Logger.LogResponseWithPrivateNotCacheable(); return(false); } // Check response code if (response.StatusCode != StatusCodes.Status200OK) { context.Logger.LogResponseWithUnsuccessfulStatusCodeNotCacheable(response.StatusCode); return(false); } // Check response freshness if (!context.ResponseDate.HasValue) { if (!context.ResponseSharedMaxAge.HasValue && !context.ResponseMaxAge.HasValue && context.ResponseTime.Value >= context.ResponseExpires) { context.Logger.LogExpirationExpiresExceeded(context.ResponseTime.Value, context.ResponseExpires.Value); return(false); } } else { var age = context.ResponseTime.Value - context.ResponseDate.Value; // Validate shared max age if (age >= context.ResponseSharedMaxAge) { context.Logger.LogExpirationSharedMaxAgeExceeded(age, context.ResponseSharedMaxAge.Value); return(false); } else if (!context.ResponseSharedMaxAge.HasValue) { // Validate max age if (age >= context.ResponseMaxAge) { context.Logger.LogExpirationMaxAgeExceeded(age, context.ResponseMaxAge.Value); return(false); } else if (!context.ResponseMaxAge.HasValue) { // Validate expiration if (context.ResponseTime.Value >= context.ResponseExpires) { context.Logger.LogExpirationExpiresExceeded(context.ResponseTime.Value, context.ResponseExpires.Value); return(false); } } } } return(true); }
/// <summary> /// 批量修改,默认对Ids中包含的数据进行修改,子类如果有特殊判断应重载本函数 /// </summary> /// <returns>true代表成功,false代表失败</returns> public virtual bool DoBatchEdit() { //获取批量修改VM的所有属性 var pros = LinkedVM.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly); bool rv = true; List <Guid> idsData = new List <Guid>(Ids); //找到对应的BaseCRUDVM,并初始化 var vmtype = this.GetType().Assembly.GetExportedTypes().Where(x => x.IsSubclassOf(typeof(BaseCRUDVM <TModel>))).FirstOrDefault(); IBaseCRUDVM <TModel> vm = null; if (vmtype != null) { vm = vmtype.GetConstructor(System.Type.EmptyTypes).Invoke(null) as IBaseCRUDVM <TModel>; vm.CopyContext(this); } //循环所有数据 for (int i = 0; i < idsData.Count; i++) { try { //如果找不到对应数据,则输出错误 TModel entity = null; entity = DC.Set <TModel>().Find(idsData[i]); if (vm != null) { vm.SetEntity(entity); } if (entity == null) { ErrorMessage.Add(idsData[i], "数据不存在"); rv = false; break; } //如果能找到,则循环LinkedVM中的属性,给entity中同名属性赋值 foreach (var pro in pros) { var proToSet = entity.GetType().GetProperty(pro.Name); var val = FC.ContainsKey("LinkedVM." + pro.Name) ? FC["LinkedVM." + pro.Name] : null; if (proToSet != null && val != null) { var hasvalue = false; if (val is StringValues sv && StringValues.IsNullOrEmpty(sv) == false) { hasvalue = true; } if (hasvalue) { proToSet.SetValue(entity, pro.GetValue(LinkedVM)); } } } //如果有对应的BaseCRUDVM则使用其进行数据验证 if (vm != null) { vm.Validate(); var errors = vm.MSD; if (errors != null && errors.Count > 0) { var error = ""; foreach (var key in errors.Keys) { if (errors[key].Count > 0) { error += errors[key].Select(x => x.ErrorMessage).ToSpratedString(); } } if (error != "") { ErrorMessage.Add(idsData[i], error); rv = false; break; } } } if (typeof(TModel).IsSubclassOf(typeof(BasePoco))) { BasePoco ent = entity as BasePoco; if (ent.CreateTime == null) { ent.CreateTime = DateTime.Now; } if (string.IsNullOrEmpty(ent.CreateBy)) { ent.CreateBy = LoginUserInfo?.ITCode; } } DC.UpdateEntity(entity); } catch (Exception e) { SetExceptionMessage(e, idsData[i]); rv = false; } } //进行数据库的修改操作 if (rv == true) { try { DC.SaveChanges(); } catch (Exception e) { SetExceptionMessage(e, null); rv = false; } } //如果有错误,输出错误信息 if (rv == false) { if (ErrorMessage.Count > 0) { foreach (var id in idsData) { if (!ErrorMessage.ContainsKey(id)) { ErrorMessage.Add(id, "已回滚"); } } } ListVM.DoSearch(); foreach (var item in ListVM.GetEntityList()) { item.BatchError = ErrorMessage.Where(x => x.Key == item.ID).Select(x => x.Value).FirstOrDefault(); } } return(rv); }
/// <summary> /// Validate CAPTCHA /// </summary> /// <param name="context">A context for action filters</param> /// <returns>True if CAPTCHA is valid; otherwise false</returns> protected bool ValidateCaptcha(ActionExecutingContext context) { var isValid = false; //get form values var captchaChallengeValue = context.HttpContext.Request.Form[CHALLENGE_FIELD_KEY]; var captchaResponseValue = context.HttpContext.Request.Form[RESPONSE_FIELD_KEY]; var gCaptchaResponseValue = context.HttpContext.Request.Form[G_RESPONSE_FIELD_KEY]; if ((!StringValues.IsNullOrEmpty(captchaChallengeValue) && !StringValues.IsNullOrEmpty(captchaResponseValue)) || !StringValues.IsNullOrEmpty(gCaptchaResponseValue)) { //create CAPTCHA validator var captchaValidtor = new GReCaptchaValidator(_captchaSettings.ReCaptchaVersion) { SecretKey = _captchaSettings.ReCaptchaPrivateKey, RemoteIp = context.HttpContext.Connection.RemoteIpAddress?.ToString(), Response = !StringValues.IsNullOrEmpty(captchaResponseValue) ? captchaResponseValue : gCaptchaResponseValue, Challenge = captchaChallengeValue }; //validate request var recaptchaResponse = captchaValidtor.Validate(); isValid = recaptchaResponse.IsValid; } return(isValid); }
public static StringValues GetQueryParam(this string url, string key) { if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out var uri)) { var queryParams = QueryHelpers.ParseNullableQuery(uri?.Query); if (queryParams != null && queryParams.TryGetValue(key, out var values) && !StringValues.IsNullOrEmpty(values)) { return(values); } } return(string.Empty); }
public static (bool isRangeRequest, RangeItemHeaderValue?range) ParseRange( HttpContext context, RequestHeaders requestHeaders, long length, ILogger logger) { var rawRangeHeader = context.Request.Headers.Range; if (StringValues.IsNullOrEmpty(rawRangeHeader)) { logger.LogTrace("Range header's value is empty."); return(false, null); } // Perf: Check for a single entry before parsing it if (rawRangeHeader.Count > 1 || rawRangeHeader[0].IndexOf(',') >= 0) { logger.LogDebug("Multiple ranges are not supported."); // The spec allows for multiple ranges but we choose not to support them because the client may request // very strange ranges (e.g. each byte separately, overlapping ranges, etc.) that could negatively // impact the server. Ignore the header and serve the response normally. return(false, null); } var rangeHeader = requestHeaders.Range; if (rangeHeader == null) { logger.LogDebug("Range header's value is invalid."); // Invalid return(false, null); } // Already verified above Debug.Assert(rangeHeader.Ranges.Count == 1); var ranges = rangeHeader.Ranges; if (ranges == null) { logger.LogDebug("Range header's value is invalid."); return(false, null); } if (ranges.Count == 0) { return(true, null); } if (length == 0) { return(true, null); } // Normalize the ranges var range = NormalizeRange(ranges.Single(), length); // Return the single range return(true, range); }
private string QueryString(string name) { if (StringValues.IsNullOrEmpty(HttpContext.Request.Query[name])) { return(default);
public static StringValues GetRelativeUrlQueryParam(this string url, string key) { if (!string.IsNullOrWhiteSpace(url)) { var queryIndex = url.IndexOf('?'); var queryUrl = queryIndex > -1 ? url.Substring(queryIndex) : string.Empty; if (!string.IsNullOrWhiteSpace(queryUrl)) { var queryParams = QueryHelpers.ParseNullableQuery(queryUrl); if (queryParams != null && queryParams.TryGetValue(key, out var values) && !StringValues.IsNullOrEmpty(values)) { return(values); } } } return(string.Empty); }
private Activity?StartActivity(HttpContext httpContext, bool loggingEnabled, bool diagnosticListenerActivityCreationEnabled, out bool hasDiagnosticListener) { var activity = _activitySource.CreateActivity(ActivityName, ActivityKind.Server); if (activity is null && (loggingEnabled || diagnosticListenerActivityCreationEnabled)) { activity = new Activity(ActivityName); } hasDiagnosticListener = false; if (activity is null) { return(null); } var headers = httpContext.Request.Headers; var requestId = headers.TraceParent; if (requestId.Count == 0) { requestId = headers.RequestId; } if (!StringValues.IsNullOrEmpty(requestId)) { activity.SetParentId(requestId); var traceState = headers.TraceState; if (traceState.Count > 0) { activity.TraceStateString = traceState; } // We expect baggage to be empty by default // Only very advanced users will be using it in near future, we encourage them to keep baggage small (few items) var baggage = headers.GetCommaSeparatedValues(HeaderNames.Baggage); if (baggage.Length == 0) { baggage = headers.GetCommaSeparatedValues(HeaderNames.CorrelationContext); } // AddBaggage adds items at the beginning of the list, so we need to add them in reverse to keep the same order as the client // An order could be important if baggage has two items with the same key (that is allowed by the contract) for (var i = baggage.Length - 1; i >= 0; i--) { if (NameValueHeaderValue.TryParse(baggage[i], out var baggageItem)) { activity.AddBaggage(baggageItem.Name.ToString(), HttpUtility.UrlDecode(baggageItem.Value.ToString())); } } } _diagnosticListener.OnActivityImport(activity, httpContext); if (_diagnosticListener.IsEnabled(ActivityStartKey)) { hasDiagnosticListener = true; StartActivity(activity, httpContext); } else { activity.Start(); } return(activity); }
// BaseKey<delimiter>H<delimiter>HeaderName=HeaderValue<delimiter>Q<delimiter>QueryName=QueryValue public string CreateStorageVaryByKey(ResponseCachingContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var varyByRules = context.CachedVaryByRules; if (varyByRules == null) { throw new InvalidOperationException($"{nameof(CachedVaryByRules)} must not be null on the {nameof(ResponseCachingContext)}"); } if ((StringValues.IsNullOrEmpty(varyByRules.Headers) && StringValues.IsNullOrEmpty(varyByRules.QueryKeys))) { return(varyByRules.VaryByKeyPrefix); } var request = context.HttpContext.Request; var builder = _builderPool.Get(); try { // Prepend with the Guid of the CachedVaryByRules builder.Append(varyByRules.VaryByKeyPrefix); // Vary by headers if (varyByRules?.Headers.Count > 0) { // Append a group separator for the header segment of the cache key builder.Append(KeyDelimiter) .Append('H'); for (var i = 0; i < varyByRules.Headers.Count; i++) { var header = varyByRules.Headers[i]; var headerValues = context.HttpContext.Request.Headers[header]; builder.Append(KeyDelimiter) .Append(header) .Append("="); for (var j = 0; j < headerValues.Count; j++) { builder.Append(headerValues[j]); } } } // Vary by query keys if (varyByRules?.QueryKeys.Count > 0) { // Append a group separator for the query key segment of the cache key builder.Append(KeyDelimiter) .Append('Q'); if (varyByRules.QueryKeys.Count == 1 && string.Equals(varyByRules.QueryKeys[0], "*", StringComparison.Ordinal)) { // Vary by all available query keys foreach (var query in context.HttpContext.Request.Query.OrderBy(q => q.Key, StringComparer.OrdinalIgnoreCase)) { builder.Append(KeyDelimiter) .AppendUpperInvariant(query.Key) .Append("="); for (var i = 0; i < query.Value.Count; i++) { builder.Append(query.Value[i]); } } } else { for (var i = 0; i < varyByRules.QueryKeys.Count; i++) { var queryKey = varyByRules.QueryKeys[i]; var queryKeyValues = context.HttpContext.Request.Query[queryKey]; builder.Append(KeyDelimiter) .Append(queryKey) .Append("="); for (var j = 0; j < queryKeyValues.Count; j++) { builder.Append(queryKeyValues[j]); } } } } return(builder.ToString()); } finally { _builderPool.Return(builder); } }
/// <summary> /// Get IP address from HTTP context /// </summary> /// <returns>String of IP address</returns> public virtual string GetCurrentIpAddress() { if (!IsRequestAvailable()) { return(string.Empty); } var result = string.Empty; try { //first try to get IP address from the forwarded header if (_httpContextAccessor.HttpContext.Request.Headers != null) { //the X-Forwarded-For (XFF) HTTP header field is a de facto standard for identifying the originating IP address of a client //connecting to a web server through an HTTP proxy or load balancer var forwardedHttpHeaderKey = NopHttpDefaults.XForwardedForHeader; if (!string.IsNullOrEmpty(_hostingConfig.ForwardedHttpHeader)) { //but in some cases server use other HTTP header //in these cases an administrator can specify a custom Forwarded HTTP header (e.g. CF-Connecting-IP, X-FORWARDED-PROTO, etc) forwardedHttpHeaderKey = _hostingConfig.ForwardedHttpHeader; } var forwardedHeader = _httpContextAccessor.HttpContext.Request.Headers[forwardedHttpHeaderKey]; if (!StringValues.IsNullOrEmpty(forwardedHeader)) { result = forwardedHeader.FirstOrDefault(); } } //if this header not exists try get connection remote IP address if (string.IsNullOrEmpty(result) && _httpContextAccessor.HttpContext.Connection.RemoteIpAddress != null) { result = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString(); } } catch { return(string.Empty); } //some of the validation if (result != null && result.Equals(IPAddress.IPv6Loopback.ToString(), StringComparison.InvariantCultureIgnoreCase)) { result = IPAddress.Loopback.ToString(); } //"TryParse" doesn't support IPv4 with port number if (IPAddress.TryParse(result ?? string.Empty, out var ip)) { //IP address is valid result = ip.ToString(); } else if (!string.IsNullOrEmpty(result)) { //remove port result = result.Split(':').FirstOrDefault(); } return(result); }
protected override async Task <HandleRequestResult> HandleRemoteAuthenticateAsync() { var query = Request.Query; var state = query["state"]; var properties = Options.StateDataFormat.Unprotect(state); if (properties == null) { return(HandleRequestResult.Fail("The oauth state was missing or invalid.")); } // OAuth2 10.12 CSRF if (!ValidateCorrelationId(properties)) { return(HandleRequestResult.Fail("Correlation failed.", properties)); } var error = query["error"]; if (!StringValues.IsNullOrEmpty(error)) { var failureMessage = new StringBuilder(); failureMessage.Append(error); var errorDescription = query["error_description"]; if (!StringValues.IsNullOrEmpty(errorDescription)) { failureMessage.Append(";Description=").Append(errorDescription); } var errorUri = query["error_uri"]; if (!StringValues.IsNullOrEmpty(errorUri)) { failureMessage.Append(";Uri=").Append(errorUri); } return(HandleRequestResult.Fail(failureMessage.ToString(), properties)); } var code = query["code"]; if (StringValues.IsNullOrEmpty(code)) { return(HandleRequestResult.Fail("Code was not found.", properties)); } var tokens = await ExchangeCodeAsync(code, BuildRedirectUri(Options.CallbackPath)); if (tokens.Error != null) { return(HandleRequestResult.Fail(tokens.Error, properties)); } if (string.IsNullOrEmpty(tokens.AccessToken)) { return(HandleRequestResult.Fail("Failed to retrieve access token.", properties)); } var identity = new ClaimsIdentity(ClaimsIssuer); if (Options.SaveTokens) { var authTokens = new List <AuthenticationToken>(); authTokens.Add(new AuthenticationToken { Name = "access_token", Value = tokens.AccessToken }); if (!string.IsNullOrEmpty(tokens.RefreshToken)) { authTokens.Add(new AuthenticationToken { Name = "refresh_token", Value = tokens.RefreshToken }); } if (!string.IsNullOrEmpty(tokens.TokenType)) { authTokens.Add(new AuthenticationToken { Name = "token_type", Value = tokens.TokenType }); } if (!string.IsNullOrEmpty(tokens.ExpiresIn)) { int value; if (int.TryParse(tokens.ExpiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out value)) { // https://www.w3.org/TR/xmlschema-2/#dateTime // https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx var expiresAt = Clock.UtcNow + TimeSpan.FromSeconds(value); authTokens.Add(new AuthenticationToken { Name = "expires_at", Value = expiresAt.ToString("o", CultureInfo.InvariantCulture) }); } } properties.StoreTokens(authTokens); } var ticket = await CreateTicketAsync(identity, properties, tokens); if (ticket != null) { return(HandleRequestResult.Success(ticket)); } else { return(HandleRequestResult.Fail("Failed to retrieve user information from remote server.", properties)); } }
private string FormatHeaders(IHeaderDictionary headersIn) { var headers = headersIn.AsEnumerable().Select(h => KeyValuePair.Create(h.Key, !StringValues.IsNullOrEmpty(h.Value) ? h.Value.ToList() : Enumerable.Empty <string>())); return(FormatEnumerableHeaders(headers)); }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseFileServer(); // Custom CORS to allow any origin + credentials (which isn't allowed by the CORS spec) // This is for testing purposes only (karma hosts the client on its own server), never do this in production app.Use((context, next) => { var originHeader = context.Request.Headers[HeaderNames.Origin]; if (!StringValues.IsNullOrEmpty(originHeader)) { context.Response.Headers[HeaderNames.AccessControlAllowOrigin] = originHeader; context.Response.Headers[HeaderNames.AccessControlAllowCredentials] = "true"; var requestMethod = context.Request.Headers[HeaderNames.AccessControlRequestMethod]; if (!StringValues.IsNullOrEmpty(requestMethod)) { context.Response.Headers[HeaderNames.AccessControlAllowMethods] = requestMethod; } var requestHeaders = context.Request.Headers[HeaderNames.AccessControlRequestHeaders]; if (!StringValues.IsNullOrEmpty(requestHeaders)) { context.Response.Headers[HeaderNames.AccessControlAllowHeaders] = requestHeaders; } } if (string.Equals(context.Request.Method, "OPTIONS", StringComparison.OrdinalIgnoreCase)) { context.Response.StatusCode = StatusCodes.Status204NoContent; return(Task.CompletedTask); } return(next.Invoke()); }); app.Use((context, next) => { if (context.Request.Path.StartsWithSegments("/redirect")) { var newUrl = context.Request.Query["baseUrl"] + "/testHub?numRedirects=" + Interlocked.Increment(ref _numRedirects); return(context.Response.WriteAsync($"{{ \"url\": \"{newUrl}\" }}")); } return(next()); }); app.Use(async(context, next) => { if (context.Request.Path.Value.Contains("/negotiate")) { context.Response.Cookies.Append("testCookie", "testValue"); context.Response.Cookies.Append("testCookie2", "testValue2"); context.Response.Cookies.Append("expiredCookie", "doesntmatter", new CookieOptions() { Expires = DateTimeOffset.Now.AddHours(-1) }); } await next.Invoke(); }); app.UseRouting(); // Custom CORS to allow any origin + credentials (which isn't allowed by the CORS spec) // This is for testing purposes only (karma hosts the client on its own server), never do this in production app.UseCors(policy => { policy.SetIsOriginAllowed(host => host.StartsWith("http://localhost:") || host.StartsWith("http://127.0.0.1:")) .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapHub <TestHub>("/testhub"); endpoints.MapHub <TestHub>("/testhub-nowebsockets", options => options.Transports = HttpTransportType.ServerSentEvents | HttpTransportType.LongPolling); endpoints.MapHub <UncreatableHub>("/uncreatable"); endpoints.MapHub <HubWithAuthorization>("/authorizedhub"); endpoints.MapConnectionHandler <EchoConnectionHandler>("/echo"); endpoints.MapGet("/generateJwtToken", context => { return(context.Response.WriteAsync(GenerateJwtToken())); }); endpoints.MapGet("/deployment", context => { var attributes = Assembly.GetAssembly(typeof(Startup)).GetCustomAttributes <AssemblyMetadataAttribute>(); context.Response.ContentType = "application/json"; using (var textWriter = new StreamWriter(context.Response.Body)) using (var writer = new JsonTextWriter(textWriter)) { var json = new JObject(); var commitHash = string.Empty; foreach (var attribute in attributes) { json.Add(attribute.Key, attribute.Value); if (string.Equals(attribute.Key, "CommitHash")) { commitHash = attribute.Value; } } if (!string.IsNullOrEmpty(commitHash)) { json.Add("GitHubUrl", $"https://github.com/aspnet/SignalR/commit/{commitHash}"); } json.WriteTo(writer); } return(Task.CompletedTask); }); }); }
/// <summary> /// Whether the request is made with ajax /// </summary> /// <returns>True or false</returns> protected virtual bool IsAjaxRequest() { return(HttpContext.Request.Form != null && !StringValues.IsNullOrEmpty(HttpContext.Request.Form["method"]) && HttpContext.Request.Form["method"] == "ajax"); }
public override int GetHashCode() { return(!StringValues.IsNullOrEmpty(_headers) ? _headers.GetHashCode() : 0); }
/// <summary> /// Called before the action executes, after model binding is complete /// </summary> /// <param name="context">A context for action filters</param> public void OnActionExecuting(ActionExecutingContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } //check request query parameters if (!context.HttpContext.Request?.Query?.Any() ?? true) { return; } //only in GET requests if (!context.HttpContext.Request.Method.Equals(WebRequestMethods.Http.Get, StringComparison.InvariantCultureIgnoreCase)) { return; } if (!DataSettingsManager.DatabaseIsInstalled) { return; } var currentCustomer = _workContext.CurrentCustomer; //ignore search engines if (currentCustomer.IsSearchEngineAccount()) { return; } //try to get discount coupon code var queryKey = NopDiscountDefaults.DiscountCouponQueryParameter; if (!context.HttpContext.Request.Query.TryGetValue(queryKey, out var couponCodes) || StringValues.IsNullOrEmpty(couponCodes)) { return; } //get validated discounts with passed coupon codes var discounts = couponCodes .SelectMany(couponCode => _discountService.GetAllDiscounts(couponCode: couponCode)) .Distinct() .ToList(); var validCouponCodes = new List <string>(); foreach (var discount in discounts) { if (!_discountService.ValidateDiscount(discount, currentCustomer, couponCodes.ToArray()).IsValid) { continue; } //apply discount coupon codes to customer _customerService.ApplyDiscountCouponCode(currentCustomer, discount.CouponCode); validCouponCodes.Add(discount.CouponCode); } //show notifications for activated coupon codes foreach (var validCouponCode in validCouponCodes.Distinct()) { _notificationService.SuccessNotification( string.Format(_localizationService.GetResource("ShoppingCart.DiscountCouponCode.Activated"), validCouponCode)); } //show notifications for invalid coupon codes foreach (var invalidCouponCode in couponCodes.Except( validCouponCodes.Distinct())) { _notificationService.WarningNotification( string.Format(_localizationService.GetResource("ShoppingCart.DiscountCouponCode.Invalid"), invalidCouponCode)); } }
public void DeleteCookie(HttpContext context, string key, CookieOptions options) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (key == null) { throw new ArgumentNullException(nameof(key)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } var keys = new List <string>(); keys.Add(key + "="); var requestCookie = context.Request.Cookies[key]; var chunks = ParseChunksCount(requestCookie); if (chunks > 0) { for (int i = 1; i <= chunks + 1; i++) { var subkey = key + ChunkKeySuffix + i.ToString(CultureInfo.InvariantCulture); keys.Add(subkey + "="); } } var domainHasValue = !string.IsNullOrEmpty(options.Domain); var pathHasValue = !string.IsNullOrEmpty(options.Path); Func <string, bool> rejectPredicate; Func <string, bool> predicate = value => keys.Any(k => value.StartsWith(k, StringComparison.OrdinalIgnoreCase)); if (domainHasValue) { rejectPredicate = value => predicate(value) && value.IndexOf("domain=" + options.Domain, StringComparison.OrdinalIgnoreCase) != -1; } else if (pathHasValue) { rejectPredicate = value => predicate(value) && value.IndexOf("path=" + options.Path, StringComparison.OrdinalIgnoreCase) != -1; } else { rejectPredicate = value => predicate(value); } var responseHeaders = context.Response.Headers; var existingValues = responseHeaders[HeaderNames.SetCookie]; if (!StringValues.IsNullOrEmpty(existingValues)) { responseHeaders[HeaderNames.SetCookie] = existingValues.Where(value => !rejectPredicate(value)).ToArray(); } AppendResponseCookie( context, key, string.Empty, new CookieOptions() { Path = options.Path, Domain = options.Domain, SameSite = options.SameSite, Secure = options.Secure, IsEssential = options.IsEssential, Expires = DateTimeOffset.UnixEpoch, HttpOnly = options.HttpOnly, }); for (int i = 1; i <= chunks; i++) { AppendResponseCookie( context, key + "C" + i.ToString(CultureInfo.InvariantCulture), string.Empty, new CookieOptions() { Path = options.Path, Domain = options.Domain, SameSite = options.SameSite, Secure = options.Secure, IsEssential = options.IsEssential, Expires = DateTimeOffset.UnixEpoch, HttpOnly = options.HttpOnly, }); } }
protected virtual string ParseVendorAttributes(IFormCollection form) { if (form == null) { throw new ArgumentNullException(nameof(form)); } var attributesXml = string.Empty; var vendorAttributes = _vendorAttributeService.GetAllVendorAttributes(); foreach (var attribute in vendorAttributes) { var controlId = $"vendor_attribute_{attribute.Id}"; StringValues ctrlAttributes; switch (attribute.AttributeControlType) { case AttributeControlType.DropdownList: case AttributeControlType.RadioList: ctrlAttributes = form[controlId]; if (!StringValues.IsNullOrEmpty(ctrlAttributes)) { var selectedAttributeId = int.Parse(ctrlAttributes); if (selectedAttributeId > 0) { attributesXml = _vendorAttributeParser.AddVendorAttribute(attributesXml, attribute, selectedAttributeId.ToString()); } } break; case AttributeControlType.Checkboxes: var cblAttributes = form[controlId]; if (!StringValues.IsNullOrEmpty(cblAttributes)) { foreach (var item in cblAttributes.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { var selectedAttributeId = int.Parse(item); if (selectedAttributeId > 0) { attributesXml = _vendorAttributeParser.AddVendorAttribute(attributesXml, attribute, selectedAttributeId.ToString()); } } } break; case AttributeControlType.ReadonlyCheckboxes: //load read-only (already server-side selected) values var attributeValues = _vendorAttributeService.GetVendorAttributeValues(attribute.Id); foreach (var selectedAttributeId in attributeValues .Where(v => v.IsPreSelected) .Select(v => v.Id) .ToList()) { attributesXml = _vendorAttributeParser.AddVendorAttribute(attributesXml, attribute, selectedAttributeId.ToString()); } break; case AttributeControlType.TextBox: case AttributeControlType.MultilineTextbox: ctrlAttributes = form[controlId]; if (!StringValues.IsNullOrEmpty(ctrlAttributes)) { var enteredText = ctrlAttributes.ToString().Trim(); attributesXml = _vendorAttributeParser.AddVendorAttribute(attributesXml, attribute, enteredText); } break; case AttributeControlType.Datepicker: case AttributeControlType.ColorSquares: case AttributeControlType.ImageSquares: case AttributeControlType.FileUpload: //not supported vendor attributes default: break; } } return(attributesXml); }
/// <inheritdoc /> public virtual async Task OnResourceExecutionAsync( ResourceExecutingContext context, ResourceExecutionDelegate next) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (next == null) { throw new ArgumentNullException(nameof(next)); } var routeData = context.RouteData; if (!routeData.TryGetWebHookReceiverName(out var receiverName)) { await next(); return; } var eventFromBodyMetadata = _eventFromBodyMetadata .FirstOrDefault(metadata => metadata.IsApplicable(receiverName)); if (eventFromBodyMetadata == null) { await next(); return; } // Determine the applicable WebhookBodyType i.e. how to read the request body. // WebHookReceiverExistsConstraint confirms the IWebHookBodyTypeMetadataService implementation exists. var bodyTypeMetadata = _bodyTypeMetadata.First(metadata => metadata.IsApplicable(receiverName)); // No need to double-check the request's Content-Type. WebHookVerifyBodyTypeFilter would have // short-circuited the request if unsupported. StringValues eventNames; switch (bodyTypeMetadata.BodyType) { case WebHookBodyType.Form: var form = await _requestReader.ReadAsFormDataAsync(context); if (form == null) { // ReadAsFormDataAsync returns null only when other filters will log and return errors // about the same conditions. Let those filters run. await next(); return; } eventNames = form[eventFromBodyMetadata.BodyPropertyPath]; break; case WebHookBodyType.Json: var json = await _requestReader.ReadBodyAsync <JContainer>(context); if (json == null) { var modelState = context.ModelState; if (modelState.IsValid) { // ReadAsJContainerAsync returns null when model state is valid only when other filters // will log and return errors about the same conditions. Let those filters run. await next(); } else { context.Result = new BadRequestObjectResult(modelState); } return; } eventNames = ObjectPathUtilities.GetStringValues(json, eventFromBodyMetadata.BodyPropertyPath); break; case WebHookBodyType.Xml: var xml = await _requestReader.ReadBodyAsync <XElement>(context); if (xml == null) { var modelState = context.ModelState; if (modelState.IsValid) { // ReadAsXmlAsync returns null when model state is valid only when other filters will log // and return errors about the same conditions. Let those filters run. await next(); } else { context.Result = new BadRequestObjectResult(modelState); } return; } eventNames = ObjectPathUtilities.GetStringValues(xml, eventFromBodyMetadata.BodyPropertyPath); break; default: var message = string.Format( CultureInfo.CurrentCulture, Resources.General_InvalidEnumValue, typeof(WebHookBodyType), bodyTypeMetadata.BodyType); throw new InvalidOperationException(message); } if (StringValues.IsNullOrEmpty(eventNames) && !eventFromBodyMetadata.AllowMissing) { _logger.LogWarning( 0, "A '{ReceiverName}' WebHook request must contain a match for '{BodyPropertyPath}' in the HTTP " + "request entity body indicating the type or types of event.", receiverName, eventFromBodyMetadata.BodyPropertyPath); var message = string.Format( CultureInfo.CurrentCulture, Resources.EventMapper_NoBodyProperty, receiverName, eventFromBodyMetadata.BodyPropertyPath); context.Result = new BadRequestObjectResult(message); return; } routeData.SetWebHookEventNames(eventNames); await next(); }
/// <summary> /// Validate payment form /// </summary> /// <param name="form">The parsed form values</param> /// <returns>List of validating errors</returns> public IList <string> ValidatePaymentForm(IFormCollection form) { if (form == null) { throw new ArgumentNullException(nameof(form)); } if (_qualpaySettings.UseEmbeddedFields) { //try to get errors from Qualpay card tokenization if (form.TryGetValue(nameof(PaymentInfoModel.Errors), out var errorsString) && !StringValues.IsNullOrEmpty(errorsString)) { return(errorsString.ToString().Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries).ToList()); } } else { //validate payment info (custom validation) var validationResult = new PaymentInfoValidator(_localizationService).Validate(new PaymentInfoModel { CardholderName = form[nameof(PaymentInfoModel.CardholderName)], CardNumber = form[nameof(PaymentInfoModel.CardNumber)], ExpireMonth = form[nameof(PaymentInfoModel.ExpireMonth)], ExpireYear = form[nameof(PaymentInfoModel.ExpireYear)], CardCode = form[nameof(PaymentInfoModel.CardCode)], BillingCardId = form[nameof(PaymentInfoModel.BillingCardId)], SaveCardDetails = form.TryGetValue(nameof(PaymentInfoModel.SaveCardDetails), out var saveCardDetails) && bool.TryParse(saveCardDetails.FirstOrDefault(), out var saveCard) && saveCard });
public async Task <object> GetStaticResult(IRequest requestContext, StaticResultOptions options) { options.ResponseHeaders = options.ResponseHeaders ?? new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); var contentType = options.ContentType; if (!StringValues.IsNullOrEmpty(requestContext.Headers[HeaderNames.IfModifiedSince])) { // See if the result is already cached in the browser var result = GetCachedResult(requestContext, options.ResponseHeaders, options); if (result != null) { return(result); } } // TODO: We don't really need the option value var isHeadRequest = options.IsHeadRequest || string.Equals(requestContext.Verb, "HEAD", StringComparison.OrdinalIgnoreCase); var factoryFn = options.ContentFactory; var responseHeaders = options.ResponseHeaders; AddCachingHeaders(responseHeaders, options.CacheDuration, false, options.DateLastModified); AddAgeHeader(responseHeaders, options.DateLastModified); var rangeHeader = requestContext.Headers[HeaderNames.Range]; if (!isHeadRequest && !string.IsNullOrEmpty(options.Path)) { var hasHeaders = new FileWriter(options.Path, contentType, rangeHeader, _logger, _fileSystem, _streamHelper) { OnComplete = options.OnComplete, OnError = options.OnError, FileShare = options.FileShare }; AddResponseHeaders(hasHeaders, options.ResponseHeaders); return(hasHeaders); } var stream = await factoryFn().ConfigureAwait(false); var totalContentLength = options.ContentLength; if (!totalContentLength.HasValue) { try { totalContentLength = stream.Length; } catch (NotSupportedException) { } } if (!string.IsNullOrWhiteSpace(rangeHeader) && totalContentLength.HasValue) { var hasHeaders = new RangeRequestWriter(rangeHeader, totalContentLength.Value, stream, contentType, isHeadRequest, _logger) { OnComplete = options.OnComplete }; AddResponseHeaders(hasHeaders, options.ResponseHeaders); return(hasHeaders); } else { if (isHeadRequest) { using (stream) { return(GetHttpResult(requestContext, Array.Empty <byte>(), contentType, true, responseHeaders)); } } var hasHeaders = new StreamWriter(stream, contentType) { OnComplete = options.OnComplete, OnError = options.OnError }; AddResponseHeaders(hasHeaders, options.ResponseHeaders); return(hasHeaders); } }
protected override async Task <HandleRequestResult> HandleRemoteAuthenticateAsync() { var query = Request.Query; var protectedRequestToken = Request.Cookies[Options.StateCookie.Name]; var requestToken = Options.StateDataFormat.Unprotect(protectedRequestToken); if (requestToken == null) { return(HandleRequestResult.Fail("Invalid state cookie.")); } var properties = requestToken.Properties; // REVIEW: see which of these are really errors var returnedToken = query["oauth_token"]; if (StringValues.IsNullOrEmpty(returnedToken)) { return(HandleRequestResult.Fail("Missing oauth_token", properties)); } if (!string.Equals(returnedToken, requestToken.Token, StringComparison.Ordinal)) { return(HandleRequestResult.Fail("Unmatched token", properties)); } var oauthVerifier = query["oauth_verifier"]; if (StringValues.IsNullOrEmpty(oauthVerifier)) { return(HandleRequestResult.Fail("Missing or blank oauth_verifier", properties)); } var cookieOptions = Options.StateCookie.Build(Context, Clock.UtcNow); Response.Cookies.Delete(Options.StateCookie.Name, cookieOptions); var accessToken = await ObtainAccessTokenAsync(requestToken, oauthVerifier); var identity = new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, accessToken.UserId, ClaimValueTypes.String, ClaimsIssuer), new Claim(ClaimTypes.Name, accessToken.ScreenName, ClaimValueTypes.String, ClaimsIssuer), new Claim("urn:twitter:userid", accessToken.UserId, ClaimValueTypes.String, ClaimsIssuer), new Claim("urn:twitter:screenname", accessToken.ScreenName, ClaimValueTypes.String, ClaimsIssuer) }, ClaimsIssuer); JObject user = null; if (Options.RetrieveUserDetails) { user = await RetrieveUserDetailsAsync(accessToken, identity); } if (Options.SaveTokens) { properties.StoreTokens(new [] { new AuthenticationToken { Name = "access_token", Value = accessToken.Token }, new AuthenticationToken { Name = "access_token_secret", Value = accessToken.TokenSecret } }); } return(HandleRequestResult.Success(await CreateTicketAsync(identity, properties, accessToken, user))); }
/// <summary> /// Get custom address attributes from the passed form /// </summary> /// <param name="form">Form values</param> /// <returns>Attributes in XML format</returns> public virtual string ParseCustomAddressAttributes(IFormCollection form) { if (form == null) { throw new ArgumentNullException(nameof(form)); } var attributesXml = string.Empty; foreach (var attribute in _addressAttributeService.GetAllAddressAttributes()) { var controlId = string.Format(SmiCommonDefaults.AddressAttributeControlName, attribute.Id); var attributeValues = form[controlId]; switch (attribute.AttributeControlType) { case AttributeControlType.DropdownList: case AttributeControlType.RadioList: if (!StringValues.IsNullOrEmpty(attributeValues) && int.TryParse(attributeValues, out var value) && value > 0) { attributesXml = AddAddressAttribute(attributesXml, attribute, value.ToString()); } break; case AttributeControlType.Checkboxes: foreach (var attributeValue in attributeValues.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { if (int.TryParse(attributeValue, out value) && value > 0) { attributesXml = AddAddressAttribute(attributesXml, attribute, value.ToString()); } } break; case AttributeControlType.ReadonlyCheckboxes: //load read-only (already server-side selected) values var addressAttributeValues = _addressAttributeService.GetAddressAttributeValues(attribute.Id); foreach (var addressAttributeValue in addressAttributeValues) { if (addressAttributeValue.IsPreSelected) { attributesXml = AddAddressAttribute(attributesXml, attribute, addressAttributeValue.Id.ToString()); } } break; case AttributeControlType.TextBox: case AttributeControlType.MultilineTextbox: if (!StringValues.IsNullOrEmpty(attributeValues)) { attributesXml = AddAddressAttribute(attributesXml, attribute, attributeValues.ToString().Trim()); } break; case AttributeControlType.Datepicker: case AttributeControlType.ColorSquares: case AttributeControlType.ImageSquares: case AttributeControlType.FileUpload: default: break; } } return(attributesXml); }
protected override async Task <HandleRequestResult> HandleRemoteAuthenticateAsync() { var query = Request.Query; var protectedRequestToken = Request.Cookies[Options.StateCookie.Name]; var requestToken = Options.StateDataFormat.Unprotect(protectedRequestToken); if (requestToken == null) { return(HandleRequestResult.Fail("Invalid state cookie.")); } var properties = requestToken.Properties; var denied = query["denied"]; if (!StringValues.IsNullOrEmpty(denied)) { // Note: denied errors are special protocol errors indicating the user didn't // approve the authorization demand requested by the remote authorization server. // Since it's a frequent scenario (that is not caused by incorrect configuration), // denied errors are handled differently using HandleAccessDeniedErrorAsync(). var result = await HandleAccessDeniedErrorAsync(properties); return(!result.None ? result : HandleRequestResult.Fail("Access was denied by the resource owner or by the remote server.", properties)); } var returnedToken = query["oauth_token"]; if (StringValues.IsNullOrEmpty(returnedToken)) { return(HandleRequestResult.Fail("Missing oauth_token", properties)); } if (!string.Equals(returnedToken, requestToken.Token, StringComparison.Ordinal)) { return(HandleRequestResult.Fail("Unmatched token", properties)); } var oauthVerifier = query["oauth_verifier"]; if (StringValues.IsNullOrEmpty(oauthVerifier)) { return(HandleRequestResult.Fail("Missing or blank oauth_verifier", properties)); } var cookieOptions = Options.StateCookie.Build(Context, Clock.UtcNow); Response.Cookies.Delete(Options.StateCookie.Name, cookieOptions); var accessToken = await ObtainAccessTokenAsync(requestToken, oauthVerifier); var identity = new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, accessToken.UserId, ClaimValueTypes.String, ClaimsIssuer), new Claim(ClaimTypes.Name, accessToken.ScreenName, ClaimValueTypes.String, ClaimsIssuer), new Claim("urn:twitter:userid", accessToken.UserId, ClaimValueTypes.String, ClaimsIssuer), new Claim("urn:twitter:screenname", accessToken.ScreenName, ClaimValueTypes.String, ClaimsIssuer) }, ClaimsIssuer); JsonDocument user; if (Options.RetrieveUserDetails) { user = await RetrieveUserDetailsAsync(accessToken, identity); } else { user = JsonDocument.Parse("{}"); } using (user) { if (Options.SaveTokens) { properties.StoreTokens(new[] { new AuthenticationToken { Name = "access_token", Value = accessToken.Token }, new AuthenticationToken { Name = "access_token_secret", Value = accessToken.TokenSecret } }); } var ticket = await CreateTicketAsync(identity, properties, accessToken, user.RootElement); return(HandleRequestResult.Success(ticket)); } }
// BaseKey<delimiter>H<delimiter>HeaderName=HeaderValue<delimiter>Q<delimiter>QueryName=QueryValue1<subdelimiter>QueryValue2 public string CreateStorageVaryByKey(ResponseCachingContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var varyByRules = context.CachedVaryByRules; if (varyByRules == null) { throw new InvalidOperationException($"{nameof(CachedVaryByRules)} must not be null on the {nameof(ResponseCachingContext)}"); } if (StringValues.IsNullOrEmpty(varyByRules.Headers) && StringValues.IsNullOrEmpty(varyByRules.QueryKeys)) { return(varyByRules.VaryByKeyPrefix); } var request = context.HttpContext.Request; var builder = _builderPool.Get(); try { // Prepend with the Guid of the CachedVaryByRules builder.Append(varyByRules.VaryByKeyPrefix); // Vary by headers var headersCount = varyByRules?.Headers.Count ?? 0; if (headersCount > 0) { // Append a group separator for the header segment of the cache key builder.Append(KeyDelimiter) .Append('H'); var requestHeaders = context.HttpContext.Request.Headers; for (var i = 0; i < headersCount; i++) { var header = varyByRules !.Headers[i] ?? string.Empty; var headerValues = requestHeaders[header]; builder.Append(KeyDelimiter) .Append(header) .Append('='); var headerValuesArray = headerValues.ToArray(); Array.Sort(headerValuesArray, StringComparer.Ordinal); for (var j = 0; j < headerValuesArray.Length; j++) { builder.Append(headerValuesArray[j]); } } } // Vary by query keys if (varyByRules?.QueryKeys.Count > 0) { // Append a group separator for the query key segment of the cache key builder.Append(KeyDelimiter) .Append('Q'); if (varyByRules.QueryKeys.Count == 1 && string.Equals(varyByRules.QueryKeys[0], "*", StringComparison.Ordinal)) { // Vary by all available query keys var queryArray = context.HttpContext.Request.Query.ToArray(); // Query keys are aggregated case-insensitively whereas the query values are compared ordinally. Array.Sort(queryArray, QueryKeyComparer.OrdinalIgnoreCase); for (var i = 0; i < queryArray.Length; i++) { builder.Append(KeyDelimiter) .AppendUpperInvariant(queryArray[i].Key) .Append('='); var queryValueArray = queryArray[i].Value.ToArray(); Array.Sort(queryValueArray, StringComparer.Ordinal); for (var j = 0; j < queryValueArray.Length; j++) { if (j > 0) { builder.Append(KeySubDelimiter); } builder.Append(queryValueArray[j]); } } } else { for (var i = 0; i < varyByRules.QueryKeys.Count; i++) { var queryKey = varyByRules.QueryKeys[i] ?? string.Empty; var queryKeyValues = context.HttpContext.Request.Query[queryKey]; builder.Append(KeyDelimiter) .Append(queryKey) .Append('='); var queryValueArray = queryKeyValues.ToArray(); Array.Sort(queryValueArray, StringComparer.Ordinal); for (var j = 0; j < queryValueArray.Length; j++) { if (j > 0) { builder.Append(KeySubDelimiter); } builder.Append(queryValueArray[j]); } } } } return(builder.ToString()); } finally { _builderPool.Return(builder); } }
public async Task ProxyAsync_EmptyRequestHeader_Proxied() { var refererReceived = new TaskCompletionSource <StringValues>(TaskCreationOptions.RunContinuationsAsynchronously); var customReceived = new TaskCompletionSource <StringValues>(TaskCreationOptions.RunContinuationsAsynchronously); IForwarderErrorFeature proxyError = null; Exception unhandledError = null; var test = new TestEnvironment( context => { if (context.Request.Headers.TryGetValue(HeaderNames.Referer, out var header)) { refererReceived.SetResult(header); } else { refererReceived.SetException(new Exception($"Missing '{HeaderNames.Referer}' header in request")); } if (context.Request.Headers.TryGetValue("custom", out header)) { customReceived.SetResult(header); } else { customReceived.SetException(new Exception($"Missing 'custom' header in request")); } return(Task.CompletedTask); }, proxyBuilder => { }, proxyApp => { proxyApp.Use(async(context, next) => { try { Assert.True(context.Request.Headers.TryGetValue(HeaderNames.Referer, out var header)); var value = Assert.Single(header); Assert.True(StringValues.IsNullOrEmpty(value)); Assert.True(context.Request.Headers.TryGetValue("custom", out header)); value = Assert.Single(header); Assert.True(StringValues.IsNullOrEmpty(value)); await next(); proxyError = context.Features.Get <IForwarderErrorFeature>(); } catch (Exception ex) { unhandledError = ex; throw; } }); }, proxyProtocol: HttpProtocols.Http1); await test.Invoke(async proxyUri => { var proxyHostUri = new Uri(proxyUri); using var tcpClient = new TcpClient(proxyHostUri.Host, proxyHostUri.Port); await using var stream = tcpClient.GetStream(); await stream.WriteAsync(Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\n")); await stream.WriteAsync(Encoding.ASCII.GetBytes($"Host: {proxyHostUri.Host}:{proxyHostUri.Port}\r\n")); await stream.WriteAsync(Encoding.ASCII.GetBytes($"Content-Length: 0\r\n")); await stream.WriteAsync(Encoding.ASCII.GetBytes($"Connection: close\r\n")); await stream.WriteAsync(Encoding.ASCII.GetBytes($"Referer: \r\n")); await stream.WriteAsync(Encoding.ASCII.GetBytes($"custom: \r\n")); await stream.WriteAsync(Encoding.ASCII.GetBytes("\r\n")); await stream.WriteAsync(Encoding.ASCII.GetBytes("\r\n")); var buffer = new byte[4096]; var responseBuilder = new StringBuilder(); while (true) { var count = await stream.ReadAsync(buffer); if (count == 0) { break; } responseBuilder.Append(Encoding.ASCII.GetString(buffer, 0, count)); } var response = responseBuilder.ToString(); Assert.Null(proxyError); Assert.Null(unhandledError); Assert.StartsWith("HTTP/1.1 200 OK", response); Assert.True(refererReceived.Task.IsCompleted); var refererHeader = await refererReceived.Task; var referer = Assert.Single(refererHeader); Assert.True(StringValues.IsNullOrEmpty(referer)); Assert.True(customReceived.Task.IsCompleted); var customHeader = await customReceived.Task; var custom = Assert.Single(customHeader); Assert.True(StringValues.IsNullOrEmpty(custom)); }); }