protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { Logger.LogInformation($"Entering authentication process with {nameof(AzureAuthenticationHandler)}"); if ((Context.User == null || Context.User.Identity == null || !Context.User.Identity.IsAuthenticated) && (Context.Request.Path != $"/{Options.AuthMeEndpoint}" || Context.Request.Path != $"/{Options.AuthRefreshEndpoint}")) { try { AzureAuthenticationResponse authResponse = await GetUserDetailsFromAzureAuthentication(); await GetRoleMembershipsForCurrentUser(authResponse); AuthenticationTicket ticket = BuildAuthenticationTicketFromAuthenticationResponse(authResponse); Logger.LogInformation("Setting context user to authenticated principal."); Context.User = ticket.Principal; Logger.LogInformation($"Authentication successful, exiting {nameof(AzureAuthenticationHandler)}"); return(AuthenticateResult.Success(ticket)); } catch (Exception ex) { Logger.LogError(ex, $"Failed to process identity in {nameof(AzureAuthenticationHandler)}"); return(AuthenticateResult.Fail(ex.Message)); } } else { Logger.LogInformation($"Identity already set, nothing to process in {nameof(AzureAuthenticationHandler)}"); return(AuthenticateResult.NoResult()); } }
private async Task GetRoleMembershipsForCurrentUser(AzureAuthenticationResponse userDetails) { string graphUrl = "https://graph.microsoft.com/v1.0/me/memberOf/$/microsoft.graph.group?$select=id,displayName,securityEnabled"; HttpRequestMessage graphRequest = new HttpRequestMessage(HttpMethod.Get, graphUrl); graphRequest.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", userDetails.GraphAccessToken); Logger.LogInformation("Making call to MS Graph to get group memberships"); using (HttpResponseMessage graphResponse = await _graphHttpClient.SendAsync(graphRequest)) { if (!graphResponse.IsSuccessStatusCode) { Logger.LogError($"Unable to fetch users group memberships. {graphResponse.StatusCode}"); throw new WebException($"Unable to fetch users group memberships. {graphResponse.StatusCode}"); } string content = await graphResponse.Content.ReadAsStringAsync(); try { Logger.LogInformation("Parsing group memberships"); JToken result = JToken.Parse(content); userDetails.GroupMemberships = result.Value <JArray>("value"); } catch { Logger.LogError("Could not retreive json from graph endpoint."); throw new WebException("Could not retreive json from graph endpoint."); } } }
private AuthenticationTicket BuildAuthenticationTicketFromAuthenticationResponse(AzureAuthenticationResponse userDetails) { string userId = userDetails.AuthMeResponse["user_id"].Value <string>(); Logger.LogDebug("Building authentication ticket for user : {0}", userId); GenericIdentity identity = new GenericIdentity(userId); Logger.LogInformation("Adding claims from payload"); List <Claim> claims = new List <Claim>(); foreach (JToken claim in userDetails.AuthMeResponse["user_claims"]) { claims.Add(new Claim(claim["typ"].ToString(), claim["val"].ToString())); } Logger.LogInformation("Adding claims for groups"); foreach (JToken group in userDetails.GroupMemberships) { bool isSecurityGroup = group["securityEnabled"].Value <bool>(); if (isSecurityGroup) { claims.Add(new Claim(Constants.GroupsClaimType, group["id"].ToString())); } } Logger.LogInformation("Add claims to new identity"); identity.AddClaims(claims); GenericPrincipal p = new GenericPrincipal(identity, null); return(new AuthenticationTicket(p, AzureAuthenticationDefaults.AuthenticationScheme)); }