public HttpResponseMessage SignInCallBack(string callback) { diagnostics.WriteInformationTrace(TraceEventId.InboundParameters, "Client callback uri:{0}", callback); ClaimsPrincipal principal = this.User as ClaimsPrincipal; BootstrapContext context = principal.Identities.First().BootstrapContext as BootstrapContext; JWTSecurityToken jwtToken = context.SecurityToken as JWTSecurityToken; UriBuilder builder = new UriBuilder(new Uri(callback)); TimeSpan span = jwtToken.ValidTo.Subtract(jwtToken.ValidFrom); double seconds = span.TotalSeconds; string queryparam = string.Format("{0}={1}&{2}={3}", Constants.JWTCOOKIETOKEN_PARAM, HttpUtility.UrlEncode(jwtToken.RawData), Constants.JWTCOOKIETOKEN_VALIDTO_PARAM, HttpUtility.UrlEncode(seconds.ToString())); builder.Query = queryparam; var response = Request.CreateResponse(HttpStatusCode.Moved); response.Headers.Location = builder.Uri; diagnostics.WriteVerboseTrace(TraceEventId.OutboundParameters, "Redirect Uri post authentication process:{0}", response.Headers.Location); return(response); }
public HttpResponseMessage AuthorizeUser() { try { // Check if OAuthCode exists if not then redict to Windows Live if (!this.HasOAuthCode()) { diagnostics.WriteInformationTrace(TraceEventId.Flow, "Redirecting to live"); // Retreive the call back param string callBackUrl = this.Request.GetQueryNameValuePairs().Where(p => p.Key == "callBackUrl").FirstOrDefault().Value; string windowsLiveLoginUrl = this.GetWindowsLiveLoginUrl(callBackUrl); // Construct the Response var response = Request.CreateResponse(HttpStatusCode.Moved); response.Headers.Location = new Uri(windowsLiveLoginUrl); return(response); } else { diagnostics.WriteInformationTrace(TraceEventId.Flow, "Call back from live"); string code = this.Request.GetQueryNameValuePairs().Where(p => p.Key == SkyDriveConstants.OAuth_Code).FirstOrDefault().Value; string callBackUrl = this.Request.GetQueryNameValuePairs().Where(p => p.Key == "callBackUrl").FirstOrDefault().Value; // Get the AccessToken and Refresh Token by calling WindowsLive rest API OAuthToken token = GetWindowsLiveTokens(code, callBackUrl); diagnostics.WriteInformationTrace(TraceEventId.Flow, "Redirecting to client"); var response = Request.CreateResponse(HttpStatusCode.Moved); string clientCallBackUrl = AppendAuthTokensToCallBackUrl(token, callBackUrl); response.Headers.Location = new Uri(clientCallBackUrl); return(response); } } catch (Exception ex) { diagnostics.WriteErrorTrace(TraceEventId.Exception, ex); string error = ex.Message + ex.StackTrace + ex.GetType().ToString(); if (null != ex.InnerException) { error += ex.InnerException.Message + ex.InnerException.StackTrace + ex.InnerException.GetType().ToString(); } return(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, error)); } }
public override ClaimsPrincipal ValidateToken(JWTSecurityToken jwt, TokenValidationParameters validationParameters) { Check.IsNotNull(jwt, "jwt"); Check.IsNotNull(validationParameters, "validationParameters"); diagnostics.WriteInformationTrace(TraceEventId.InboundParameters, "JWT token details from ACS: {0}, {1}, {2}, {3}", jwt.Issuer, jwt.ValidFrom, jwt.ValidTo, jwt.RawData); string audienceUrl; if (this.Configuration != null) { audienceUrl = this.Configuration.AudienceRestriction.AllowedAudienceUris[0].ToString(); } else { audienceUrl = validationParameters.AllowedAudience; } // set up valid issuers if ((validationParameters.ValidIssuer == null) && (validationParameters.ValidIssuers == null || !validationParameters.ValidIssuers.Any())) { List <string> issuers = new List <string>(); issuers.AddRange(ConfigurationManager.AppSettings["Issuers"].Split(new[] { ',' })); validationParameters.ValidIssuers = issuers; } // setup signing token. if (validationParameters.SigningToken == null) { var resolver = (NamedKeyIssuerTokenResolver)this.Configuration.IssuerTokenResolver; if (resolver.SecurityKeys != null) { List <SecurityKey> skeys; if (resolver.SecurityKeys.TryGetValue(audienceUrl, out skeys)) { var tok = new NamedKeySecurityToken(audienceUrl, skeys); validationParameters.SigningToken = tok; } } } diagnostics.WriteInformationTrace(TraceEventId.Flow, "Successfully validated JWT token from ACS"); return(base.ValidateToken(jwt, validationParameters)); }
protected override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { Check.IsNotNull(request, "request"); HttpStatusCode statusCode; string token; if (request.RequestUri.AbsolutePath.Contains("/authenticate")) { return(base.SendAsync(request, cancellationToken)); } if (request.RequestUri.AbsolutePath.Contains("/signout")) { return(base.SendAsync(request, cancellationToken)); } if (request.RequestUri.AbsolutePath.Contains("/SignOutCallback")) { return(base.SendAsync(request, cancellationToken)); } if (request.RequestUri.AbsolutePath.Contains("/windowsLiveAuthorization")) { return(base.SendAsync(request, cancellationToken)); } if (request.RequestUri.AbsolutePath.Contains("api/GetSupportedIdentityProviders")) { return(base.SendAsync(request, cancellationToken)); } if (request.RequestUri.AbsolutePath.Contains("api/SignInCallBack")) { return(base.SendAsync(request, cancellationToken)); } if (!TryRetrieveToken(request, out token)) { statusCode = HttpStatusCode.Unauthorized; return(Task <HttpResponseMessage> .Factory.StartNew(() => new HttpResponseMessage(statusCode))); } try { diagnostics.WriteInformationTrace(TraceEventId.Flow, "Validating bearer token: {0}", token); string issuersValue = ConfigurationManager.AppSettings["Issuers"]; string signingSymmetricKey = ConfigurationManager.AppSettings["SigningSymmetricKey"]; string allowedAudience = ConfigurationManager.AppSettings["AllowedAudience"]; // Use JWTSecurityTokenHandler to validate the JWT token ApiJWTSecurityTokenHandler tokenHandler = new ApiJWTSecurityTokenHandler(); List <string> issuers = new List <string>(); issuers.AddRange(issuersValue.Split(new[] { ',' })); InMemorySymmetricSecurityKey securityKey = new InMemorySymmetricSecurityKey(Convert.FromBase64String(signingSymmetricKey)); NamedKeySecurityToken namedToken = new NamedKeySecurityToken(allowedAudience, new List <SecurityKey>() { securityKey }); // Set the expected properties of the JWT token in the TokenValidationParameters TokenValidationParameters validationParameters = new TokenValidationParameters() { AllowedAudience = allowedAudience, ValidIssuers = issuers, SigningToken = namedToken }; ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(token, validationParameters); ClaimsIdentity claimsIdentity = (ClaimsIdentity)claimsPrincipal.Identity; try { IUserService userService = (IUserService)GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IUserService)); User user = IdentityHelper.GetCurrentUser(userService, claimsPrincipal); foreach (var role in user.UserRoles) { if (!claimsIdentity.HasClaim(ClaimTypes.Role, role.Role.Name)) { claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, role.Role.Name)); } } } catch (UserNotFoundException) { // No need to do anything here because GetUsersByNameIdentifier action in UsersController will take care of sending appropriate http response. } Thread.CurrentPrincipal = claimsPrincipal; if (HttpContext.Current != null) { HttpContext.Current.User = claimsPrincipal; } diagnostics.WriteInformationTrace(TraceEventId.Flow, "Authorization token validated successfully"); return(base.SendAsync(request, cancellationToken)); } catch (SecurityTokenValidationException secutiryTokenValidationException) { FederatedAuthentication.WSFederationAuthenticationModule.SignOut(true); HttpResponseMessage response = request.CreateErrorResponse(HttpStatusCode.Unauthorized, secutiryTokenValidationException); return(Task <HttpResponseMessage> .Factory.StartNew(() => response)); } }
public HttpResponseMessage PostUsers([FromBody] UserInformation user) { string message = string.Empty; HttpStatusCode status = HttpStatusCode.Created; // Check if the model binding was successful and is in a valid state if (!ModelState.IsValid) { diagnostics.WriteInformationTrace(TraceEventId.InboundParameters, "Model state invalid"); return(Request.CreateErrorResponse(HttpStatusCode.BadRequest, string.Empty)); } try { // Check if the user service is valid Check.IsNotNull(this.userService, "userService"); Check.IsNotNull(user, "user"); user.NameIdentifier = Helpers.IdentityHelper.GetNameClaimTypeValue(this.User as ClaimsPrincipal); User registeredUser = this.userService.RegisterUser(user.ToEntity()); HttpResponseMessage response = Request.CreateResponse <UserInformation>(status, new UserInformation(registeredUser) ); response.Headers.Location = new Uri( Url.Link(Microsoft.Research.DataOnboarding.WebApi.Helpers.RouteConstants.DefaultApiRouteName, new { id = registeredUser.UserId } )); return(response); } catch (ArgumentNullException ane) { if (ane.ParamName.Equals("userService")) { message = MessageStrings.User_Service_Is_Null; status = HttpStatusCode.InternalServerError; } else if (ane.ParamName.Equals("user")) { message = MessageStrings.Invalid_User_Data; status = HttpStatusCode.BadRequest; } else { diagnostics.WriteErrorTrace(TraceEventId.Exception, "Invalid argument: {0}, {1}, {2}", ane.ParamName, ane.Message, ane.StackTrace); status = HttpStatusCode.InternalServerError; } } catch (ArgumentException ae) { message = string.Format(CultureInfo.CurrentCulture, MessageStrings.Argument_Error_Message_Template, ae.ParamName); status = HttpStatusCode.BadRequest; } catch (UserAlreadyExistsException) { message = MessageStrings.User_Already_Exists; status = HttpStatusCode.BadRequest; } catch (UserDataUpdateException) { diagnostics.WriteErrorTrace(TraceEventId.Exception, "UserDataUpdateException"); message = string.Concat(MessageStrings.User_Data_Update_Error_Message, MessageStrings.Contact_Support); status = HttpStatusCode.InternalServerError; } return(Request.CreateErrorResponse(status, message)); }
public HttpResponseMessage Publish() { string message = string.Empty; HttpStatusCode status = HttpStatusCode.OK; PostFileModel dataDetail = new PostFileModel(); try { diagnostics.WriteInformationTrace(TraceEventId.Flow, "Into publish"); if (HttpContext.Current.Request["PostFileData"] != null) { var postFileString = HttpContext.Current.Request["PostFileData"]; if (postFileString != null) { //diagnostics.WriteInformationTrace(TraceEventId.Flow, "Into publishing3"); /**************************************************** * TODO: Try catch block below is required to handle the case where the * clients send post request with JSON payload as plain text. * The API needs to be refactored to take the model as input * and have the MVC framework resolve/deserialize the payload * into model object. * **************************************************/ PostFileModel postFileData = default(PostFileModel); try { postFileData = Helper.DeSerializeObject <PostFileModel>(postFileString.DecodeFrom64(), "postFile"); } catch (Exception) { // If the data is not base 64 encoded using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(postFileString))) { DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(PostFileModel)); postFileData = (PostFileModel)jsonSerializer.ReadObject(stream); } } DM.Repository repository = repositoryService.GetRepositoryById(postFileData.SelectedRepositoryId); this.fileService = this.fileServiceFactory.GetFileService(repository.BaseRepository.Name); // Get the AuthToken from the request. TODO need to move below code to SkyDriveFileController. AuthToken userAuthToken = postFileData.UserAuthToken; userAuthToken.UserId = this.user.UserId; userAuthToken.RespositoryId = repository.RepositoryId; // Save the file details to db and publish logic this.fileService.SaveFile(postFileData); return(Request.CreateResponse <OperationStatus>(HttpStatusCode.OK, OperationStatus.CreateSuccessStatus())); } } } catch (ArgumentNullException ane) { diagnostics.WriteErrorTrace(TraceEventId.Exception, ane); status = HttpStatusCode.BadRequest; if (ane.ParamName.Equals("fileService")) { message = MessageStrings.File_Service_Is_Null; } else { message = ane.Message + ane.StackTrace + ane.GetType().ToString(); } } catch (Exception ex) { diagnostics.WriteErrorTrace(TraceEventId.Exception, ex); message = ex.Message + ex.StackTrace + ex.GetType().ToString(); if (null != ex.InnerException) { message += ex.InnerException.Message + ex.InnerException.StackTrace + ex.InnerException.GetType().ToString(); } status = HttpStatusCode.InternalServerError; } return(Request.CreateErrorResponse(status, message)); }
public async Task <HttpResponseMessage> Post(string fileName, string fileExtension, string contentType) { try { Check.IsNotEmptyOrWhiteSpace(fileName, "fileName"); Check.IsNotEmptyOrWhiteSpace(fileExtension, "fileExtension"); Check.IsNotEmptyOrWhiteSpace(contentType, "contentType"); byte[] fileContent = default(byte[]); if (Request.Content.IsMimeMultipartContent("form-data")) { string root = Path.GetTempPath(); MultipartFormDataStreamProvider streamProvider = new MultipartFormDataStreamProvider(root); await Request.Content.ReadAsMultipartAsync(streamProvider); MultipartFileData multipartFileData = streamProvider.FileData.First(); /********************************************************* * This API under stress can cause IO exception, for File read * or Delete operation. More details @https://aspnetwebstack.codeplex.com/workitem/176 * Following logic retries file operations at most 3 times * inducing the recommended delay in case of failure. */ int executionDelay = 50, readRetryCount = 3, deleteRetryCount = 3; // Retry mechanics for file read operation while (readRetryCount-- > 0) { try { using (FileStream fileSource = new FileStream(multipartFileData.LocalFileName, FileMode.Open, FileAccess.Read)) { fileContent = await fileSource.GetBytesAsync(); } break; } catch (IOException ioe) { diagnostics.WriteErrorTrace(TraceEventId.Exception, ioe.ToString()); } await Task.Delay(executionDelay); } // Retry mechanics for file delete operation while (deleteRetryCount-- > 0) { try { await Task.Factory.StartNew(() => System.IO.File.Delete(multipartFileData.LocalFileName)); break; } catch (IOException ioe) { diagnostics.WriteErrorTrace(TraceEventId.Exception, ioe.ToString()); } await Task.Delay(executionDelay); } } else { var bufferlessInputStream = HttpContext.Current.Request.GetBufferlessInputStream(); Check.IsNotNull(bufferlessInputStream, "HttpContext.Current.Request.GetBufferlessInputStream()"); fileContent = await bufferlessInputStream.GetBytesAsync(); } this.fileService.ValidateForUpload(fileName, this.user.UserId); DataFile dataFile = new DataFile { FileContent = fileContent, ContentType = contentType, FileName = fileName, CreatedBy = this.user.UserId, FileExtentsion = fileExtension }; IFileHandler fileHandler = this.fileHandlerFactory.GetFileHandler(contentType, this.user.UserId); diagnostics.WriteInformationTrace(Utilities.Enums.TraceEventId.Flow, "blob-before file upload"); var uploadedDataDetails = fileHandler.Upload(dataFile); diagnostics.WriteInformationTrace(Utilities.Enums.TraceEventId.Flow, "blob-after file upload"); if (!uploadedDataDetails.Any() || uploadedDataDetails.Any(dd => dd.FileDetail.FileId == 0)) { return(Request.CreateErrorResponse(HttpStatusCode.BadRequest, MessageStrings.UploadFailed)); } return(Request.CreateResponse <IEnumerable <DataDetail> >(HttpStatusCode.OK, uploadedDataDetails)); } catch (ValidationException validationException) { HttpError error = validationException.GetHttpError(string.Format(MessageStrings.Upload_Validation_Error_Template, validationException.FileName)); return(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, error)); } catch (ArgumentException ex) { message = string.Format(CultureInfo.CurrentCulture, MessageStrings.Argument_Error_Message_Template, ex.ParamName); status = HttpStatusCode.BadRequest; } return(Request.CreateErrorResponse(status, message)); }