Arquitectura, buenas prácticas y desarrollo sobre la nueva herramienta de Microsoft SharePoint 2016

Cómo utilizar API Graph en nuestros desarrollos

En los últimos meses hemos visto como en Microsoft han ido surgiendo aplicaciones en base a Graph. Quizás el notorio sea Delve… Por si alguien aún no lo conoce, Delve es una aplicación que muestra la información que considera que nos interesa. Para hacerlo, por un lado utiliza Machine Learning y, por otro utiliza Graph para obtener toda la información relativa a información a objetos que se encuentran en el Directorio Activo. En este artículo vamos a ver cómo podemos empezar a utilizarla 😉

La API Graph (por definirlo de una forma muy sencilla) es una unificación de todas las API’s que actualmente hay en Office 365 aprovechando el acceso a datos, inteligencia y conocimientos procedentes de la nube de Microsoft.

 

Manos a la Obra

Siempre que trabajemos con Autenticación contra Office 365, el primer paso es registrar nuestra aplicación dentro del tenant para indicarle cuales son los permisos que le vamos a otorgar. Lo podemos hacer de dos formas:

  1. Registramos la APP en el portal de Azure siguiendo los pasos indicando en este artículo y dando permisos para utilizar la API Graph.
  2. Utilizando Visual Studio (bien a la hora de crear el proyecto) o pulsanso botón derecho desde el explorador de Soluciones y pulsar sobre la Opción de Configure Azure AD Autenticación.

Una vez tenemos la aplicación autenticada, debemos tener claro los siguientes conceptos para el tema de la autenticación de nuestra aplicación contra el Azure Active Directory:

  • ClientID y SecretID: Son dos GUID que son los que identifican nuestra Aplicación
  • TenantID: Guid del Tenant donde va a estar alojada la Aplicación
  • Domain: Dominio donde esta la aplicación por ejemplo encamina.com
  • PostLogoutRedirectUri: Página de redirección de la autenticación una vez se autentica contra el AAD

Ahora desde la aplicación que estamos desarrollando, tendremos que autenticarnos contra el Azure Active Directory. Para ello, vamos a utilizar la librería ADAL. Una librería que la podemos obtener mediante Nugget, y cuya función principal es abstraernos de las peticiones que hay que hacer a Azure para autenticarse, lo cual simplifica mucho nuestro desarrollo. Si queréis saber más, podéis leer este artículo que escribí para la Revista CompartiMOSS.

Un ejemplo de autenticación utilizando ADAL en una aplicación ASP.NET puede ser el siguiente:

  app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    ClientId = Settings.ClientId,
                    Authority = string.Concat(Settings.AadInstance, Settings.TenantId),
                    PostLogoutRedirectUri = Settings.PostLogoutRedirectUri,
                    AuthenticationMode = AuthenticationMode.Active,
                    TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters { ValidateIssuer = false },


                    Notifications = new OpenIdConnectAuthenticationNotifications()
                    {
                        RedirectToIdentityProvider = n =>
                        {
                            // if signing out, add the id_token_hint
                            if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
                            {
                                var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");

                                if (idTokenHint != null)
                                {
                                    n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
                                }
                            }

                            return Task.FromResult(0);
                        },

                        AuthorizationCodeReceived = async (context) =>
                        {
                            var userObjectId = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
                            var encaminaAdal = new EncaminaAdalTokenCache(userObjectId);

                            var authContext = new AuthenticationContext(Settings.AzureADAuthority, encaminaAdal);

                            // Generate the parameterized URL for Azure login.
                            authContext.GetAuthorizationRequestURL(
                                Settings.O365UnifiedAPIResource,
                                Settings.ClientId,
                                new Uri(Settings.PostLogoutRedirectUri),
                                UserIdentifier.AnyUser,
                                null);

                            var authenticationResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
                                context.Code,
						        new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)),
                                new ClientCredential(Settings.ClientId, Settings.ClientSecret),                                                        
                                Settings.O365UnifiedAPIResource);
                            
                           
                        }

