public void Initialize(ClaimsPrincipal user, string operationId, string taskTitle) { OperationId = operationId; UserUrlPart = user.FindFirstValue(ClaimTypes.NameIdentifier); TaskTitle = taskTitle; hub.Clients.User(UserUrlPart).SendAsync("taskBegin", new { OperationId, TaskTitle }); logger.DescribeOperation(taskTitle); logger.OverrideUser(user); }
public XioResult <ClientModel> GetClient(ClientSpecModel model) { log.DescribeOperation("GetClient"); if (model.MicrosoftTenantId != Guid.Empty) { var existing = db.Clients.SingleOrDefault(x => x.MicrosoftTenantId == model.MicrosoftTenantId); if (existing != null) { log.LogInformation("GetClient returned existing client.", ("client", existing.UrlPart)); return(new XioResult <ClientModel>(true, mapper.Map <ClientModel>(existing))); } } if (!string.IsNullOrWhiteSpace(model.UrlPart)) { var existing = db.Clients.SingleOrDefault(x => x.UrlPart == model.UrlPart); if (existing != null) { log.LogInformation("GetClient returned existing client.", ("client", existing.UrlPart)); return(new XioResult <ClientModel>(true, mapper.Map <ClientModel>(existing))); } } if (model.Id > 0) { var existing = db.Clients.SingleOrDefault(x => x.Id == model.Id); if (existing != null) { log.LogInformation("GetClient returned existing client.", ("client", existing.UrlPart)); return(new XioResult <ClientModel>(true, mapper.Map <ClientModel>(existing))); } } // this is a create var newClient = db.Clients.Add(new Client { CountryCode = model.CountryCode, PostCode = model.PostCode, ProviderId = 1, // todo: something with providder Title = model.Title, MicrosoftTenantId = model.MicrosoftTenantId, UrlPart = db.GetUrlPart <Client>(model.Title) }); db.SaveChanges(); log.LogInformation("GetClient created new client.", ("client", newClient.Entity.UrlPart)); return(new XioResult <ClientModel>(true, mapper.Map <ClientModel>(newClient.Entity))); }
public async Task <IActionResult> ReceiveSSOCode(string code, string session_state) { log.DescribeOperation("Microsoft SSO Login"); // The secret for the authentication is stored in Azure Key Vault. Without this, you can not authenticate using this method. var client = new SecretClient(vaultUri: new Uri("https://binxio.vault.azure.net/"), credential: new DefaultAzureCredential()); var secret = client.GetSecret("BinxioAuthClientSecret"); var httpClient = httpFactory.CreateClient("msAuth"); var dict = new Dictionary <string, string>(); dict.Add("client_id", "27764a95-e99f-4501-a490-94f3c6cfee1a"); dict.Add("scope", "https://graph.microsoft.com/User.Read https://graph.microsoft.com/User.Read.All"); dict.Add("grant_type", "authorization_code"); dict.Add("code", code); dict.Add("session_state", session_state); dict.Add("redirect_url", Request.Scheme + "://" + Request.Host.Value + "/auth/configure_session"); dict.Add("client_secret", secret.Value.Value); FormUrlEncodedContent fuec = new FormUrlEncodedContent(dict); var request = httpClient.PostAsync("/e591b0fa-f212-4c0f-a347-f7f70460dadb/oauth2/v2.0/token", fuec).Result; if (request.IsSuccessStatusCode) { log.LogInformation("Token request successful."); var graph = httpFactory.CreateClient("msGraph"); // token var obj = JsonConvert.DeserializeObject <Dictionary <string, string> >(request.Content.ReadAsStringAsync().Result); var token = obj["access_token"]; // client info long clientId = -1; var orgRequest = new HttpRequestMessage(HttpMethod.Get, "v1.0/organization"); orgRequest.Headers.Add("Authorization", "Bearer " + token); var orgResponse = await graph.SendAsync(orgRequest); if (orgResponse.IsSuccessStatusCode) { log.LogInformation("Organization information request successful."); var org = JsonConvert.DeserializeObject <dynamic>(orgResponse.Content.ReadAsStringAsync().Result); if (((JArray)org.value).Count > 0) { // the client is the Azure AD tenant that provied the login. Create or get it here. var cli = clients.GetClient(new Common.Clients.ClientSpecModel { CountryCode = org.value[0].countryLetterCode, PostCode = org.value[0].postalCode, MicrosoftTenantId = org.value[0].id, Title = org.value[0].displayName, }); clientId = cli.Result.Id; } else { // todo: user has to create a client here. } } else { log.LogError("Unable to read information from Microsoft Graph endpoint /organization", ("statusCode", orgResponse.StatusCode.ToString()), ("errorMessage", orgResponse.Content.ReadAsStringAsync().Result)); return(Content(orgResponse.Content.ReadAsStringAsync().Result)); } var meRequest = new HttpRequestMessage(HttpMethod.Get, "v1.0/me"); meRequest.Headers.Add("Authorization", "Bearer " + token); var meResponse = await graph.SendAsync(meRequest); if (meResponse.IsSuccessStatusCode) { log.LogInformation("Request for user information successful."); var content = await meResponse.Content.ReadAsStringAsync(); var jobj = JsonConvert.DeserializeObject <dynamic>(content); var extant = await users.UserExists(new SingleUserQueryModel(emailAddress : (string)jobj.mail)); if (extant.IsSuccessful) { // log this user in. await HttpContext.SignInAsync(users.GetClaimsPrincipal(extant.Result)); return(Redirect("/")); } else { // create user and log in var createdUser = await users.CreateUser(new CreateUserModel { AccessToken = token, ClientId = clientId, DisplayName = jobj.displayName, FirstName = jobj.givenName, LastName = jobj.surname, EmailAddress = jobj.mail, JobTitle = jobj.jobTitle, MicrosoftAccountId = Guid.Parse((string)jobj.id), PreferredLanguage = jobj.preferredLanguage }); await HttpContext.SignInAsync(users.GetClaimsPrincipal(createdUser.Result)); return(Redirect("/")); } } else { log.LogError("Unable to read information from Microsoft Graph endpoint /me", ("statusCode", meResponse.StatusCode.ToString()), ("errorMessage", meResponse.Content.ReadAsStringAsync().Result)); return(Content(meResponse.Content.ReadAsStringAsync().Result)); } } else { log.LogError("Token request failed.", ("statusCode", request.StatusCode.ToString()), ("errorMessage", request.Content.ReadAsStringAsync().Result)); return(Content(request.Content.ReadAsStringAsync().Result)); } }