Este código lo ubicamos dentro del modulo de arranque de nuestra aplicación. En nuestro caso, hemos añadido un sistema de «Cache del Token», de tal forma que podamos ahorrarnos llamadas de autenticación al AAD.

Antes de hacer una petición, con este token lo que hacemos es verificar si el Token sigue vigente y que prolongue su vigencia de tal forma que mientras estemos haciendo uso de la API no tendremos ningún problema en acceder. En el caso de que estemos un periodo sin actividad y volvamos a utilizar la aplicación, esta nos volverá a pedir las credenciales. ¿A que os suena este comportamiento?

Para poder utilizar la Api Graph, en primer lugar obtendremos el Token de la siguiente forma:

     public async Task<string> GetTokenForApplication()
        {
                  
            var signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
            var userObjectID =
                    ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier")
                        .Value;
                // get a token for the Graph without triggering any user interaction (from the cache, via multi-resource refresh token, etc)
                var clientcred = new ClientCredential(this.clientId, this.clientSecret);
                // initialize AuthenticationContext with the token cache of the currently signed in user, as kept in the app's database
                var encaminaAdalTokenCache = new EncaminaAdalTokenCache(signedInUserID);
                var authenticationContext =
                    new AuthenticationContext(string.Concat(this.aadInstance, this.tenantId), encaminaAdalTokenCache);

                var authenticationResult =
                    await authenticationContext.AcquireTokenSilentAsync(this.O365UnifiedAPIResource, clientcred,
                        new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
                return authenticationResult.AccessToken;           
        }

Con este Token ya podemos realizar una consulta a la API. Por ejemplo, que nos devuelva todos los grupos a los que pertenece un usuario:

  public async Task<IEnumerable<GroupGraph>> GetGroups()
        {
            var accessToken = await this.service.GetTokenForApplication();
            IEnumerable<GroupGraph> groupGraphResponse = null;
            using (var client = new HttpClient())
            {
                using (var request = new HttpRequestMessage(HttpMethod.Get, Settings.GetMyGroupOrganization))
                {
                    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
                    using (var response = await client.SendAsync(request))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            using (var content = response.Content)
                            {
                                var result = await content.ReadAsStringAsync();
                                groupGraphResponse = JsonConvert.DeserializeObject<GroupResponse>(result).value;
                            }
                        }
                    }
                }
            }
            return groupGraphResponse;
        }

Para poder saber todos los EndPoint que hay disponibles, os recomiendo ir a la documentación oficial que proporciona Microsoft. También disponemos de una aplicación para poder realizadas a la API y podemos probar su funcionamiento, así como la devolución de los datos.

Resumen

Como hemos podido ver, Microsoft cada vez nos proporciona más herramientas para que podamos utilizar las servicios que hay en Office 365 en nuestros desarrollos. Ahora mismo la tendencia de que esté todo centralizado en un único producto (SharePoint) ha cambiado. Ahora todos son servicios que se pueden consumir desde la app/dispositivo que se quiera.

Esto proporciona más libertad a la hora de escoger/plantear una solución con lo cual todo el mundo sale beneficiado: el desarrollador porque no debe incrustar un desarrollo en una plataforma que no esta preparada para ello y el cliente porque recibe un desarrollo de más calidad y más acorde a las expectativas solicitadas.

mm

Sobre Adrián Díaz

Adrián Díaz es Ingeniero Informático por la Universidad Politécnica de Valencia. Es MVP de Microsoft en la categoría Office Development desde 2014, MCPD de SharePoint 2010, Microsoft Active Profesional y Microsoft Comunity Contribuitor 2012. Cofundador del grupo de usuarios de SharePoint de Levante LevaPoint. Lleva desarrollando con tecnologías Microsoft más de 10 años y desde hace 3 años está centrado en el desarrollo sobre SharePoint. Actualmente es Software & Cloud Architect Lead en ENCAMINA.
Esta entrada ha sido publicada en Azure, Office 365 y etiquetada como . Enlace permanente .

Suscríbete a Desarrollando sobre SharePoint

Recibe todas las actualizaciones semanalmente de nuestro blog

You have Successfully Subscribed!

ENCAMINA, piensa en colores