├── .gitignore ├── 01 intro-restapi.pptx ├── 02 raw-restapi.pptx ├── 03 aspnetmvc-restapi.pptx ├── Demos ├── 01-arp-app │ └── README.md ├── 02-create-app │ └── README.md ├── 03-create-aspnet-mvcapp │ ├── .vs │ │ ├── MSGraphCalendarViewer │ │ │ └── v15 │ │ │ │ └── Server │ │ │ │ └── sqlite3 │ │ │ │ ├── db.lock │ │ │ │ ├── storage.ide │ │ │ │ ├── storage.ide-shm │ │ │ │ └── storage.ide-wal │ │ └── config │ │ │ └── applicationhost.config │ ├── MSGraphCalendarViewer.sln │ ├── MSGraphCalendarViewer │ │ ├── App_Start │ │ │ ├── BundleConfig.cs │ │ │ ├── FilterConfig.cs │ │ │ ├── RouteConfig.cs │ │ │ └── Startup.Auth.cs │ │ ├── ApplicationInsights.config │ │ ├── Content │ │ │ ├── Site.css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap-theme.min.css.map │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ ├── Controllers │ │ │ ├── AccountController.cs │ │ │ └── HomeController.cs │ │ ├── Global.asax │ │ ├── Global.asax.cs │ │ ├── Helpers │ │ │ ├── IAuthProvider.cs │ │ │ └── SampleAuthProvider.cs │ │ ├── MSGraphCalendarViewer.csproj │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── Scripts │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ ├── jquery-3.3.1.intellisense.js │ │ │ ├── jquery-3.3.1.js │ │ │ ├── jquery-3.3.1.min.js │ │ │ ├── jquery-3.3.1.min.map │ │ │ ├── jquery-3.3.1.slim.js │ │ │ ├── jquery-3.3.1.slim.min.js │ │ │ ├── jquery-3.3.1.slim.min.map │ │ │ ├── jquery.validate-vsdoc.js │ │ │ ├── jquery.validate.js │ │ │ ├── jquery.validate.min.js │ │ │ ├── jquery.validate.unobtrusive.js │ │ │ ├── jquery.validate.unobtrusive.min.js │ │ │ └── modernizr-2.8.3.js │ │ ├── Startup.cs │ │ ├── TokenStorage │ │ │ └── SessionTokenCache.cs │ │ ├── Views │ │ │ ├── Home │ │ │ │ ├── About.cshtml │ │ │ │ ├── Contact.cshtml │ │ │ │ └── Index.cshtml │ │ │ ├── Shared │ │ │ │ ├── Error.cshtml │ │ │ │ ├── _Layout.cshtml │ │ │ │ └── _LoginPartial.cshtml │ │ │ ├── Web.config │ │ │ └── _ViewStart.cshtml │ │ ├── Web.Debug.config │ │ ├── Web.Release.config │ │ ├── Web.config │ │ ├── favicon.ico │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── packages.config │ └── README.md ├── 04-leverage-msgraphsdk │ ├── .vs │ │ ├── MSGraphCalendarViewer │ │ │ └── v15 │ │ │ │ └── Server │ │ │ │ └── sqlite3 │ │ │ │ ├── db.lock │ │ │ │ ├── storage.ide │ │ │ │ ├── storage.ide-shm │ │ │ │ └── storage.ide-wal │ │ └── config │ │ │ └── applicationhost.config │ ├── MSGraphCalendarViewer.sln │ ├── MSGraphCalendarViewer │ │ ├── App_Start │ │ │ ├── BundleConfig.cs │ │ │ ├── FilterConfig.cs │ │ │ ├── RouteConfig.cs │ │ │ └── Startup.Auth.cs │ │ ├── ApplicationInsights.config │ │ ├── Content │ │ │ ├── Site.css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap-theme.min.css.map │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ ├── Controllers │ │ │ ├── AccountController.cs │ │ │ ├── CalendarController.cs │ │ │ └── HomeController.cs │ │ ├── Global.asax │ │ ├── Global.asax.cs │ │ ├── Helpers │ │ │ ├── IAuthProvider.cs │ │ │ └── SampleAuthProvider.cs │ │ ├── MSGraphCalendarViewer.csproj │ │ ├── Models │ │ │ ├── GraphOdataResponse.cs │ │ │ └── GraphService.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── Scripts │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ ├── jquery-3.3.1.intellisense.js │ │ │ ├── jquery-3.3.1.js │ │ │ ├── jquery-3.3.1.min.js │ │ │ ├── jquery-3.3.1.min.map │ │ │ ├── jquery-3.3.1.slim.js │ │ │ ├── jquery-3.3.1.slim.min.js │ │ │ ├── jquery-3.3.1.slim.min.map │ │ │ ├── jquery.validate-vsdoc.js │ │ │ ├── jquery.validate.js │ │ │ ├── jquery.validate.min.js │ │ │ ├── jquery.validate.unobtrusive.js │ │ │ ├── jquery.validate.unobtrusive.min.js │ │ │ └── modernizr-2.8.3.js │ │ ├── Startup.cs │ │ ├── TokenStorage │ │ │ └── SessionTokenCache.cs │ │ ├── Views │ │ │ ├── Calendar │ │ │ │ └── Index.cshtml │ │ │ ├── Home │ │ │ │ ├── About.cshtml │ │ │ │ ├── Contact.cshtml │ │ │ │ └── Index.cshtml │ │ │ ├── Shared │ │ │ │ ├── Error.cshtml │ │ │ │ ├── _Layout.cshtml │ │ │ │ └── _LoginPartial.cshtml │ │ │ ├── Web.config │ │ │ └── _ViewStart.cshtml │ │ ├── Web.Debug.config │ │ ├── Web.Release.config │ │ ├── Web.config │ │ ├── favicon.ico │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── packages.config │ └── README.md └── README.md ├── Images ├── aad-api-permissions.PNG ├── aad-application-id.PNG ├── aad-consent.png ├── aad-copy-client-secret.png ├── aad-delegated-permissions.PNG ├── aad-implicit-grant.png ├── aad-new-client-secret.png ├── aad-portal-app-registrations.png ├── aad-register-an-app.PNG ├── aad-request-api-permissions.PNG ├── arp-update-app-01.png ├── calendar-events-01.png ├── postman-accesstoken-01.png ├── postman-accesstoken-02.png ├── postman-graph-01.png ├── postman-graph-02.png ├── postman-graph-03.png ├── postman-login-01.png ├── postman-login-02.png ├── postman-login-03.png ├── vs-calendarController-01.png ├── vs-newproj-01.png └── vs-sslenabled.png ├── LICENSE ├── Lab.md ├── LabFiles ├── AccountController.cs ├── GraphOdataResponse.cs ├── IAuthProvider.cs ├── SampleAuthProvider.cs ├── SessionTokenCache.cs ├── Startup.Auth.cs ├── Startup.cs └── _LoginPartial.cshtml ├── README-Localized ├── README-es-es.md ├── README-fr-fr.md ├── README-ja-jp.md ├── README-pt-br.md ├── README-ru-ru.md └── README-zh-cn.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | [Dd]ebug/ 11 | [Dd]ebugPublic/ 12 | [Rr]elease/ 13 | x64/ 14 | build/ 15 | bld/ 16 | [Bb]in/ 17 | [Oo]bj/ 18 | 19 | # MSTest test Results 20 | [Tt]est[Rr]esult*/ 21 | [Bb]uild[Ll]og.* 22 | 23 | #NUNIT 24 | *.VisualState.xml 25 | TestResult.xml 26 | 27 | # Build Results of an ATL Project 28 | [Dd]ebugPS/ 29 | [Rr]eleasePS/ 30 | dlldata.c 31 | 32 | *_i.c 33 | *_p.c 34 | *_i.h 35 | *.ilk 36 | *.meta 37 | *.obj 38 | *.pch 39 | *.pdb 40 | *.pgc 41 | *.pgd 42 | *.rsp 43 | *.sbr 44 | *.tlb 45 | *.tli 46 | *.tlh 47 | *.tmp 48 | *.tmp_proj 49 | *.log 50 | *.vspscc 51 | *.vssscc 52 | .builds 53 | *.pidb 54 | *.svclog 55 | *.scc 56 | 57 | # Chutzpah Test files 58 | _Chutzpah* 59 | 60 | # Visual C++ cache files 61 | ipch/ 62 | *.aps 63 | *.ncb 64 | *.opensdf 65 | *.sdf 66 | *.cachefile 67 | 68 | # Visual Studio profiler 69 | *.psess 70 | *.vsp 71 | *.vspx 72 | 73 | # TFS 2012 Local Workspace 74 | $tf/ 75 | 76 | # Guidance Automation Toolkit 77 | *.gpState 78 | 79 | # ReSharper is a .NET coding add-in 80 | _ReSharper*/ 81 | *.[Rr]e[Ss]harper 82 | *.DotSettings.user 83 | 84 | # JustCode is a .NET coding addin-in 85 | .JustCode 86 | 87 | # TeamCity is a build add-in 88 | _TeamCity* 89 | 90 | # DotCover is a Code Coverage Tool 91 | *.dotCover 92 | 93 | # NCrunch 94 | *.ncrunch* 95 | _NCrunch_* 96 | .*crunch*.local.xml 97 | 98 | # MightyMoose 99 | *.mm.* 100 | AutoTest.Net/ 101 | 102 | # Web workbench (sass) 103 | .sass-cache/ 104 | 105 | # Installshield output folder 106 | [Ee]xpress/ 107 | 108 | # DocProject is a documentation generator add-in 109 | DocProject/buildhelp/ 110 | DocProject/Help/*.HxT 111 | DocProject/Help/*.HxC 112 | DocProject/Help/*.hhc 113 | DocProject/Help/*.hhk 114 | DocProject/Help/*.hhp 115 | DocProject/Help/Html2 116 | DocProject/Help/html 117 | 118 | # Click-Once directory 119 | publish/ 120 | 121 | # Publish Web Output 122 | *.[Pp]ublish.xml 123 | *.azurePubxml 124 | 125 | # NuGet Packages Directory 126 | packages/ 127 | ## TODO: If the tool you use requires repositories.config uncomment the next line 128 | #!packages/repositories.config 129 | 130 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 131 | # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented) 132 | !packages/build/ 133 | 134 | # Windows Azure Build Output 135 | csx/ 136 | *.build.csdef 137 | 138 | # Windows Store app package directory 139 | AppPackages/ 140 | 141 | # Others 142 | sql/ 143 | *.Cache 144 | ClientBin/ 145 | [Ss]tyle[Cc]op.* 146 | ~$* 147 | *~ 148 | *.dbmdl 149 | *.dbproj.schemaview 150 | *.publishsettings 151 | node_modules/ 152 | 153 | # RIA/Silverlight projects 154 | Generated_Code/ 155 | 156 | # Backup & report files from converting an old project file to a newer 157 | # Visual Studio version. Backup files are not needed, because we have git ;-) 158 | _UpgradeReport_Files/ 159 | Backup*/ 160 | UpgradeLog*.XML 161 | UpgradeLog*.htm 162 | 163 | # SQL Server files 164 | *.mdf 165 | *.ldf 166 | 167 | # Business Intelligence projects 168 | *.rdl.data 169 | *.bim.layout 170 | *.bim_*.settings 171 | 172 | # Microsoft Fakes 173 | FakesAssemblies/ 174 | 175 | # MacOS files 176 | **.DS_Store -------------------------------------------------------------------------------- /01 intro-restapi.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/01 intro-restapi.pptx -------------------------------------------------------------------------------- /02 raw-restapi.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/02 raw-restapi.pptx -------------------------------------------------------------------------------- /03 aspnetmvc-restapi.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/03 aspnetmvc-restapi.pptx -------------------------------------------------------------------------------- /Demos/01-arp-app/README.md: -------------------------------------------------------------------------------- 1 | # Create an Azure AD web application with the App Registration Portal 2 | 3 | In this demo, you will create a new Azure AD native application using the App Registry Portal (ARP). 4 | 5 | 1. Visit the [Azure Active Directory admin center](https://aad.portal.azure.com) and login using a **Work or School Account**. 6 | 7 | 1. Select **Azure Active Directory** in the left-hand navigation, then select **App registrations (Preview)** under **Manage**. 8 | 9 | ![A screenshot of the App registrations ](../../Images/aad-portal-app-registrations.png) 10 | 11 | 1. Select **New registration**. On the **Register an application** page, set the values as follows. 12 | 13 | - Set a preferred **Name** e.g. `WebO365CalendarEvents`. 14 | - Set **Supported account types** to **Accounts in any organizational directory**. 15 | - Under **Redirect URI**, set the first drop-down to Web and set the value to the `https://localhost:1234`. 16 | > You will eventually have to come back to add a new URL to this when we know the SSL of the ASP.NET application that you will build in an exercise later in this lab. 17 | 18 | ![A screenshot of the Register an application page](../../Images/aad-register-an-app.PNG) 19 | 20 | 1. Choose **Register**. On the **WebO365CalendarEvents** page, copy the value of the **Application (client) ID** and save it, you will need it in the next step. 21 | 22 | ![A screenshot of Application Id](../../Images/aad-application-id.PNG) 23 | 24 | 1. Select **Authentication** under **Manage**. Locate the **Implicit grant** section and enable **ID tokens**. Choose **Save**. 25 | 26 | ![A screenshot of Implicit grant](../../Images/aad-implicit-grant.png) 27 | 28 | 1. Select **Certificates & secrets** under **Manage**. Select the **New client secret** button. Enter a value in **Description** and select one of the options for **Expires** and choose **Add**. 29 | 30 | ![A screenshot of the Add a client secret dialog](../../Images/aad-new-client-secret.png) 31 | 32 | 1. Copy the client secret value before you leave this page. You will need it in the next step. 33 | 34 | > **IMPORTANT**: 35 | > This client secret is never shown again, so make sure you copy it now. 36 | 37 | ![A screenshot of the newly added client secret](../../Images/aad-copy-client-secret.png) 38 | 39 | 1. From the **Manage** page, select **API permissions** > **Add a permission**. 40 | 41 | ![A screenshot of Select API Permissions](../../Images/aad-api-permissions.PNG) 42 | 43 | 1. Choose **Microsoft API** > **Microsoft Graph**. 44 | 45 | ![A screenshot of Request API permissions](../../Images/aad-request-api-permissions.PNG) 46 | 47 | 1. Choose **Delegated permissions**. In the search box, type **Calendars.Read** and select the first option from the list. Select **Add permissions**. 48 | 49 | ![A screenshot of Application permissions](../../Images/aad-delegated-permissions.PNG) -------------------------------------------------------------------------------- /Demos/02-create-app/README.md: -------------------------------------------------------------------------------- 1 | # Working with the Microsoft Graph REST API in Postman 2 | 3 | In this demo, you will use a combination of the browser and the HTTP tool [Postman](https://www.getpostman.com/) to authenticate with Azure AD and request data from the Microsoft Graph REST API with raw HTTP requests. This will help you understand the processes involved in authenticating. 4 | 5 | ## Authenticate with Azure AD and obtain an OAuth2 access token 6 | 7 | The first step is to authenticate with Azure AD to establish your identity. Once you do that, you can request an access token. 8 | 9 | 1. Login and obtain an Azure AD OAuth2 authorization code: 10 | 1. Take the following URL and replace the **{{REPLACE_APPLICATION_ID}}** with the ID you copied previously when creating the Azure AD application in the last step. This is the Azure AD v2 authorization endpoint. 11 | 12 | > Note that the values within the different querystring values are URL encoded. The **scope** value is a space delimited list of the scopes (*aka: permissions*) your application is requesting. In this case: openid, https://graph.microsoft.com/user.read & https://graph.microsoft.com/calendars.read 13 | 14 | ```text 15 | https://login.microsoftonline.com/common/oauth2/v2.0/authorize? 16 | client_id={{REPLACE_APPLICATION_ID}} 17 | &response_type=code 18 | &redirect_uri=https%3A%2F%2Flocalhost%3A1234 19 | &response_mode=query 20 | &scope=openid%20https%3A%2F%2Fgraph.microsoft.com%2Fuser.read%20https%3A%2F%2Fgraph.microsoft.com%2Fcalendars.read 21 | &state=12345 22 | ``` 23 | 24 | 1. Open a browser. 25 | 1. Past the URL into the browser. 26 | 1. When prompted to login, use your Work or School account. 27 | 28 | ![Screenshot of the Azure AD login prompt](../../Images/postman-login-01.png) 29 | 30 | 1. After a successful login, you will be prompted to consent to granting the application specific permissions. Review the permissions which match the ones you requested in the URL, and select **Accept**. 31 | 32 | ![Screenshot of the Azure AD common consent dialog](../../Images/postman-login-02.png) 33 | 34 | 1. After accepting the permission consent request, Azure AD will send you the redirect URI specified in the URL you provided. This is the **https://localhost:1234** site, which isn't running so it will show up as a broken page. 35 | 36 | Look at the URL and locate the **code** querystring value. Copy the entire value of the **code** property in the querystring as you will use that to request an access token from Azure AD's v2 token endpoint. 37 | 38 | ![Screenshot of the response with the OAuth2 authorization code](../../Images/postman-login-03.png) 39 | 40 | The code value will look like the following. Be sure to only copy the **code** value as there are other querystring properties of **state** and **session_state** that are added after the **code**. 41 | 42 | ```text 43 | OAQABAAIAAADX8GCi6Js6SK82TsD2Pb7rrzh_YHqdEhLMktqE5WgIgk4jirwDCnPbN-mj4sfVOf_8txfxxlK3xNjNx4dYZH5RNcWrLRtXdl6Amf3U0U_dzJq8csCv84ZsxzYyBafZuPy-7ME7Yt3QRlt0pTJLYC8yUwLrtFEwZio3DZJbcFZhufEkT8gpwboIjhydq1QRZPIoJuXB9dIQ4Dk1p8ziEAj22K1nmEnUXBqtUTmDowGkjJ74ucEVEaOuq6Sbr6N_yUflgzryQq62aKRFr5IxjCETchkRDtX7gYgjCq4kDdvXiYxBhLY6QNTtWp3l1raOK9rpPOfmD4lHQHRGT8LoXrDmR9lCnFKjWfZmF6hkLPwE_6KP-v7oTewgfRZXIYM_zy-GeuQPoe6gTJra2q3y_I3xOJZVkOMk6l-DJohVsb8XkMpfnSWmMZA0xud461jPhqTHo-wjSCBqGKfHsoIjuujqKhXloigpcIYzdwZmtA6ejsKbW-c4Fy17NSbCmkSIjVACsbW3jGt5_JNEGtEA4k8LC_7MHNMGF0NXG0FnjNW7kJrexHV0ygvU_xApgt8kvf81pDAnyxmWR6QP7QY0aHKBagC0gOdzF_YAu25UjTYnmLYxW1Vje6lLIe_yA6qAZ1kH4XStTaDwaH2-DAMzJ_CAIAA 44 | ``` 45 | 46 | Use the authorization code to request an OAuth2 access token from Azure AD that will be used to issue calls to the Microsoft Graph 47 | 48 | 1. Obtain an OAuth2 access token from Azure AD: 49 | 1. Open **Postman**. 50 | 1. Use the following image to guide you in setting the correct values: 51 | * Set the request type to **POST** 52 | * Set the URL to **https://login.microsoftonline.com/common/oauth2/v2.0/token** 53 | * Select the **Body** tab 54 | * Select the radio button option **form-data** 55 | * Add a header **client_id** and set it's value to the Azure AD application ID copied previously. 56 | * Add a header **client_secret** and set it's value to the Azure AD application password copied previously. 57 | * Add a header **scope** and set it's value to **openid https://graph.microsoft.com/user.read https://graph.microsoft.com/calendars.read** 58 | * Add a header **redirect_uri** and set it's value to **https://localhost:1234** 59 | * Add a header **grant_type** and set it's value to **authorization_code** 60 | * Add a header **code** and set it's value to the value of the authorization code requested in the last step. 61 | 62 | ![Screenshot of the Postman with the access token request](../../Images/postman-accesstoken-01.png) 63 | 64 | 1. Select **Send** to execute the request. 65 | 1. The request's response is displayed in the lower half of the Postman application. The response contains the 66 | 1. **scopes** - the access token has permissions to request 67 | 1. **access_token** - a JWT token used to authenticate with the Microsoft Graph REST API 68 | 1. **id_token** - a JWT token that contains details about the user who logged in 69 | 70 | ## Use the Microsoft Graph REST API 71 | 72 | Use the access token to to get first 20 calendar events from your Office 365 calendar using the Microsoft Graph REST API. 73 | 74 | 1. Within **Postman**, select the **+** (**plus**) icon to create a new tab for a new request: 75 | 76 | ![Screenshot of the Postman creating a new tab](../../Images/postman-graph-01.png) 77 | 78 | 1. Verify the access token (id_token) obtained in the previous steps works by requesting your own details from the Microsoft Graph REST API: 79 | 1. Set the request type to **GET** 80 | 1. Set the endpoint to **https://graph.microsoft.com/v1.0/me** 81 | 1. Select the **Headers** tab 82 | 1. Add a new header: 83 | * **Key**: Authorization 84 | * **Value**: Bearer {{REPLACE_WITH_ACCESS_TOKEN}} 85 | 1. Select **Send** to execute the request 86 | 87 | ![Screenshot of Postman request and response from the Microsoft Graph REST API](../../Images/postman-graph-02.png) 88 | 89 | 1. Update the request to obtain a list the top 20 events from your Office 365 calendar: 90 | 1. In Postman, change the endpoint to **https://graph.microsoft.com/v1.0/me/events** 91 | 1. Select the **Params** button to open the querystring parameter builder. 92 | 1. Add the following parameters: 93 | * **$select**: subject,start,end 94 | * **$top**: 20 95 | * **$skip**: 0 96 | 1. Select **Send** to execute the request 97 | 98 | ![Screenshot of Postman request and response from the Microsoft Graph REST API](../../Images/postman-graph-03.png) 99 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/.vs/MSGraphCalendarViewer/v15/Server/sqlite3/db.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Demos/03-create-aspnet-mvcapp/.vs/MSGraphCalendarViewer/v15/Server/sqlite3/db.lock -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/.vs/MSGraphCalendarViewer/v15/Server/sqlite3/storage.ide: -------------------------------------------------------------------------------- 1 | SQLite format 3@ .A  -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/.vs/MSGraphCalendarViewer/v15/Server/sqlite3/storage.ide-shm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Demos/03-create-aspnet-mvcapp/.vs/MSGraphCalendarViewer/v15/Server/sqlite3/storage.ide-shm -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/.vs/MSGraphCalendarViewer/v15/Server/sqlite3/storage.ide-wal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Demos/03-create-aspnet-mvcapp/.vs/MSGraphCalendarViewer/v15/Server/sqlite3/storage.ide-wal -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.168 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSGraphCalendarViewer", "MSGraphCalendarViewer\MSGraphCalendarViewer.csproj", "{0133341B-C403-47F8-8D6E-9CAF30973AFC}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {0133341B-C403-47F8-8D6E-9CAF30973AFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {0133341B-C403-47F8-8D6E-9CAF30973AFC}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {0133341B-C403-47F8-8D6E-9CAF30973AFC}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {0133341B-C403-47F8-8D6E-9CAF30973AFC}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {F4B9E8BA-9D0B-4B5D-A759-E8CC5EBFDB41} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/App_Start/BundleConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Optimization; 3 | 4 | namespace MSGraphCalendarViewer 5 | { 6 | public class BundleConfig 7 | { 8 | // For more information on bundling, visit https://go.microsoft.com/fwlink/?LinkId=301862 9 | public static void RegisterBundles(BundleCollection bundles) 10 | { 11 | bundles.Add(new ScriptBundle("~/bundles/jquery").Include( 12 | "~/Scripts/jquery-{version}.js")); 13 | 14 | bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( 15 | "~/Scripts/jquery.validate*")); 16 | 17 | // Use the development version of Modernizr to develop with and learn from. Then, when you're 18 | // ready for production, use the build tool at https://modernizr.com to pick only the tests you need. 19 | bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( 20 | "~/Scripts/modernizr-*")); 21 | 22 | bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( 23 | "~/Scripts/bootstrap.js")); 24 | 25 | bundles.Add(new StyleBundle("~/Content/css").Include( 26 | "~/Content/bootstrap.css", 27 | "~/Content/site.css")); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/App_Start/FilterConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | 4 | namespace MSGraphCalendarViewer 5 | { 6 | public class FilterConfig 7 | { 8 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) 9 | { 10 | filters.Add(new HandleErrorAttribute()); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/App_Start/RouteConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Routing; 7 | 8 | namespace MSGraphCalendarViewer 9 | { 10 | public class RouteConfig 11 | { 12 | public static void RegisterRoutes(RouteCollection routes) 13 | { 14 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 15 | 16 | routes.MapRoute( 17 | name: "Default", 18 | url: "{controller}/{action}/{id}", 19 | defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 20 | ); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/App_Start/Startup.Auth.cs: -------------------------------------------------------------------------------- 1 | using System.Configuration; 2 | using System.IdentityModel.Claims; 3 | using System.Threading.Tasks; 4 | using System.Web; 5 | using Owin; 6 | using MSGraphCalendarViewer.TokenStorage; 7 | using Microsoft.Identity.Client; 8 | using Microsoft.IdentityModel.Tokens; 9 | using Microsoft.Owin.Security; 10 | using Microsoft.Owin.Security.Cookies; 11 | using Microsoft.Owin.Security.OpenIdConnect; 12 | 13 | namespace MSGraphCalendarViewer 14 | { 15 | public partial class Startup 16 | { 17 | // The appId is used by the application to uniquely identify itself to Azure AD. 18 | // The appSecret is the application's password. 19 | // The redirectUri is where users are redirected after sign in and consent. 20 | // The graphScopes are the Microsoft Graph permission scopes that are used by this sample: User.Read Mail.Send 21 | private static string appId = ConfigurationManager.AppSettings["ida:AppId"]; 22 | private static string appSecret = ConfigurationManager.AppSettings["ida:AppSecret"]; 23 | private static string redirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"]; 24 | private static string graphScopes = ConfigurationManager.AppSettings["ida:GraphScopes"]; 25 | 26 | public void ConfigureAuth(IAppBuilder app) 27 | { 28 | app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); 29 | 30 | app.UseCookieAuthentication(new CookieAuthenticationOptions()); 31 | 32 | app.UseOpenIdConnectAuthentication( 33 | new OpenIdConnectAuthenticationOptions 34 | { 35 | ClientId = appId, 36 | Authority = "https://login.microsoftonline.com/common/v2.0", 37 | PostLogoutRedirectUri = redirectUri, 38 | RedirectUri = redirectUri, 39 | Scope = "openid email profile offline_access " + graphScopes, 40 | TokenValidationParameters = new TokenValidationParameters 41 | { 42 | ValidateIssuer = false, 43 | }, 44 | Notifications = new OpenIdConnectAuthenticationNotifications 45 | { 46 | AuthorizationCodeReceived = async (context) => 47 | { 48 | var code = context.Code; 49 | string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value; 50 | 51 | TokenCache userTokenCache = new SessionTokenCache( 52 | signedInUserID, 53 | context.OwinContext.Environment["System.Web.HttpContextBase"] as HttpContextBase 54 | ).GetMsalCacheInstance(); 55 | ConfidentialClientApplication cca = new ConfidentialClientApplication( 56 | appId, 57 | redirectUri, 58 | new ClientCredential(appSecret), 59 | userTokenCache, 60 | null); 61 | 62 | string[] scopes = graphScopes.Split(new char[] { ' ' }); 63 | AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, scopes); 64 | }, 65 | AuthenticationFailed = (context) => 66 | { 67 | context.HandleResponse(); 68 | context.Response.Redirect("/Error?message=" + context.Exception.Message); 69 | return Task.FromResult(0); 70 | } 71 | } 72 | } 73 | ); 74 | 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/ApplicationInsights.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 12 | search|spider|crawl|Bot|Monitor|AlwaysOn 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 30 | core.windows.net 31 | core.chinacloudapi.cn 32 | core.cloudapi.de 33 | core.usgovcloudapi.net 34 | localhost 35 | 127.0.0.1 36 | 37 | 38 | Microsoft.Azure.EventHubs 39 | Microsoft.Azure.ServiceBus 40 | 41 | 42 | 43 | 60 | 61 | 62 | 63 | 64 | 88 | 89 | 90 | 91 | 92 | 94 | 95 | 96 | 97 | 102 | Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.RequestDataHttpHandler 103 | System.Web.StaticFileHandler 104 | System.Web.Handlers.AssemblyResourceLoader 105 | System.Web.Optimization.BundleHandler 106 | System.Web.Script.Services.ScriptHandlerFactory 107 | System.Web.Handlers.TraceHandler 108 | System.Web.Services.Discovery.DiscoveryRequestHandler 109 | System.Web.HttpDebugHandler 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 5 121 | Event 122 | 123 | 124 | 5 125 | Event 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Content/Site.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | padding-bottom: 20px; 4 | } 5 | 6 | /* Set padding to keep content from hitting the edges */ 7 | .body-content { 8 | padding-left: 15px; 9 | padding-right: 15px; 10 | } 11 | 12 | /* Override the default bootstrap behavior where horizontal description lists 13 | will truncate terms that are too long to fit in the left column 14 | */ 15 | .dl-horizontal dt { 16 | white-space: normal; 17 | } 18 | 19 | /* Set width on the form input elements since they're 100% wide by default */ 20 | input, 21 | select, 22 | textarea { 23 | max-width: 280px; 24 | } 25 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Controllers/AccountController.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | using Microsoft.Owin.Security; 4 | using Microsoft.Owin.Security.Cookies; 5 | using Microsoft.Owin.Security.OpenIdConnect; 6 | using System.Security.Claims; 7 | using MSGraphCalendarViewer.TokenStorage; 8 | using MSGraphCalendarViewer.Helpers; 9 | 10 | namespace MSGraphCalendarViewer.Controllers 11 | { 12 | public class AccountController : Controller 13 | { 14 | public void SignIn() 15 | { 16 | if (!Request.IsAuthenticated) 17 | { 18 | HttpContext.GetOwinContext().Authentication.Challenge( 19 | new AuthenticationProperties { RedirectUri = "/" }, 20 | OpenIdConnectAuthenticationDefaults.AuthenticationType); 21 | } 22 | } 23 | 24 | public void SignOut() 25 | { 26 | if (Request.IsAuthenticated) 27 | { 28 | string userObjectId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value; 29 | 30 | SessionTokenCache tokenCache = new SessionTokenCache(userObjectId, HttpContext); 31 | HttpContext.GetOwinContext().Authentication.SignOut(OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType); 32 | } 33 | 34 | HttpContext.GetOwinContext().Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType); 35 | Response.Redirect("/"); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | 7 | namespace MSGraphCalendarViewer.Controllers 8 | { 9 | public class HomeController : Controller 10 | { 11 | public ActionResult Index() 12 | { 13 | return View(); 14 | } 15 | 16 | public ActionResult About() 17 | { 18 | ViewBag.Message = "Your application description page."; 19 | 20 | return View(); 21 | } 22 | 23 | public ActionResult Contact() 24 | { 25 | ViewBag.Message = "Your contact page."; 26 | 27 | return View(); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="MSGraphCalendarViewer.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Optimization; 7 | using System.Web.Routing; 8 | 9 | namespace MSGraphCalendarViewer 10 | { 11 | public class MvcApplication : System.Web.HttpApplication 12 | { 13 | protected void Application_Start() 14 | { 15 | AreaRegistration.RegisterAllAreas(); 16 | FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 17 | RouteConfig.RegisterRoutes(RouteTable.Routes); 18 | BundleConfig.RegisterBundles(BundleTable.Bundles); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Helpers/IAuthProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace MSGraphCalendarViewer.Helpers 4 | { 5 | public interface IAuthProvider 6 | { 7 | Task GetUserAccessTokenAsync(); 8 | } 9 | } -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Helpers/SampleAuthProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Linq; 5 | using System.Security.Claims; 6 | using System.Threading.Tasks; 7 | using System.Web; 8 | using Microsoft.Identity.Client; 9 | using Microsoft.Owin.Security; 10 | using Microsoft.Owin.Security.OpenIdConnect; 11 | using MSGraphCalendarViewer.TokenStorage; 12 | 13 | namespace MSGraphCalendarViewer.Helpers 14 | { 15 | public sealed class SampleAuthProvider : IAuthProvider 16 | { 17 | private string redirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"]; 18 | private string appId = ConfigurationManager.AppSettings["ida:AppId"]; 19 | private string appSecret = ConfigurationManager.AppSettings["ida:AppSecret"]; 20 | private string scopes = ConfigurationManager.AppSettings["ida:GraphScopes"]; 21 | private SessionTokenCache tokenCache { get; set; } 22 | 23 | private static readonly SampleAuthProvider instance = new SampleAuthProvider(); 24 | private SampleAuthProvider() { } 25 | 26 | public static SampleAuthProvider Instance 27 | { 28 | get 29 | { 30 | return instance; 31 | } 32 | } 33 | 34 | public async Task GetUserAccessTokenAsync() 35 | { 36 | string signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value; 37 | HttpContextWrapper httpContext = new HttpContextWrapper(HttpContext.Current); 38 | TokenCache userTokenCache = new SessionTokenCache(signedInUserID, httpContext).GetMsalCacheInstance(); 39 | 40 | ConfidentialClientApplication cca = new ConfidentialClientApplication( 41 | appId, 42 | redirectUri, 43 | new ClientCredential(appSecret), 44 | userTokenCache, 45 | null); 46 | 47 | try 48 | { 49 | AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes.Split(new char[] { ' ' }), cca.Users.First()); 50 | return result.AccessToken; 51 | } 52 | 53 | catch (Exception) 54 | { 55 | HttpContext.Current.Request.GetOwinContext().Authentication.Challenge( 56 | new AuthenticationProperties() { RedirectUri = "/" }, 57 | OpenIdConnectAuthenticationDefaults.AuthenticationType); 58 | 59 | throw new Exception(); 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/MSGraphCalendarViewer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Debug 7 | AnyCPU 8 | 9 | 10 | 2.0 11 | {0133341B-C403-47F8-8D6E-9CAF30973AFC} 12 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} 13 | Library 14 | Properties 15 | MSGraphCalendarViewer 16 | MSGraphCalendarViewer 17 | v4.7.2 18 | false 19 | true 20 | 21 | 44385 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | true 31 | full 32 | false 33 | bin\ 34 | DEBUG;TRACE 35 | prompt 36 | 4 37 | 38 | 39 | true 40 | pdbonly 41 | true 42 | bin\ 43 | TRACE 44 | prompt 45 | 4 46 | 47 | 48 | 49 | ..\packages\Microsoft.AspNet.TelemetryCorrelation.1.0.5\lib\net45\Microsoft.AspNet.TelemetryCorrelation.dll 50 | 51 | 52 | ..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll 53 | 54 | 55 | 56 | ..\packages\Microsoft.Identity.Client.2.7.1\lib\net45\Microsoft.Identity.Client.dll 57 | 58 | 59 | ..\packages\Microsoft.IdentityModel.JsonWebTokens.5.3.0\lib\net461\Microsoft.IdentityModel.JsonWebTokens.dll 60 | 61 | 62 | ..\packages\Microsoft.IdentityModel.Logging.5.3.0\lib\net461\Microsoft.IdentityModel.Logging.dll 63 | 64 | 65 | ..\packages\Microsoft.IdentityModel.Protocols.5.3.0\lib\net461\Microsoft.IdentityModel.Protocols.dll 66 | 67 | 68 | ..\packages\Microsoft.IdentityModel.Protocols.OpenIdConnect.5.3.0\lib\net461\Microsoft.IdentityModel.Protocols.OpenIdConnect.dll 69 | 70 | 71 | ..\packages\Microsoft.IdentityModel.Tokens.5.3.0\lib\net461\Microsoft.IdentityModel.Tokens.dll 72 | 73 | 74 | ..\packages\Microsoft.Owin.4.0.0\lib\net451\Microsoft.Owin.dll 75 | 76 | 77 | ..\packages\Microsoft.Owin.Host.SystemWeb.4.0.0\lib\net451\Microsoft.Owin.Host.SystemWeb.dll 78 | 79 | 80 | ..\packages\Microsoft.Owin.Security.4.0.0\lib\net451\Microsoft.Owin.Security.dll 81 | 82 | 83 | ..\packages\Microsoft.Owin.Security.Cookies.4.0.0\lib\net451\Microsoft.Owin.Security.Cookies.dll 84 | 85 | 86 | ..\packages\Microsoft.Owin.Security.OpenIdConnect.4.0.0\lib\net451\Microsoft.Owin.Security.OpenIdConnect.dll 87 | 88 | 89 | ..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll 90 | 91 | 92 | ..\packages\Owin.1.0\lib\net40\Owin.dll 93 | 94 | 95 | 96 | 97 | ..\packages\System.Diagnostics.DiagnosticSource.4.6.0-preview.18571.3\lib\net46\System.Diagnostics.DiagnosticSource.dll 98 | 99 | 100 | 101 | 102 | ..\packages\System.IdentityModel.Tokens.Jwt.5.3.0\lib\net461\System.IdentityModel.Tokens.Jwt.dll 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.Helpers.dll 113 | 114 | 115 | ..\packages\Microsoft.AspNet.Mvc.5.2.7\lib\net45\System.Web.Mvc.dll 116 | 117 | 118 | ..\packages\Microsoft.AspNet.Razor.3.2.7\lib\net45\System.Web.Razor.dll 119 | 120 | 121 | ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.dll 122 | 123 | 124 | ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Deployment.dll 125 | 126 | 127 | ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Razor.dll 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | True 141 | ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll 142 | 143 | 144 | 145 | 146 | 147 | 148 | ..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll 149 | 150 | 151 | True 152 | ..\packages\WebGrease.1.6.0\lib\WebGrease.dll 153 | 154 | 155 | True 156 | ..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | Global.asax 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | Web.config 200 | 201 | 202 | Web.config 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 10.0 235 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | True 248 | True 249 | 56223 250 | / 251 | http://localhost:56223/ 252 | False 253 | False 254 | 255 | 256 | False 257 | 258 | 259 | 260 | 261 | 262 | 263 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 264 | 265 | 266 | 267 | 273 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MSGraphCalendarViewer")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MSGraphCalendarViewer")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("daa38240-8b98-45f6-88cd-c13131c1633e")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Scripts/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | // Unobtrusive validation support library for jQuery and jQuery Validate 2 | // Copyright (c) .NET Foundation. All rights reserved. 3 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 4 | // @version v3.2.11 5 | !function(a){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery-validation")):jQuery.validator.unobtrusive=a(jQuery)}(function(a){function e(a,e,n){a.rules[e]=n,a.message&&(a.messages[e]=a.message)}function n(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function t(a){return a.replace(/([!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function r(a){return a.substr(0,a.lastIndexOf(".")+1)}function i(a,e){return 0===a.indexOf("*.")&&(a=a.replace("*.",e)),a}function o(e,n){var r=a(this).find("[data-valmsg-for='"+t(n[0].name)+"']"),i=r.attr("data-valmsg-replace"),o=i?a.parseJSON(i)!==!1:null;r.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",r),o?(r.empty(),e.removeClass("input-validation-error").appendTo(r)):e.hide()}function d(e,n){var t=a(this).find("[data-valmsg-summary=true]"),r=t.find("ul");r&&r.length&&n.errorList.length&&(r.empty(),t.addClass("validation-summary-errors").removeClass("validation-summary-valid"),a.each(n.errorList,function(){a("
  • ").html(this.message).appendTo(r)}))}function s(e){var n=e.data("unobtrusiveContainer");if(n){var t=n.attr("data-valmsg-replace"),r=t?a.parseJSON(t):null;n.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),r&&n.empty()}}function l(e){var n=a(this),t="__jquery_unobtrusive_validation_form_reset";if(!n.data(t)){n.data(t,!0);try{n.data("validator").resetForm()}finally{n.removeData(t)}n.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),n.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function u(e){var n=a(e),t=n.data(v),r=a.proxy(l,e),i=f.unobtrusive.options||{},u=function(n,t){var r=i[n];r&&a.isFunction(r)&&r.apply(e,t)};return t||(t={options:{errorClass:i.errorClass||"input-validation-error",errorElement:i.errorElement||"span",errorPlacement:function(){o.apply(e,arguments),u("errorPlacement",arguments)},invalidHandler:function(){d.apply(e,arguments),u("invalidHandler",arguments)},messages:{},rules:{},success:function(){s.apply(e,arguments),u("success",arguments)}},attachValidation:function(){n.off("reset."+v,r).on("reset."+v,r).validate(this.options)},validate:function(){return n.validate(),n.valid()}},n.data(v,t)),t}var m,f=a.validator,v="unobtrusiveValidation";return f.unobtrusive={adapters:[],parseElement:function(e,n){var t,r,i,o=a(e),d=o.parents("form")[0];d&&(t=u(d),t.options.rules[e.name]=r={},t.options.messages[e.name]=i={},a.each(this.adapters,function(){var n="data-val-"+this.name,t=o.attr(n),s={};void 0!==t&&(n+="-",a.each(this.params,function(){s[this]=o.attr(n+this)}),this.adapt({element:e,form:d,message:t,params:s,rules:r,messages:i}))}),a.extend(r,{__dummy__:!0}),n||t.attachValidation())},parse:function(e){var n=a(e),t=n.parents().addBack().filter("form").add(n.find("form")).has("[data-val=true]");n.find("[data-val=true]").each(function(){f.unobtrusive.parseElement(this,!0)}),t.each(function(){var a=u(this);a&&a.attachValidation()})}},m=f.unobtrusive.adapters,m.add=function(a,e,n){return n||(n=e,e=[]),this.push({name:a,params:e,adapt:n}),this},m.addBool=function(a,n){return this.add(a,function(t){e(t,n||a,!0)})},m.addMinMax=function(a,n,t,r,i,o){return this.add(a,[i||"min",o||"max"],function(a){var i=a.params.min,o=a.params.max;i&&o?e(a,r,[i,o]):i?e(a,n,i):o&&e(a,t,o)})},m.addSingleVal=function(a,n,t){return this.add(a,[n||"val"],function(r){e(r,t||a,r.params[n])})},f.addMethod("__dummy__",function(a,e,n){return!0}),f.addMethod("regex",function(a,e,n){var t;return!!this.optional(e)||(t=new RegExp(n).exec(a),t&&0===t.index&&t[0].length===a.length)}),f.addMethod("nonalphamin",function(a,e,n){var t;return n&&(t=a.match(/\W/g),t=t&&t.length>=n),t}),f.methods.extension?(m.addSingleVal("accept","mimtype"),m.addSingleVal("extension","extension")):m.addSingleVal("extension","extension","accept"),m.addSingleVal("regex","pattern"),m.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),m.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),m.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),m.add("equalto",["other"],function(n){var o=r(n.element.name),d=n.params.other,s=i(d,o),l=a(n.form).find(":input").filter("[name='"+t(s)+"']")[0];e(n,"equalTo",l)}),m.add("required",function(a){"INPUT"===a.element.tagName.toUpperCase()&&"CHECKBOX"===a.element.type.toUpperCase()||e(a,"required",!0)}),m.add("remote",["url","type","additionalfields"],function(o){var d={url:o.params.url,type:o.params.type||"GET",data:{}},s=r(o.element.name);a.each(n(o.params.additionalfields||o.element.name),function(e,n){var r=i(n,s);d.data[r]=function(){var e=a(o.form).find(":input").filter("[name='"+t(r)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),e(o,"remote",d)}),m.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&e(a,"minlength",a.params.min),a.params.nonalphamin&&e(a,"nonalphamin",a.params.nonalphamin),a.params.regex&&e(a,"regex",a.params.regex)}),m.add("fileextensions",["extensions"],function(a){e(a,"extension",a.params.extensions)}),a(function(){f.unobtrusive.parse(document)}),f.unobtrusive}); -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Startup.cs: -------------------------------------------------------------------------------- 1 | using Owin; 2 | using Microsoft.Owin; 3 | 4 | [assembly: OwinStartup(typeof(MSGraphCalendarViewer.Startup))] 5 | 6 | namespace MSGraphCalendarViewer 7 | { 8 | public partial class Startup 9 | { 10 | public void Configuration(IAppBuilder app) 11 | { 12 | ConfigureAuth(app); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/TokenStorage/SessionTokenCache.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading; 5 | using System.Web; 6 | using Microsoft.Identity.Client; 7 | 8 | namespace MSGraphCalendarViewer.TokenStorage 9 | { 10 | public class SessionTokenCache 11 | { 12 | private static ReaderWriterLockSlim SessionLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); 13 | string UserId = string.Empty; 14 | string CacheId = string.Empty; 15 | HttpContextBase httpContext = null; 16 | 17 | TokenCache cache = new TokenCache(); 18 | 19 | public SessionTokenCache(string userId, HttpContextBase httpcontext) 20 | { 21 | UserId = userId; 22 | CacheId = UserId + "_TokenCache"; 23 | httpContext = httpcontext; 24 | Load(); 25 | } 26 | 27 | public TokenCache GetMsalCacheInstance() 28 | { 29 | cache.SetBeforeAccess(BeforeAccessNotification); 30 | cache.SetAfterAccess(AfterAccessNotification); 31 | Load(); 32 | return cache; 33 | } 34 | 35 | public void SaveUserStateValue(string state) 36 | { 37 | SessionLock.EnterWriteLock(); 38 | httpContext.Session[CacheId + "_state"] = state; 39 | SessionLock.ExitWriteLock(); 40 | } 41 | public string ReadUserStateValue() 42 | { 43 | string state = string.Empty; 44 | SessionLock.EnterReadLock(); 45 | state = (string)httpContext.Session[CacheId + "_state"]; 46 | SessionLock.ExitReadLock(); 47 | return state; 48 | } 49 | public void Load() 50 | { 51 | SessionLock.EnterReadLock(); 52 | cache.Deserialize((byte[])httpContext.Session[CacheId]); 53 | SessionLock.ExitReadLock(); 54 | } 55 | 56 | public void Persist() 57 | { 58 | SessionLock.EnterWriteLock(); 59 | 60 | cache.HasStateChanged = false; 61 | 62 | httpContext.Session[CacheId] = cache.Serialize(); 63 | SessionLock.ExitWriteLock(); 64 | } 65 | 66 | void BeforeAccessNotification(TokenCacheNotificationArgs args) 67 | { 68 | Load(); 69 | } 70 | 71 | void AfterAccessNotification(TokenCacheNotificationArgs args) 72 | { 73 | if (cache.HasStateChanged) 74 | { 75 | Persist(); 76 | } 77 | } 78 | 79 | } 80 | } -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Views/Home/About.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "About"; 3 | } 4 |

    @ViewBag.Title.

    5 |

    @ViewBag.Message

    6 | 7 |

    Use this area to provide additional information.

    8 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Views/Home/Contact.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Contact"; 3 | } 4 |

    @ViewBag.Title.

    5 |

    @ViewBag.Message

    6 | 7 |
    8 | One Microsoft Way
    9 | Redmond, WA 98052-6399
    10 | P: 11 | 425.555.0100 12 |
    13 | 14 |
    15 | Support: Support@example.com
    16 | Marketing: Marketing@example.com 17 |
    -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Home Page"; 3 | } 4 | 5 |
    6 |

    ASP.NET

    7 |

    ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.

    8 |

    Learn more »

    9 |
    10 | 11 |
    12 |
    13 |

    Getting started

    14 |

    15 | ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that 16 | enables a clean separation of concerns and gives you full control over markup 17 | for enjoyable, agile development. 18 |

    19 |

    Learn more »

    20 |
    21 |
    22 |

    Get more libraries

    23 |

    NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.

    24 |

    Learn more »

    25 |
    26 |
    27 |

    Web Hosting

    28 |

    You can easily find a web hosting company that offers the right mix of features and price for your applications.

    29 |

    Learn more »

    30 |
    31 |
    -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Error 6 | 7 | 8 |
    9 |

    Error.

    10 |

    An error occurred while processing your request.

    11 |
    12 | 13 | 14 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewBag.Title - My ASP.NET Application 7 | @Styles.Render("~/Content/css") 8 | @Scripts.Render("~/bundles/modernizr") 9 | 10 | 11 | 31 |
    32 | @RenderBody() 33 |
    34 |
    35 |

    © @DateTime.Now.Year - My ASP.NET Application

    36 |
    37 |
    38 | 39 | @Scripts.Render("~/bundles/jquery") 40 | @Scripts.Render("~/bundles/bootstrap") 41 | @RenderSection("scripts", required: false) 42 | 43 | 44 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Views/Shared/_LoginPartial.cshtml: -------------------------------------------------------------------------------- 1 | @if (Request.IsAuthenticated) 2 | { 3 | 4 | 13 | 14 | } 15 | else 16 | { 17 | 35 | 36 | 43 | } 44 | 45 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Views/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 |
    7 |
    8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } 4 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Web.Debug.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Web.Release.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/favicon.ico -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/MSGraphCalendarViewer/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Demos/03-create-aspnet-mvcapp/README.md: -------------------------------------------------------------------------------- 1 | # Create & Configure an ASP.NET MVC Web Application & Configure it for MSAL 2 | 3 | In this demo you will create a new ASP.NET MVC web application. After creating it, you will configure it to use the Microsoft Authentication Library (MSAL) to handle all authentication to acquire a token to call the Microsoft Graph API in a later exercise. 4 | 5 | 1. Open Visual Studio 2017. 6 | 1. In Visual Studio, select **File > New > Project**. 7 | 1. In the **New Project** dialog, do the following: 8 | 1. Select **Templates > Visual C# > Web**. 9 | 1. Select **ASP.NET Web Application (.NET Framework)**. 10 | 1. Enter **MSGraphCalendarViewer** for the Name of the project. 11 | 12 | ![Visual Studio 2017 create new project dialog](../../Images/vs-newproj-01.png) 13 | 14 | > Note: Ensure that you enter the exact same name for the Visual Studio Project that is specified in these lab instructions. The Visual Studio Project name becomes part of the namespace in the code. The code inside these instructions depends on the namespace matching the Visual Studio Project name specified in these instructions. If you use a different project name the code will not compile unless you adjust all the namespaces to match the Visual Studio Project name you enter when you create the project. 15 | 16 | 1. Select **OK**. 17 | 1. In the **New ASP.NET Web Application Project** dialog, do the following: 18 | 1. Select **MVC**. 19 | 1. Select **OK**. 20 | 21 | 1. Confirm the web project is using SSL by default: 22 | 23 | 1. In the **Solution Explorer** tool window, select the project and look at the **Properties** tool window. 24 | 1. Verify the property **SSL Enabled** is set to **TRUE**. 25 | 1. Copy the **SSL URL** property as you will need it later. 26 | 1. Save your changes. 27 | 28 | ![Screenshot of project property setting SSL to enabled.](../../Images/vs-sslenabled.png) 29 | 30 | > It is important to do this now because in the next step when you create the application in Azure AD, you want the reply URL to use HTTPS. If you did not do this now, you would have to manually make the changes the Visual Studio wizard is going to do for you in creating the app. 31 | 32 | 1. Update the Azure AD application with the project's SSL URL: 33 | 34 | 1. Open a browser and navigate to the [Azure Active Directory admin center](https://aad.portal.azure.com). Login using a **Work or School Account**. 35 | 1. Select the application you previously created: **WebO365CalendarEvents**. 36 | 1. Select **Authentication** under **Manage**. Locate the **Redirect URIs** section 37 | 1. Select the drop-down **TYPE** as **Web**, and enter enter the SSL URL from the ASP.NET MVC project you just created into the **REDIRECT URI** box. Choose **Save**. 38 | 39 | ![Screenshot of the web app platform with the ASP.NET MVC application's SSL URL added to the Redirect URIs.](../../Images/arp-update-app-01.png) 40 | 41 | 1. Update the projects application settings: 42 | 43 | 1. Go back to Visual Studio where the project is open. 44 | 1. Open the **web.config** file. 45 | 1. Add the following application settings to the `` XML element. You will update the `ida:AppId` & `ida:AppSecret` properties later. 46 | 47 | Set the value of `ida:RedirectUri` to the value of the **SSL URL** you copied from a previous step. 48 | 49 | ```xml 50 | 51 | 52 | 53 | 54 | ``` 55 | 56 | 1. Add the Microsoft Authentication Library (MSAL) and OWIN middleware packages to the web application: 57 | 58 | 1. In Visual Studio, select the menu item **View > Other Windows > Package Manager Console**. 59 | 1. In the **Package Manager Console** tool window, run the following commands to install the necessary packages for MSAL & the OWIN middleware: 60 | 61 | ```powershell 62 | Install-Package Microsoft.Identity.Client -Version 2.7.1 63 | Install-Package Microsoft.IdentityModel.Tokens 64 | Install-Package Microsoft.Owin 65 | Install-Package Microsoft.Owin.Host.SystemWeb 66 | Install-Package Microsoft.Owin.Security.Cookies 67 | Install-Package Microsoft.Owin.Security.OpenIdConnect 68 | Install-Package System.IdentityModel.Tokens.Jwt 69 | ``` 70 | >Note: Do not update bootstrap package past 3.3.7. The default home page and navigation built into the MVC template does not support it. 71 | 72 | 1. Add authentication startup and configuration classes for MSAL & OWIN middleware: 73 | 74 | 1. Add two partial classes that will be executed when the OWIN middleware starts up when the application loads for the first time. These will configure the application to authenticate with Azure AD using specific application credentials and request permissions: 75 | 1. Copy the [LabFiles/Startup.cs](./LabFiles/Startup.cs) file to the root of the project. 76 | 1. Copy the [LabFiles/Startup.Auth.cs](./LabFiles/Startup.Auth.cs) file to the **App_Start** folder in the project. 77 | 1. Add a sample authentication provider to the project that will be used to obtain an OAuth2 access token from Azure AD: 78 | 1. Create a new folder **Helpers** in the root of the project and add the following files to it: 79 | * [LabFiles/IAuthProvider.cs](./LabFiles/IAuthProvider.cs) 80 | * [LabFiles/SampleAuthProvider.cs](./LabFiles/SampleAuthProvider.cs) 81 | 1. Create an OAuth2 token cache to store tokens obtained from Azure AD for a performance optimization. The application will first try to retrieve valid, unexpired tokens from the cache before making the round trip to Azure AD: 82 | 1. Create a new folder **TokenStorage** in the root of the project and add the following files to it: 83 | * [LabFiles/SessionTokenCache.cs](./LabFiles/SessionTokenCache.cs) 84 | 85 | 1. Update the user interface of the web application support logging into the application 86 | 87 | 1. Add an MVC controller that will handle the login and logout process for the application as well as a partial view that contains the login/logout controls. 88 | 1. Copy the [LabFiles/AccountController.cs](./LabFiles/AccountController.cs) file to the **Controllers** folder in the project. 89 | 1. Copy the [LabFiles/_LoginPartial.cshtml](./LabFiles/_LoginPartial.cshtml) file to the **Views/Shared** folder in the project. 90 | 1. Open the **Views/Shared/_Layout.cshtml** file. 91 | 1. Locate the part of the file that includes a few links at the top of the page. It looks similar to the following markup: 92 | 93 | ```html 94 | 99 | ``` 100 | 101 | 1. Add the following immediately after the closing `` tag 102 | 103 | ```html 104 | @Html.Partial("_LoginPartial") 105 | ``` -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/.vs/MSGraphCalendarViewer/v15/Server/sqlite3/db.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Demos/04-leverage-msgraphsdk/.vs/MSGraphCalendarViewer/v15/Server/sqlite3/db.lock -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/.vs/MSGraphCalendarViewer/v15/Server/sqlite3/storage.ide: -------------------------------------------------------------------------------- 1 | SQLite format 3@ .A  -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/.vs/MSGraphCalendarViewer/v15/Server/sqlite3/storage.ide-shm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Demos/04-leverage-msgraphsdk/.vs/MSGraphCalendarViewer/v15/Server/sqlite3/storage.ide-shm -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/.vs/MSGraphCalendarViewer/v15/Server/sqlite3/storage.ide-wal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Demos/04-leverage-msgraphsdk/.vs/MSGraphCalendarViewer/v15/Server/sqlite3/storage.ide-wal -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.168 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSGraphCalendarViewer", "MSGraphCalendarViewer\MSGraphCalendarViewer.csproj", "{0133341B-C403-47F8-8D6E-9CAF30973AFC}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {0133341B-C403-47F8-8D6E-9CAF30973AFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {0133341B-C403-47F8-8D6E-9CAF30973AFC}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {0133341B-C403-47F8-8D6E-9CAF30973AFC}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {0133341B-C403-47F8-8D6E-9CAF30973AFC}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {F4B9E8BA-9D0B-4B5D-A759-E8CC5EBFDB41} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/App_Start/BundleConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Optimization; 3 | 4 | namespace MSGraphCalendarViewer 5 | { 6 | public class BundleConfig 7 | { 8 | // For more information on bundling, visit https://go.microsoft.com/fwlink/?LinkId=301862 9 | public static void RegisterBundles(BundleCollection bundles) 10 | { 11 | bundles.Add(new ScriptBundle("~/bundles/jquery").Include( 12 | "~/Scripts/jquery-{version}.js")); 13 | 14 | bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( 15 | "~/Scripts/jquery.validate*")); 16 | 17 | // Use the development version of Modernizr to develop with and learn from. Then, when you're 18 | // ready for production, use the build tool at https://modernizr.com to pick only the tests you need. 19 | bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( 20 | "~/Scripts/modernizr-*")); 21 | 22 | bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( 23 | "~/Scripts/bootstrap.js")); 24 | 25 | bundles.Add(new StyleBundle("~/Content/css").Include( 26 | "~/Content/bootstrap.css", 27 | "~/Content/site.css")); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/App_Start/FilterConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | 4 | namespace MSGraphCalendarViewer 5 | { 6 | public class FilterConfig 7 | { 8 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) 9 | { 10 | filters.Add(new HandleErrorAttribute()); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/App_Start/RouteConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Routing; 7 | 8 | namespace MSGraphCalendarViewer 9 | { 10 | public class RouteConfig 11 | { 12 | public static void RegisterRoutes(RouteCollection routes) 13 | { 14 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 15 | 16 | routes.MapRoute( 17 | name: "Default", 18 | url: "{controller}/{action}/{id}", 19 | defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 20 | ); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/App_Start/Startup.Auth.cs: -------------------------------------------------------------------------------- 1 | using System.Configuration; 2 | using System.IdentityModel.Claims; 3 | using System.Threading.Tasks; 4 | using System.Web; 5 | using Owin; 6 | using MSGraphCalendarViewer.TokenStorage; 7 | using Microsoft.Identity.Client; 8 | using Microsoft.IdentityModel.Tokens; 9 | using Microsoft.Owin.Security; 10 | using Microsoft.Owin.Security.Cookies; 11 | using Microsoft.Owin.Security.OpenIdConnect; 12 | 13 | namespace MSGraphCalendarViewer 14 | { 15 | public partial class Startup 16 | { 17 | // The appId is used by the application to uniquely identify itself to Azure AD. 18 | // The appSecret is the application's password. 19 | // The redirectUri is where users are redirected after sign in and consent. 20 | // The graphScopes are the Microsoft Graph permission scopes that are used by this sample: User.Read Mail.Send 21 | private static string appId = ConfigurationManager.AppSettings["ida:AppId"]; 22 | private static string appSecret = ConfigurationManager.AppSettings["ida:AppSecret"]; 23 | private static string redirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"]; 24 | private static string graphScopes = ConfigurationManager.AppSettings["ida:GraphScopes"]; 25 | 26 | public void ConfigureAuth(IAppBuilder app) 27 | { 28 | app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); 29 | 30 | app.UseCookieAuthentication(new CookieAuthenticationOptions()); 31 | 32 | app.UseOpenIdConnectAuthentication( 33 | new OpenIdConnectAuthenticationOptions 34 | { 35 | ClientId = appId, 36 | Authority = "https://login.microsoftonline.com/common/v2.0", 37 | PostLogoutRedirectUri = redirectUri, 38 | RedirectUri = redirectUri, 39 | Scope = "openid email profile offline_access " + graphScopes, 40 | TokenValidationParameters = new TokenValidationParameters 41 | { 42 | ValidateIssuer = false, 43 | }, 44 | Notifications = new OpenIdConnectAuthenticationNotifications 45 | { 46 | AuthorizationCodeReceived = async (context) => 47 | { 48 | var code = context.Code; 49 | string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value; 50 | 51 | TokenCache userTokenCache = new SessionTokenCache( 52 | signedInUserID, 53 | context.OwinContext.Environment["System.Web.HttpContextBase"] as HttpContextBase 54 | ).GetMsalCacheInstance(); 55 | ConfidentialClientApplication cca = new ConfidentialClientApplication( 56 | appId, 57 | redirectUri, 58 | new ClientCredential(appSecret), 59 | userTokenCache, 60 | null); 61 | 62 | string[] scopes = graphScopes.Split(new char[] { ' ' }); 63 | AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, scopes); 64 | }, 65 | AuthenticationFailed = (context) => 66 | { 67 | context.HandleResponse(); 68 | context.Response.Redirect("/Error?message=" + context.Exception.Message); 69 | return Task.FromResult(0); 70 | } 71 | } 72 | } 73 | ); 74 | 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/ApplicationInsights.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 12 | search|spider|crawl|Bot|Monitor|AlwaysOn 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 30 | core.windows.net 31 | core.chinacloudapi.cn 32 | core.cloudapi.de 33 | core.usgovcloudapi.net 34 | localhost 35 | 127.0.0.1 36 | 37 | 38 | Microsoft.Azure.EventHubs 39 | Microsoft.Azure.ServiceBus 40 | 41 | 42 | 43 | 60 | 61 | 62 | 63 | 64 | 88 | 89 | 90 | 91 | 92 | 94 | 95 | 96 | 97 | 102 | Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.RequestDataHttpHandler 103 | System.Web.StaticFileHandler 104 | System.Web.Handlers.AssemblyResourceLoader 105 | System.Web.Optimization.BundleHandler 106 | System.Web.Script.Services.ScriptHandlerFactory 107 | System.Web.Handlers.TraceHandler 108 | System.Web.Services.Discovery.DiscoveryRequestHandler 109 | System.Web.HttpDebugHandler 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 5 121 | Event 122 | 123 | 124 | 5 125 | Event 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Content/Site.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | padding-bottom: 20px; 4 | } 5 | 6 | /* Set padding to keep content from hitting the edges */ 7 | .body-content { 8 | padding-left: 15px; 9 | padding-right: 15px; 10 | } 11 | 12 | /* Override the default bootstrap behavior where horizontal description lists 13 | will truncate terms that are too long to fit in the left column 14 | */ 15 | .dl-horizontal dt { 16 | white-space: normal; 17 | } 18 | 19 | /* Set width on the form input elements since they're 100% wide by default */ 20 | input, 21 | select, 22 | textarea { 23 | max-width: 280px; 24 | } 25 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Controllers/AccountController.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | using Microsoft.Owin.Security; 4 | using Microsoft.Owin.Security.Cookies; 5 | using Microsoft.Owin.Security.OpenIdConnect; 6 | using System.Security.Claims; 7 | using MSGraphCalendarViewer.TokenStorage; 8 | using MSGraphCalendarViewer.Helpers; 9 | 10 | namespace MSGraphCalendarViewer.Controllers 11 | { 12 | public class AccountController : Controller 13 | { 14 | public void SignIn() 15 | { 16 | if (!Request.IsAuthenticated) 17 | { 18 | HttpContext.GetOwinContext().Authentication.Challenge( 19 | new AuthenticationProperties { RedirectUri = "/" }, 20 | OpenIdConnectAuthenticationDefaults.AuthenticationType); 21 | } 22 | } 23 | 24 | public void SignOut() 25 | { 26 | if (Request.IsAuthenticated) 27 | { 28 | string userObjectId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value; 29 | 30 | SessionTokenCache tokenCache = new SessionTokenCache(userObjectId, HttpContext); 31 | HttpContext.GetOwinContext().Authentication.SignOut(OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType); 32 | } 33 | 34 | HttpContext.GetOwinContext().Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType); 35 | Response.Redirect("/"); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Controllers/CalendarController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using MSGraphCalendarViewer.Helpers; 7 | using MSGraphCalendarViewer.Models; 8 | using System.Net.Http.Headers; 9 | using System.Threading.Tasks; 10 | 11 | namespace MSGraphCalendarViewer.Controllers 12 | { 13 | [Authorize] 14 | public class CalendarController : Controller 15 | { 16 | // GET: Calendar 17 | public async Task Index() 18 | { 19 | GraphService graphService = new GraphService(); 20 | string accessToken = await SampleAuthProvider.Instance.GetUserAccessTokenAsync(); 21 | 22 | ViewBag.Events = await graphService.GetCalendarEvents(accessToken); 23 | 24 | return View(); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | 7 | namespace MSGraphCalendarViewer.Controllers 8 | { 9 | public class HomeController : Controller 10 | { 11 | public ActionResult Index() 12 | { 13 | return View(); 14 | } 15 | 16 | public ActionResult About() 17 | { 18 | ViewBag.Message = "Your application description page."; 19 | 20 | return View(); 21 | } 22 | 23 | public ActionResult Contact() 24 | { 25 | ViewBag.Message = "Your contact page."; 26 | 27 | return View(); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="MSGraphCalendarViewer.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Optimization; 7 | using System.Web.Routing; 8 | 9 | namespace MSGraphCalendarViewer 10 | { 11 | public class MvcApplication : System.Web.HttpApplication 12 | { 13 | protected void Application_Start() 14 | { 15 | AreaRegistration.RegisterAllAreas(); 16 | FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 17 | RouteConfig.RegisterRoutes(RouteTable.Routes); 18 | BundleConfig.RegisterBundles(BundleTable.Bundles); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Helpers/IAuthProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace MSGraphCalendarViewer.Helpers 4 | { 5 | public interface IAuthProvider 6 | { 7 | Task GetUserAccessTokenAsync(); 8 | } 9 | } -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Helpers/SampleAuthProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Linq; 5 | using System.Security.Claims; 6 | using System.Threading.Tasks; 7 | using System.Web; 8 | using Microsoft.Identity.Client; 9 | using Microsoft.Owin.Security; 10 | using Microsoft.Owin.Security.OpenIdConnect; 11 | using MSGraphCalendarViewer.TokenStorage; 12 | 13 | namespace MSGraphCalendarViewer.Helpers 14 | { 15 | public sealed class SampleAuthProvider : IAuthProvider 16 | { 17 | private string redirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"]; 18 | private string appId = ConfigurationManager.AppSettings["ida:AppId"]; 19 | private string appSecret = ConfigurationManager.AppSettings["ida:AppSecret"]; 20 | private string scopes = ConfigurationManager.AppSettings["ida:GraphScopes"]; 21 | private SessionTokenCache tokenCache { get; set; } 22 | 23 | private static readonly SampleAuthProvider instance = new SampleAuthProvider(); 24 | private SampleAuthProvider() { } 25 | 26 | public static SampleAuthProvider Instance 27 | { 28 | get 29 | { 30 | return instance; 31 | } 32 | } 33 | 34 | public async Task GetUserAccessTokenAsync() 35 | { 36 | string signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value; 37 | HttpContextWrapper httpContext = new HttpContextWrapper(HttpContext.Current); 38 | TokenCache userTokenCache = new SessionTokenCache(signedInUserID, httpContext).GetMsalCacheInstance(); 39 | 40 | ConfidentialClientApplication cca = new ConfidentialClientApplication( 41 | appId, 42 | redirectUri, 43 | new ClientCredential(appSecret), 44 | userTokenCache, 45 | null); 46 | 47 | try 48 | { 49 | var accounts = await cca.GetAccountsAsync(); 50 | AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes.Split(new char[] { ' ' }), accounts.First()); 51 | return result.AccessToken; 52 | } 53 | 54 | catch (Exception) 55 | { 56 | HttpContext.Current.Request.GetOwinContext().Authentication.Challenge( 57 | new AuthenticationProperties() { RedirectUri = "/" }, 58 | OpenIdConnectAuthenticationDefaults.AuthenticationType); 59 | 60 | throw new Exception(); 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Models/GraphOdataResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Web; 6 | 7 | namespace MSGraphCalendarViewer.Models 8 | { 9 | public class GraphOdataResponse 10 | { 11 | [JsonProperty("odata.context")] 12 | public string Context { get; set; } 13 | [JsonProperty("value")] 14 | public List Events { get; set; } 15 | } 16 | 17 | public class GraphOdataDate 18 | { 19 | [JsonProperty("dateTime")] 20 | public string DateTime { get; set; } 21 | [JsonProperty("timeZone")] 22 | public string TimeZone { get; set; } 23 | } 24 | 25 | public class GraphOdataEvent 26 | { 27 | [JsonProperty("odata.etag")] 28 | public string Etag { set; get; } 29 | [JsonProperty("id")] 30 | public string Id { set; get; } 31 | [JsonProperty("subject")] 32 | public string Subject { set; get; } 33 | [JsonProperty("start")] 34 | public GraphOdataDate Start { set; get; } 35 | [JsonProperty("end")] 36 | public GraphOdataDate End { set; get; } 37 | } 38 | } -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Models/GraphService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Newtonsoft.Json; 4 | using Newtonsoft.Json.Linq; 5 | using System.Net.Http; 6 | using System.Net.Http.Headers; 7 | using System.Threading.Tasks; 8 | 9 | namespace MSGraphCalendarViewer.Models 10 | { 11 | public class GraphService 12 | { 13 | public async Task> GetCalendarEvents(string accessToken) 14 | { 15 | List myEventList = new List(); 16 | 17 | string query = "https://graph.microsoft.com/v1.0/me/events?$select=subject,start,end&$top=20&$skip=0"; 18 | 19 | using (var client = new HttpClient()) 20 | { 21 | using (var request = new HttpRequestMessage(HttpMethod.Get, query)) 22 | { 23 | request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 24 | request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); 25 | 26 | using (var response = await client.SendAsync(request)) 27 | { 28 | if (response.IsSuccessStatusCode) 29 | { 30 | var json = await response.Content.ReadAsStringAsync(); 31 | var result = JsonConvert.DeserializeObject(json); 32 | myEventList = result.Events.ToList(); 33 | } 34 | 35 | return myEventList; 36 | } 37 | } 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MSGraphCalendarViewer")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MSGraphCalendarViewer")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("daa38240-8b98-45f6-88cd-c13131c1633e")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Scripts/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | // Unobtrusive validation support library for jQuery and jQuery Validate 2 | // Copyright (c) .NET Foundation. All rights reserved. 3 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 4 | // @version v3.2.11 5 | !function(a){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery-validation")):jQuery.validator.unobtrusive=a(jQuery)}(function(a){function e(a,e,n){a.rules[e]=n,a.message&&(a.messages[e]=a.message)}function n(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function t(a){return a.replace(/([!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function r(a){return a.substr(0,a.lastIndexOf(".")+1)}function i(a,e){return 0===a.indexOf("*.")&&(a=a.replace("*.",e)),a}function o(e,n){var r=a(this).find("[data-valmsg-for='"+t(n[0].name)+"']"),i=r.attr("data-valmsg-replace"),o=i?a.parseJSON(i)!==!1:null;r.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",r),o?(r.empty(),e.removeClass("input-validation-error").appendTo(r)):e.hide()}function d(e,n){var t=a(this).find("[data-valmsg-summary=true]"),r=t.find("ul");r&&r.length&&n.errorList.length&&(r.empty(),t.addClass("validation-summary-errors").removeClass("validation-summary-valid"),a.each(n.errorList,function(){a("
  • ").html(this.message).appendTo(r)}))}function s(e){var n=e.data("unobtrusiveContainer");if(n){var t=n.attr("data-valmsg-replace"),r=t?a.parseJSON(t):null;n.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),r&&n.empty()}}function l(e){var n=a(this),t="__jquery_unobtrusive_validation_form_reset";if(!n.data(t)){n.data(t,!0);try{n.data("validator").resetForm()}finally{n.removeData(t)}n.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),n.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function u(e){var n=a(e),t=n.data(v),r=a.proxy(l,e),i=f.unobtrusive.options||{},u=function(n,t){var r=i[n];r&&a.isFunction(r)&&r.apply(e,t)};return t||(t={options:{errorClass:i.errorClass||"input-validation-error",errorElement:i.errorElement||"span",errorPlacement:function(){o.apply(e,arguments),u("errorPlacement",arguments)},invalidHandler:function(){d.apply(e,arguments),u("invalidHandler",arguments)},messages:{},rules:{},success:function(){s.apply(e,arguments),u("success",arguments)}},attachValidation:function(){n.off("reset."+v,r).on("reset."+v,r).validate(this.options)},validate:function(){return n.validate(),n.valid()}},n.data(v,t)),t}var m,f=a.validator,v="unobtrusiveValidation";return f.unobtrusive={adapters:[],parseElement:function(e,n){var t,r,i,o=a(e),d=o.parents("form")[0];d&&(t=u(d),t.options.rules[e.name]=r={},t.options.messages[e.name]=i={},a.each(this.adapters,function(){var n="data-val-"+this.name,t=o.attr(n),s={};void 0!==t&&(n+="-",a.each(this.params,function(){s[this]=o.attr(n+this)}),this.adapt({element:e,form:d,message:t,params:s,rules:r,messages:i}))}),a.extend(r,{__dummy__:!0}),n||t.attachValidation())},parse:function(e){var n=a(e),t=n.parents().addBack().filter("form").add(n.find("form")).has("[data-val=true]");n.find("[data-val=true]").each(function(){f.unobtrusive.parseElement(this,!0)}),t.each(function(){var a=u(this);a&&a.attachValidation()})}},m=f.unobtrusive.adapters,m.add=function(a,e,n){return n||(n=e,e=[]),this.push({name:a,params:e,adapt:n}),this},m.addBool=function(a,n){return this.add(a,function(t){e(t,n||a,!0)})},m.addMinMax=function(a,n,t,r,i,o){return this.add(a,[i||"min",o||"max"],function(a){var i=a.params.min,o=a.params.max;i&&o?e(a,r,[i,o]):i?e(a,n,i):o&&e(a,t,o)})},m.addSingleVal=function(a,n,t){return this.add(a,[n||"val"],function(r){e(r,t||a,r.params[n])})},f.addMethod("__dummy__",function(a,e,n){return!0}),f.addMethod("regex",function(a,e,n){var t;return!!this.optional(e)||(t=new RegExp(n).exec(a),t&&0===t.index&&t[0].length===a.length)}),f.addMethod("nonalphamin",function(a,e,n){var t;return n&&(t=a.match(/\W/g),t=t&&t.length>=n),t}),f.methods.extension?(m.addSingleVal("accept","mimtype"),m.addSingleVal("extension","extension")):m.addSingleVal("extension","extension","accept"),m.addSingleVal("regex","pattern"),m.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),m.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),m.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),m.add("equalto",["other"],function(n){var o=r(n.element.name),d=n.params.other,s=i(d,o),l=a(n.form).find(":input").filter("[name='"+t(s)+"']")[0];e(n,"equalTo",l)}),m.add("required",function(a){"INPUT"===a.element.tagName.toUpperCase()&&"CHECKBOX"===a.element.type.toUpperCase()||e(a,"required",!0)}),m.add("remote",["url","type","additionalfields"],function(o){var d={url:o.params.url,type:o.params.type||"GET",data:{}},s=r(o.element.name);a.each(n(o.params.additionalfields||o.element.name),function(e,n){var r=i(n,s);d.data[r]=function(){var e=a(o.form).find(":input").filter("[name='"+t(r)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),e(o,"remote",d)}),m.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&e(a,"minlength",a.params.min),a.params.nonalphamin&&e(a,"nonalphamin",a.params.nonalphamin),a.params.regex&&e(a,"regex",a.params.regex)}),m.add("fileextensions",["extensions"],function(a){e(a,"extension",a.params.extensions)}),a(function(){f.unobtrusive.parse(document)}),f.unobtrusive}); -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Startup.cs: -------------------------------------------------------------------------------- 1 | using Owin; 2 | using Microsoft.Owin; 3 | 4 | [assembly: OwinStartup(typeof(MSGraphCalendarViewer.Startup))] 5 | 6 | namespace MSGraphCalendarViewer 7 | { 8 | public partial class Startup 9 | { 10 | public void Configuration(IAppBuilder app) 11 | { 12 | ConfigureAuth(app); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/TokenStorage/SessionTokenCache.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading; 5 | using System.Web; 6 | using Microsoft.Identity.Client; 7 | 8 | namespace MSGraphCalendarViewer.TokenStorage 9 | { 10 | public class SessionTokenCache 11 | { 12 | private static ReaderWriterLockSlim SessionLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); 13 | string UserId = string.Empty; 14 | string CacheId = string.Empty; 15 | HttpContextBase httpContext = null; 16 | 17 | TokenCache cache = new TokenCache(); 18 | 19 | public SessionTokenCache(string userId, HttpContextBase httpcontext) 20 | { 21 | UserId = userId; 22 | CacheId = UserId + "_TokenCache"; 23 | httpContext = httpcontext; 24 | Load(); 25 | } 26 | 27 | public TokenCache GetMsalCacheInstance() 28 | { 29 | cache.SetBeforeAccess(BeforeAccessNotification); 30 | cache.SetAfterAccess(AfterAccessNotification); 31 | Load(); 32 | return cache; 33 | } 34 | 35 | public void SaveUserStateValue(string state) 36 | { 37 | SessionLock.EnterWriteLock(); 38 | httpContext.Session[CacheId + "_state"] = state; 39 | SessionLock.ExitWriteLock(); 40 | } 41 | public string ReadUserStateValue() 42 | { 43 | string state = string.Empty; 44 | SessionLock.EnterReadLock(); 45 | state = (string)httpContext.Session[CacheId + "_state"]; 46 | SessionLock.ExitReadLock(); 47 | return state; 48 | } 49 | public void Load() 50 | { 51 | SessionLock.EnterReadLock(); 52 | cache.Deserialize((byte[])httpContext.Session[CacheId]); 53 | SessionLock.ExitReadLock(); 54 | } 55 | 56 | public void Persist() 57 | { 58 | SessionLock.EnterWriteLock(); 59 | 60 | cache.HasStateChanged = false; 61 | 62 | httpContext.Session[CacheId] = cache.Serialize(); 63 | SessionLock.ExitWriteLock(); 64 | } 65 | 66 | void BeforeAccessNotification(TokenCacheNotificationArgs args) 67 | { 68 | Load(); 69 | } 70 | 71 | void AfterAccessNotification(TokenCacheNotificationArgs args) 72 | { 73 | if (cache.HasStateChanged) 74 | { 75 | Persist(); 76 | } 77 | } 78 | 79 | } 80 | } -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Views/Calendar/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Home Page"; 3 | } 4 |
    5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | @foreach (var o365Event in ViewBag.Events) 15 | { 16 | 17 | 18 | 19 | 20 | 21 | } 22 | 23 |
    SubjectStartEnd
    @o365Event.Subject@o365Event.Start.DateTime@o365Event.End.DateTime
    24 |
    25 | 26 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Views/Home/About.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "About"; 3 | } 4 |

    @ViewBag.Title.

    5 |

    @ViewBag.Message

    6 | 7 |

    Use this area to provide additional information.

    8 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Views/Home/Contact.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Contact"; 3 | } 4 |

    @ViewBag.Title.

    5 |

    @ViewBag.Message

    6 | 7 |
    8 | One Microsoft Way
    9 | Redmond, WA 98052-6399
    10 | P: 11 | 425.555.0100 12 |
    13 | 14 |
    15 | Support: Support@example.com
    16 | Marketing: Marketing@example.com 17 |
    -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Home Page"; 3 | } 4 | 5 |
    6 |

    ASP.NET

    7 |

    ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.

    8 |

    Learn more »

    9 |
    10 | 11 |
    12 |
    13 |

    Getting started

    14 |

    15 | ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that 16 | enables a clean separation of concerns and gives you full control over markup 17 | for enjoyable, agile development. 18 |

    19 |

    Learn more »

    20 |
    21 |
    22 |

    Get more libraries

    23 |

    NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.

    24 |

    Learn more »

    25 |
    26 |
    27 |

    Web Hosting

    28 |

    You can easily find a web hosting company that offers the right mix of features and price for your applications.

    29 |

    Learn more »

    30 |
    31 |
    -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Error 6 | 7 | 8 |
    9 |

    Error.

    10 |

    An error occurred while processing your request.

    11 |
    12 | 13 | 14 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewBag.Title - My ASP.NET Application 7 | @Styles.Render("~/Content/css") 8 | @Scripts.Render("~/bundles/modernizr") 9 | 10 | 11 | 32 |
    33 | @RenderBody() 34 |
    35 |
    36 |

    © @DateTime.Now.Year - My ASP.NET Application

    37 |
    38 |
    39 | 40 | @Scripts.Render("~/bundles/jquery") 41 | @Scripts.Render("~/bundles/bootstrap") 42 | @RenderSection("scripts", required: false) 43 | 44 | 45 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Views/Shared/_LoginPartial.cshtml: -------------------------------------------------------------------------------- 1 | @if (Request.IsAuthenticated) 2 | { 3 | 4 | 13 | 14 | } 15 | else 16 | { 17 | 35 | 36 | 43 | } 44 | 45 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Views/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 |
    7 |
    8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } 4 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Web.Debug.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Web.Release.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/favicon.ico -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/MSGraphCalendarViewer/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Demos/04-leverage-msgraphsdk/README.md: -------------------------------------------------------------------------------- 1 | # Update the ASP.NET MVC Application to Leverage the Microsoft Graph REST API 2 | 3 | In this demo you will update the ASP.NET MVC application created in the last exercise to call the Microsoft Graph REST API. 4 | 5 | 1. The Microsoft Graph REST API will return data in an OData JSON response format. To simplify working with the data, use JSON.NET to deserialize the response. 6 | 1. Copy the [LabFiles/GraphOdataResponse.cs](./LabFiles/GraphOdataResponse.cs) file to the **Models** folder in the project. 7 | 1. Add a new service that will handle all communication with the Microsoft Graph REST API: 8 | 1. In the **Visual Studio** **Solution Explorer** tool window, right-click the **Models** folder and select **Add > Class**. 9 | 1. In the **Add Class** dialog, name the class **GraphService** and select **Add**. 10 | 1. Add the following `using` statements to the existing ones in the **GraphService.cs** file that was created. 11 | 12 | ```cs 13 | using Newtonsoft.Json; 14 | using Newtonsoft.Json.Linq; 15 | using System.Net.Http; 16 | using System.Net.Http.Headers; 17 | using System.Threading.Tasks; 18 | ``` 19 | 20 | 1. Add the following method to the `GraphService` class. This will use the Microsoft Graph REST API to retrieve the first 20 calendar events from your Office 365 calendar. The response is then deserialized into using JSON.NET into a .NET class. The events are then returned back to the caller. 21 | 22 | ```cs 23 | public async Task> GetCalendarEvents(string accessToken) 24 | { 25 | List myEventList = new List(); 26 | 27 | string query = "https://graph.microsoft.com/v1.0/me/events?$select=subject,start,end&$top=20&$skip=0"; 28 | 29 | using (var client = new HttpClient()) 30 | { 31 | using (var request = new HttpRequestMessage(HttpMethod.Get, query)) 32 | { 33 | request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 34 | request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); 35 | 36 | using (var response = await client.SendAsync(request)) 37 | { 38 | if (response.IsSuccessStatusCode) 39 | { 40 | var json = await response.Content.ReadAsStringAsync(); 41 | var result = JsonConvert.DeserializeObject(json); 42 | myEventList = result.Events.ToList(); 43 | } 44 | 45 | return myEventList; 46 | } 47 | } 48 | } 49 | } 50 | ``` 51 | 52 | 1. Add a new ASP.NET MVC controller that will retrieve events from the user's calendar: 53 | 54 | 1. In the **Visual Studio** **Solution Explorer** tool window, right-click the **Controllers** folder and select **Add > Controller**. 55 | 1. In the **Add Scaffold** dialog, select **MVC 5 Controller - Empty**, select **Add** and name the controller **CalendarController** and then select **Add**. 56 | 1. Add the following `using` statements to the existing ones in the **CalendarController.cs** file that was created. 57 | 58 | ```cs 59 | using MSGraphCalendarViewer.Helpers; 60 | using MSGraphCalendarViewer.Models; 61 | using System.Net.Http.Headers; 62 | ``` 63 | 64 | 1. Decorate the controller to allow only authenticated users to use it by adding `[Authorize]` in the line immediately before the controller: 65 | 66 | ```cs 67 | [Authorize] 68 | public class CalendarController : Controller 69 | ``` 70 | 71 | 1. Modify the existing `Index()` method to be asynchronous by adding the `async` keyword and modifying the return type to be as follows: 72 | 73 | ```cs 74 | public async Task Index() 75 | ``` 76 | 77 | 1. Update the `Index()` method to use the `GraphServiceClient` object to call the Microsoft Graph API and retrieve the first 20 events in the user's calendar: 78 | 79 | ```cs 80 | public async Task Index() 81 | { 82 | GraphService graphService = new GraphService(); 83 | string accessToken = await SampleAuthProvider.Instance.GetUserAccessTokenAsync(); 84 | 85 | ViewBag.Events = await graphService.GetCalendarEvents(accessToken); 86 | 87 | return View(); 88 | } 89 | ``` 90 | 1. Implement the Calendar controller's associated ASP.NET MVC view: 91 | 92 | 1. In the `CalendarController` class method `Index()`, locate the `View()` return statement at the end of the method. Right-click `View()` in the code and select **Add View**: 93 | 94 | ![Screenshot adding a view using the context menu in the code.](../../Images/vs-calendarController-01.png) 95 | 96 | 1. In the **Add View** dialog, set the following values (*leave all other values as their default values*) and select **Add**: 97 | 98 | * **View name:** Index 99 | * **Template:** Empty (without model) 100 | 101 | 1. In the newly created **Views/Calendar/Index.cshtml** file, replace the default code with the following code: 102 | 103 | ```html 104 | @{ 105 | ViewBag.Title = "Home Page"; 106 | } 107 |
    108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | @foreach (var o365Event in ViewBag.Events) 118 | { 119 | 120 | 121 | 122 | 123 | 124 | } 125 | 126 |
    SubjectStartEnd
    @o365Event.Subject@o365Event.Start.DateTime@o365Event.End.DateTime
    127 |
    128 | ``` 129 | 130 | 1. Update the navigation in the **Views/Shared/_Layout.cshtml** file to include a fourth link pointing to a new controller *Calendar*: 131 | 132 | ```html 133 | 139 | ``` 140 | 141 | 1. Save your changes to all files. 142 | 143 | Test the application: 144 | 145 | 1. Press **F5** to start the application. 146 | 1. When the browser loads, select **Signin with Microsoft** and login. 147 | 1. If this is the first time running the application, you will be prompted to consent to the application. Review the consent dialog and select **Accept**. The dialog will look similar to the following dialog: 148 | 149 | ![Screenshot of Azure AD consent dialog](../../Images/aad-consent.png) 150 | 151 | 1. When the ASP.NET application loads, select the **Calendar** link in the top navigation. 152 | 1. You should see a list of calendar items from your calendar appear on the page. 153 | 154 | ![Screenshot of the web application showing calendar events](../../Images/calendar-events-01.png) 155 | -------------------------------------------------------------------------------- /Demos/README.md: -------------------------------------------------------------------------------- 1 | # Building Apps with the Microsoft Graph REST API 2 | 3 | This folder contains demos for the Microsoft Graph module. 4 | 5 | ## Demos 6 | 7 | * [Create an Azure AD web application with the App Registration Portal](./01-arp-app) 8 | * [Working with the Microsoft Graph REST API in Postman](./02-create-app) 9 | * [Create & Configure an ASP.NET MVC Web Application & Configure it for MSAL](./03-create-aspnet-mvcapp) 10 | * [Update the ASP.NET MVC Application to Leverage the Microsoft Graph REST API](./04-leverage-msgraphsdk) 11 | 12 | ## Running demonstrations 13 | 14 | Each demonstration is included as source code for convenience. However, several of the projects rely on other source code repositories. It is recommended that you obtain the original source and configure the projects according to the instructions in those repositories. 15 | 16 | Each project has been updated to leverage configuration files when possible instead of editing source code files. -------------------------------------------------------------------------------- /Images/aad-api-permissions.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/aad-api-permissions.PNG -------------------------------------------------------------------------------- /Images/aad-application-id.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/aad-application-id.PNG -------------------------------------------------------------------------------- /Images/aad-consent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/aad-consent.png -------------------------------------------------------------------------------- /Images/aad-copy-client-secret.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/aad-copy-client-secret.png -------------------------------------------------------------------------------- /Images/aad-delegated-permissions.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/aad-delegated-permissions.PNG -------------------------------------------------------------------------------- /Images/aad-implicit-grant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/aad-implicit-grant.png -------------------------------------------------------------------------------- /Images/aad-new-client-secret.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/aad-new-client-secret.png -------------------------------------------------------------------------------- /Images/aad-portal-app-registrations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/aad-portal-app-registrations.png -------------------------------------------------------------------------------- /Images/aad-register-an-app.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/aad-register-an-app.PNG -------------------------------------------------------------------------------- /Images/aad-request-api-permissions.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/aad-request-api-permissions.PNG -------------------------------------------------------------------------------- /Images/arp-update-app-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/arp-update-app-01.png -------------------------------------------------------------------------------- /Images/calendar-events-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/calendar-events-01.png -------------------------------------------------------------------------------- /Images/postman-accesstoken-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/postman-accesstoken-01.png -------------------------------------------------------------------------------- /Images/postman-accesstoken-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/postman-accesstoken-02.png -------------------------------------------------------------------------------- /Images/postman-graph-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/postman-graph-01.png -------------------------------------------------------------------------------- /Images/postman-graph-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/postman-graph-02.png -------------------------------------------------------------------------------- /Images/postman-graph-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/postman-graph-03.png -------------------------------------------------------------------------------- /Images/postman-login-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/postman-login-01.png -------------------------------------------------------------------------------- /Images/postman-login-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/postman-login-02.png -------------------------------------------------------------------------------- /Images/postman-login-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/postman-login-03.png -------------------------------------------------------------------------------- /Images/vs-calendarController-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/vs-calendarController-01.png -------------------------------------------------------------------------------- /Images/vs-newproj-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/vs-newproj-01.png -------------------------------------------------------------------------------- /Images/vs-sslenabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-training-restapi/4a363b9f5ece7e238ba53857ce5eb211738c5163/Images/vs-sslenabled.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Microsoft Graph 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LabFiles/AccountController.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | using Microsoft.Owin.Security; 4 | using Microsoft.Owin.Security.Cookies; 5 | using Microsoft.Owin.Security.OpenIdConnect; 6 | using System.Security.Claims; 7 | using MSGraphCalendarViewer.TokenStorage; 8 | using MSGraphCalendarViewer.Helpers; 9 | 10 | namespace MSGraphCalendarViewer.Controllers 11 | { 12 | public class AccountController : Controller 13 | { 14 | public void SignIn() 15 | { 16 | if (!Request.IsAuthenticated) 17 | { 18 | HttpContext.GetOwinContext().Authentication.Challenge( 19 | new AuthenticationProperties { RedirectUri = "/" }, 20 | OpenIdConnectAuthenticationDefaults.AuthenticationType); 21 | } 22 | } 23 | 24 | public void SignOut() 25 | { 26 | if (Request.IsAuthenticated) 27 | { 28 | string userObjectId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value; 29 | 30 | SessionTokenCache tokenCache = new SessionTokenCache(userObjectId, HttpContext); 31 | HttpContext.GetOwinContext().Authentication.SignOut(OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType); 32 | } 33 | 34 | HttpContext.GetOwinContext().Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType); 35 | Response.Redirect("/"); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /LabFiles/GraphOdataResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Web; 6 | 7 | namespace MSGraphCalendarViewer.Models 8 | { 9 | public class GraphOdataResponse 10 | { 11 | [JsonProperty("odata.context")] 12 | public string Context { get; set; } 13 | [JsonProperty("value")] 14 | public List Events { get; set; } 15 | } 16 | 17 | public class GraphOdataDate 18 | { 19 | [JsonProperty("dateTime")] 20 | public string DateTime { get; set; } 21 | [JsonProperty("timeZone")] 22 | public string TimeZone { get; set; } 23 | } 24 | 25 | public class GraphOdataEvent 26 | { 27 | [JsonProperty("odata.etag")] 28 | public string Etag { set; get; } 29 | [JsonProperty("id")] 30 | public string Id { set; get; } 31 | [JsonProperty("subject")] 32 | public string Subject { set; get; } 33 | [JsonProperty("start")] 34 | public GraphOdataDate Start { set; get; } 35 | [JsonProperty("end")] 36 | public GraphOdataDate End { set; get; } 37 | } 38 | } -------------------------------------------------------------------------------- /LabFiles/IAuthProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace MSGraphCalendarViewer.Helpers 4 | { 5 | public interface IAuthProvider 6 | { 7 | Task GetUserAccessTokenAsync(); 8 | } 9 | } -------------------------------------------------------------------------------- /LabFiles/SampleAuthProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Linq; 5 | using System.Security.Claims; 6 | using System.Threading.Tasks; 7 | using System.Web; 8 | using Microsoft.Identity.Client; 9 | using Microsoft.Owin.Security; 10 | using Microsoft.Owin.Security.OpenIdConnect; 11 | using MSGraphCalendarViewer.TokenStorage; 12 | 13 | namespace MSGraphCalendarViewer.Helpers 14 | { 15 | public sealed class SampleAuthProvider : IAuthProvider 16 | { 17 | private string redirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"]; 18 | private string appId = ConfigurationManager.AppSettings["ida:AppId"]; 19 | private string appSecret = ConfigurationManager.AppSettings["ida:AppSecret"]; 20 | private string scopes = ConfigurationManager.AppSettings["ida:GraphScopes"]; 21 | private SessionTokenCache tokenCache { get; set; } 22 | 23 | private static readonly SampleAuthProvider instance = new SampleAuthProvider(); 24 | private SampleAuthProvider() { } 25 | 26 | public static SampleAuthProvider Instance 27 | { 28 | get 29 | { 30 | return instance; 31 | } 32 | } 33 | 34 | public async Task GetUserAccessTokenAsync() 35 | { 36 | string signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value; 37 | HttpContextWrapper httpContext = new HttpContextWrapper(HttpContext.Current); 38 | TokenCache userTokenCache = new SessionTokenCache(signedInUserID, httpContext).GetMsalCacheInstance(); 39 | 40 | ConfidentialClientApplication cca = new ConfidentialClientApplication( 41 | appId, 42 | redirectUri, 43 | new ClientCredential(appSecret), 44 | userTokenCache, 45 | null); 46 | 47 | try 48 | { 49 | var accounts = await cca.GetAccountsAsync(); 50 | AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes.Split(new char[] { ' ' }), accounts.First()); 51 | return result.AccessToken; 52 | } 53 | 54 | catch (Exception) 55 | { 56 | HttpContext.Current.Request.GetOwinContext().Authentication.Challenge( 57 | new AuthenticationProperties() { RedirectUri = "/" }, 58 | OpenIdConnectAuthenticationDefaults.AuthenticationType); 59 | 60 | throw new Exception(); 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /LabFiles/SessionTokenCache.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading; 5 | using System.Web; 6 | using Microsoft.Identity.Client; 7 | 8 | namespace MSGraphCalendarViewer.TokenStorage 9 | { 10 | public class SessionTokenCache 11 | { 12 | private static ReaderWriterLockSlim SessionLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); 13 | string UserId = string.Empty; 14 | string CacheId = string.Empty; 15 | HttpContextBase httpContext = null; 16 | 17 | TokenCache cache = new TokenCache(); 18 | 19 | public SessionTokenCache(string userId, HttpContextBase httpcontext) 20 | { 21 | UserId = userId; 22 | CacheId = UserId + "_TokenCache"; 23 | httpContext = httpcontext; 24 | Load(); 25 | } 26 | 27 | public TokenCache GetMsalCacheInstance() 28 | { 29 | cache.SetBeforeAccess(BeforeAccessNotification); 30 | cache.SetAfterAccess(AfterAccessNotification); 31 | Load(); 32 | return cache; 33 | } 34 | 35 | public void SaveUserStateValue(string state) 36 | { 37 | SessionLock.EnterWriteLock(); 38 | httpContext.Session[CacheId + "_state"] = state; 39 | SessionLock.ExitWriteLock(); 40 | } 41 | public string ReadUserStateValue() 42 | { 43 | string state = string.Empty; 44 | SessionLock.EnterReadLock(); 45 | state = (string)httpContext.Session[CacheId + "_state"]; 46 | SessionLock.ExitReadLock(); 47 | return state; 48 | } 49 | public void Load() 50 | { 51 | SessionLock.EnterReadLock(); 52 | cache.Deserialize((byte[])httpContext.Session[CacheId]); 53 | SessionLock.ExitReadLock(); 54 | } 55 | 56 | public void Persist() 57 | { 58 | SessionLock.EnterWriteLock(); 59 | 60 | cache.HasStateChanged = false; 61 | 62 | httpContext.Session[CacheId] = cache.Serialize(); 63 | SessionLock.ExitWriteLock(); 64 | } 65 | 66 | void BeforeAccessNotification(TokenCacheNotificationArgs args) 67 | { 68 | Load(); 69 | } 70 | 71 | void AfterAccessNotification(TokenCacheNotificationArgs args) 72 | { 73 | if (cache.HasStateChanged) 74 | { 75 | Persist(); 76 | } 77 | } 78 | 79 | } 80 | } -------------------------------------------------------------------------------- /LabFiles/Startup.Auth.cs: -------------------------------------------------------------------------------- 1 | using System.Configuration; 2 | using System.IdentityModel.Claims; 3 | using System.Threading.Tasks; 4 | using System.Web; 5 | using Owin; 6 | using MSGraphCalendarViewer.TokenStorage; 7 | using Microsoft.Identity.Client; 8 | using Microsoft.IdentityModel.Tokens; 9 | using Microsoft.Owin.Security; 10 | using Microsoft.Owin.Security.Cookies; 11 | using Microsoft.Owin.Security.OpenIdConnect; 12 | 13 | namespace MSGraphCalendarViewer 14 | { 15 | public partial class Startup 16 | { 17 | // The appId is used by the application to uniquely identify itself to Azure AD. 18 | // The appSecret is the application's password. 19 | // The redirectUri is where users are redirected after sign in and consent. 20 | // The graphScopes are the Microsoft Graph permission scopes that are used by this sample: User.Read Mail.Send 21 | private static string appId = ConfigurationManager.AppSettings["ida:AppId"]; 22 | private static string appSecret = ConfigurationManager.AppSettings["ida:AppSecret"]; 23 | private static string redirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"]; 24 | private static string graphScopes = ConfigurationManager.AppSettings["ida:GraphScopes"]; 25 | 26 | public void ConfigureAuth(IAppBuilder app) 27 | { 28 | app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); 29 | 30 | app.UseCookieAuthentication(new CookieAuthenticationOptions()); 31 | 32 | app.UseOpenIdConnectAuthentication( 33 | new OpenIdConnectAuthenticationOptions 34 | { 35 | ClientId = appId, 36 | Authority = "https://login.microsoftonline.com/common/v2.0", 37 | PostLogoutRedirectUri = redirectUri, 38 | RedirectUri = redirectUri, 39 | Scope = "openid email profile offline_access " + graphScopes, 40 | TokenValidationParameters = new TokenValidationParameters 41 | { 42 | ValidateIssuer = false, 43 | }, 44 | Notifications = new OpenIdConnectAuthenticationNotifications 45 | { 46 | AuthorizationCodeReceived = async (context) => 47 | { 48 | var code = context.Code; 49 | string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value; 50 | 51 | TokenCache userTokenCache = new SessionTokenCache( 52 | signedInUserID, 53 | context.OwinContext.Environment["System.Web.HttpContextBase"] as HttpContextBase 54 | ).GetMsalCacheInstance(); 55 | ConfidentialClientApplication cca = new ConfidentialClientApplication( 56 | appId, 57 | redirectUri, 58 | new ClientCredential(appSecret), 59 | userTokenCache, 60 | null); 61 | 62 | string[] scopes = graphScopes.Split(new char[] { ' ' }); 63 | AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, scopes); 64 | }, 65 | AuthenticationFailed = (context) => 66 | { 67 | context.HandleResponse(); 68 | context.Response.Redirect("/Error?message=" + context.Exception.Message); 69 | return Task.FromResult(0); 70 | } 71 | } 72 | } 73 | ); 74 | 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /LabFiles/Startup.cs: -------------------------------------------------------------------------------- 1 | using Owin; 2 | using Microsoft.Owin; 3 | 4 | [assembly: OwinStartup(typeof(MSGraphCalendarViewer.Startup))] 5 | 6 | namespace MSGraphCalendarViewer 7 | { 8 | public partial class Startup 9 | { 10 | public void Configuration(IAppBuilder app) 11 | { 12 | ConfigureAuth(app); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /LabFiles/_LoginPartial.cshtml: -------------------------------------------------------------------------------- 1 | @if (Request.IsAuthenticated) 2 | { 3 | 4 | 13 | 14 | } 15 | else 16 | { 17 | 35 | 36 | 43 | } 44 | 45 | -------------------------------------------------------------------------------- /README-Localized/README-es-es.md: -------------------------------------------------------------------------------- 1 | # Módulo de aprendizaje de Microsoft Graph: crear aplicaciones con la API de REST de Microsoft Graph 2 | 3 | Este módulo le mostrará cómo trabajar con la API de REST de Microsoft Graph para acceder a los datos de Office 365. 4 | 5 | ## Práctica: crear aplicaciones con la API de REST de Microsoft Graph 6 | 7 | En esta práctica, va a usar la API de REST de Microsoft Graph para crear una aplicación de ASP.NET MVC con el punto de conexión de autenticación de Azure AD v2 y la biblioteca de autenticación de Microsoft (MSAL) para acceder a los datos de Office 365. También aprenderá a realizar la autenticación manual con Azure AD y llamar al punto de conexión de la API de REST de Microsoft Graph por medio de llamadas HTTP sin procesar. 8 | 9 | * [Manual de laboratorio](./Lab.md) 10 | 11 | ## Demostraciones 12 | 13 | * [Crear una aplicación web de Azure AD con el portal de registro de aplicaciones](./Demos/01-arp-app) 14 | * [Trabajar con la API de REST de Microsoft Graph en Postman](./Demos/02-create-app) 15 | * [Crear y configurar una aplicación web de ASP.NET MVC y configurarla para MSAL](./Demos/03-create-aspnet-mvcapp) 16 | * [Actualizar la aplicación de ASP.NET MVC para aprovechar la API de REST de Microsoft Graph](./Demos/04-leverage-msgraphsdk) 17 | 18 | ## Vea el módulo 19 | 20 | Este módulo se ha grabado y está disponible en el canal de desarrollo de Office en YouTube: [Crear aplicaciones con la API de REST de Microsoft Graph](https://youtu.be/GF4JSTeR6VA) 21 | 22 | > **Nota:** El tutorial en vídeo no se ha actualizado para reflejar la nueva experiencia de registro de la aplicación de Azure AD y el uso de la biblioteca actualizada de `Microsoft.Identity 2.7.1`. 23 | 24 | ## Colaboradores 25 | 26 | | Roles | Autor(es) | 27 | | -------------------- | ---------------------------------------------------------------- | 28 | | Actualizaciones de manuales | Irvine Sunday (Microsoft) @irvinesunday | 29 | | Manuales de laboratorio / Diapositivas | Andrew Connell (Microsoft MVP, Voitanos) @andrewconnell | 30 | | QA | Julie Turner (Microsoft MVP, Sympraxis Consulting) @juliemturner | 31 | | Patrocinador / Soporte | Yina Arenas (Microsoft) @yinaa | 32 | 33 | ## Historial de versiones 34 | 35 | | Versión | Fecha | Comentarios | 36 | | ------- | ------------------ | ---------------------------------------------- | 37 | | 1.5 | 4 de abril de 2019 | Actualización de contenido del 2T de 2019 | 38 | | 1.4 | 18 de diciembre de 2018 | Actualización de contenido del 2T de 2019 | 39 | | 1.3 | 14 de septiembre de 2018 | Actualización de contenido del 1T de 2019 | 40 | | 1.2 | 28 de junio de 2018 | Se agregó presentación de pantalla. | 41 | | 1.1 | 22 de junio de 2018 | Se reescribió para usar las instrucciones más recientes. | 42 | | 1.0 | ~24 de noviembre de 2017 | Se agregaron desgloses de producto de Microsoft Graph. | 43 | 44 | ## Aviso de declinación de responsabilidades 45 | 46 | **ESTE CÓDIGO ES PROPORCIONADO *TAL CUAL* SIN GARANTÍA DE NINGÚN TIPO, YA SEA EXPLÍCITA O IMPLÍCITA, INCLUIDAS LAS GARANTÍAS IMPLÍCITAS DE IDONEIDAD PARA UN FIN DETERMINADO, COMERCIABILIDAD O AUSENCIA DE INFRACCIÓN.** 47 | 48 | -------------------------------------------------------------------------------- /README-Localized/README-fr-fr.md: -------------------------------------------------------------------------------- 1 | # Module de formation Microsoft Graph : créer des applications avec l’API REST Microsoft Graph 2 | 3 | Ce module vous présente l'utilisation de l’API REST Microsoft Graph pour accéder aux données dans Office 365. 4 | 5 | ## Atelier : création d’applications avec l’API REST Microsoft Graph 6 | 7 | Dans cet atelier, vous allez tirer partie de l’API REST Microsoft Graph pour créer une application ASP.NET MVC à l’aide du point de terminaison d’authentification Azure AD v2 et de la Bibliothèque d’authentification Microsoft (MSAL) pour accéder aux données dans Office 365. Vous allez également découvrir comment effectuer une authentification manuelle avec Azure AD et appeler le point de terminaison de l’API REST Microsoft Graph à l’aide d’appels HTTP bruts. 8 | 9 | * [Manuel de l'atelier](./Lab.md) 10 | 11 | ## Démonstrations 12 | 13 | * [Créer une application Web Azure AD à l’aide du portail Inscription d’application](./Demos/01-arp-app) 14 | * [Utilisation de l’API REST Microsoft Graph dans Postman](./Demos/02-create-app) 15 | * [Créer & configurer une application Web ASP.NET MVC & la configurer pour MSAL](./Demos/03-create-aspnet-mvcapp) 16 | * [Mettre à jour l’application ASP.NET MVC pour tirer parti de l’API Microsoft Graph REST](./Demos/04-leverage-msgraphsdk) 17 | 18 | ## Regardez le module 19 | 20 | Ce module enregistré est disponible sur la chaîne YouTube de développement Office : [Création d’applications avec l’API REST Microsoft Graph](https://youtu.be/GF4JSTeR6VA) 21 | 22 | > **Remarque :** Le didacticiel vidéo n’a pas été mis à jour pour prendre en compte la nouvelle expérience d’inscription des applications Azure AD et l’utilisation de la bibliothèque `Microsoft. Identity 2.7.1` mise à jour. 23 | 24 | ## Contributeurs 25 | 26 | | Rôles | Auteur(s) | 27 | | -------------------- | ---------------------------------------------------------------- | 28 | | Mises à jour des manuels | Irvine Sunday (Microsoft) @irvinesunday | 29 | | Manuels de l’atelier/diapositives | Andrew Connell (Microsoft MVP, Voitanos) @andrewconnell | 30 | | QA | Julie Turner (Microsoft MVP, Sympraxis Consulting) @juliemturner | 31 | | Sponsor / Support | Yina Arenas (Microsoft) @yinaa | 32 | 33 | ## Historique des versions 34 | 35 | | Version | Date | Commentaires | 36 | | ------- | ------------------ | ---------------------------------------------- | 37 | | 1.5 | 04 avril 2019 | actualisation du contenu deuxième trimestre 2019 | 38 | | 1.4 | 18 décembre 2018 | actualisation du contenu deuxième trimestre 2019 | 39 | | 1.3 | 14 septembre 2018 | actualisation du contenu premier trimestre 2019 | 40 | | 1.2 | 28 juin 2018 | Capture vidéo ajoutée | 41 | | 1.1 | 22 juin, 2018 | Réécriture des recommandations les plus récentes. | 42 | | 1.0 | ~ 24 novembre 2017 | Ajout des discussion sur les produits liés à Microsoft Graph. | 43 | 44 | ## Clause d’exclusion 45 | 46 | **CE CODE EST FOURNI *EN L’ÉTAT*, SANS GARANTIE D'AUCUNE SORTE, EXPRESSE OU IMPLICITE, Y COMPRIS TOUTE GARANTIE IMPLICITE D'ADAPTATION À UN USAGE PARTICULIER, DE QUALITÉ MARCHANDE ET DE NON-CONTREFAÇON.** 47 | 48 | -------------------------------------------------------------------------------- /README-Localized/README-ja-jp.md: -------------------------------------------------------------------------------- 1 | # Microsoft Graph トレーニング モジュール - Microsoft Graph REST API を使用するアプリの作成 2 | 3 | このモジュールでは、Microsoft Graph REST API を使用して、Office 365 のデータにアクセスする方法について説明します。 4 | 5 | ## ラボ - Microsoft Graph REST API を使用するアプリの作成 6 | 7 | このラボでは、Microsoft Graph REST API を利用して、ASP.NET MVC アプリケーションを作成します。これは、Azure AD v2 認証エンドポイントと Microsoft 認証ライブラリ (MSAL) を使用して Office 365 のデータにアクセスするアプリケーションです。また、Azure AD を使用して手動で認証を実行する方法、未加工の HTTP 呼び出しを使用して Microsoft Graph REST API エンドポイントを呼び出す方法についても説明します。 8 | 9 | * [ラボ マニュアル](./Lab.md) 10 | 11 | ## デモ 12 | 13 | * [アプリ登録ポータルを使用して Azure AD web アプリケーションを作成する](./Demos/01-arp-app) 14 | * [Postman で Microsoft Graph REST API を操作する](./Demos/02-create-app) 15 | * [ASP.NET MVC Web アプリケーションの作成と構成、および MSAL 用の構成](./Demos/03-create-aspnet-mvcapp) 16 | * [ASP.NET MVC アプリケーションを更新して、Microsoft Graph REST API を活用する](./Demos/04-leverage-msgraphsdk) 17 | 18 | ## モジュールを見る 19 | 20 | このモジュールは録画されており、こちらで視聴できます。Office 開発 YouTube チャンネル: [Microsoft Graph REST API を使用するアプリの作成](https://youtu.be/GF4JSTeR6VA) 21 | 22 | > **注:**このビデオ チュートリアルは更新されていないため、新しい Azure AD アプリの登録機能や、更新された `Microsoft.Identity 2.7.1` ライブラリは使用していません。 23 | 24 | ## 共同作成者 25 | 26 | | ロール | 作成者 | 27 | | -------------------- | ---------------------------------------------------------------- | 28 | | マニュアル更新 | Irvine Sunday (Microsoft) @irvinesunday | 29 | | ラボ マニュアル/スライド | Andrew Connell (Microsoft MVP, Voitanos) @andrewconnell | 30 | | QA | Julie Turner (Microsoft MVP, Sympraxis Consulting) @juliemturner | 31 | | スポンサー/サポート | Yina Arenas (Microsoft) @yinaa | 32 | 33 | ## バージョン履歴 34 | 35 | | バージョン | 日付 | コメント | 36 | | ------- | ------------------ | ---------------------------------------------- | 37 | | 1.5 | 2019 年 4月 4 日 | 2019Q2 コンテンツ更新 | 38 | | 1.4 | 2018 年 12 月 18 日 | 2019Q2 コンテンツ更新 | 39 | | 1.3 | 2018 年 9 月 14 日 | 2019Q1 コンテンツ更新 | 40 | | 1.2 | 2018 年 6 月 28 日 | Screencast を追加。 | 41 | | 1.1 | 2018 年 6 月 22 日 | 最新のガイドを使用するように書き換え。 | 42 | | 1.0 | - 2017 年 11 月 24 日 | Microsoft Graph 関連製品 ブレイクアウトを追加。 | 43 | 44 | ## 免責事項 45 | 46 | **このコードは、明示または黙示のいかなる種類の保証なしに*現状のまま*提供されるものであり、特定目的への適合性、商品性、権利侵害の不存在についての暗黙的な保証は一切ありません。** 47 | 48 | -------------------------------------------------------------------------------- /README-Localized/README-pt-br.md: -------------------------------------------------------------------------------- 1 | # Módulo de Treinamento do Microsoft Graph – Compile aplicativos com a API REST do Microsoft Graph 2 | 3 | Este módulo mostrará como trabalhar com a API REST do Microsoft Graph para acessar os dados no Office 365. 4 | 5 | ## Lab - Compile aplicativos com a API REST do Microsoft Graph 6 | 7 | Neste laboratório, você aproveitará a API REST do Microsoft Graph para compilar um aplicativo ASP.NET MVC usando o ponto de extremidade de autenticação do Azure AD v2 e a Biblioteca de Autenticação da Microsoft (MSAL) para acessar os dados no Office 365. Você também aprenderá a executar uma autenticação manual com o Azure AD e a chamar o ponto de extremidade da API REST do Microsoft Graph usando chamadas HTTP brutas. 8 | 9 | * [Manual do laboratório](./Lab.md) 10 | 11 | ## Demonstrações 12 | 13 | * [Compilar um aplicativo Web do Azure AD com o portal de registro de aplicativos](./Demos/01-arp-app) 14 | * [Como trabalhar com a API REST do Microsoft Graph no Postman](./Demos/02-create-app) 15 | * [Criar e configurar um aplicativo Web ASP.NET MVC e configurá-lo para MSAL](./Demos/03-create-aspnet-mvcapp) 16 | * [Atualizar o aplicativo ASP.NET MVC para utilizar a API REST do Microsoft Graph](./Demos/04-leverage-msgraphsdk) 17 | 18 | ## Assista ao módulo 19 | 20 | Este módulo foi gravado e está disponível no canal Office Development no YouTube: [Compile os aplicativos com a API REST do Microsoft Graph](https://youtu.be/GF4JSTeR6VA) 21 | 22 | > **Observação:** O tutorial de vídeo não foi atualizado para refletir a nova experiência de registro do aplicativo Azure AD e o uso da biblioteca atualizada `Microsoft.Identity 2.7.1`. 23 | 24 | ## Colaboradores 25 | 26 | | Funções | Autor(es) | 27 | | -------------------- | ---------------------------------------------------------------- | 28 | | Atualizações de Manuais | Irvine Sunday (Microsoft) @irvinesunday | 29 | | Manuais/Slides do Laboratório | Andrew Connell (MVP da Microsoft, Voitanos) @andrewconnell | 30 | | QA | Julie Turner (MVP da Microsoft, Sympraxis Consulting) @juliemturner | 31 | | Patrocinador/suporte | Yina Arenas (Microsoft) @yinaa | 32 | 33 | ## Histórico de versão 34 | 35 | | Versão | Data | Comentários | 36 | | ------- | ------------------ | ---------------------------------------------- | 37 | | 1.5 | 04 de abril de 2019 | atualização de conteúdo 2019T2 | 38 | | 1.4 | 18 de dezembro de 2018 | atualização de conteúdo 2019T2 | 39 | | 1.3 | 14 de setembro de 2018 | atualização de conteúdo 2019T1 | 40 | | 1.2 | 28 de junho de 2018 | Adição de screencast. | 41 | | 1.1 | 22 de junho de 2018 | Reescrito para usar o guia mais recente. | 42 | | 1.0 | ~ 24 de novembro de 2017 | Adição de sessões de produtos relacionados ao Microsoft Graph. | 43 | 44 | ## Aviso de isenção de responsabilidade 45 | 46 | **ESSE CÓDIGO É FORNECIDO *NAS CIRCUNTÂNCIAS ATUAIS*SEM GARANTIA DE QUALQUER TIPO, SEJA EXPRESSA OU IMPLÍCITA, INCLUINDO QUAISQUER GARANTIAS IMPLÍCITAS DE ADEQUAÇÃO A UMA FINALIDADE ESPECÍFICA, COMERCIABILIDADE OU NÃO VIOLAÇÃO.** 47 | 48 | -------------------------------------------------------------------------------- /README-Localized/README-ru-ru.md: -------------------------------------------------------------------------------- 1 | # Модуль обучающих курсов Microsoft Graph - Создавайте приложения с помощью Microsoft Graph REST API 2 | 3 | В этом разделе приведена информация о том, как работать с Microsoft Graph REST API для доступа к данным в Office 365. 4 | 5 | ## Практическое занятие— Создайте приложение с помощью Microsoft Graph REST API 6 | 7 | В этом практическом занятии вы будете использовать Microsoft Graph REST API чтобы создать приложение ASP.NET MVC, используя конечную точку проверки подлинности Azure AD v2 и библиотеку проверки подлинности Microsoft (MSAL) для доступа к данным в Office 365. Вы также узнаете, как выполнять ручную проверку подлинности в Azure AD и позвонить на конечную точку Microsoft Graph REST API, используя необработанные HTTP-вызовы.. 8 | 9 | * [Руководство по практическому занятию](./Lab.md) 10 | 11 | ## Демонстрации 12 | 13 | * [Создание веб-приложения Azure AD на портале регистрации приложений](./Demos/01-arp-app) 14 | * [Работа с Microsoft Graph REST API в публикации](./Demos/02-create-app) 15 | * [Создать и настроить веб-приложение ASP.NET MVC и настроить его для MSAL](./Demos/03-create-aspnet-mvcapp) 16 | * [Обновите приложение ASP.NET MVC, чтобы использовать Microsoft Graph REST API](./Demos/04-leverage-msgraphsdk) 17 | 18 | ## Посмотреть модуль 19 | 20 | Этот модуль записан и доступен в канале разработчиков Office на сайте YouTube: [Создание приложений с применением Microsoft Graph REST API](https://youtu.be/GF4JSTeR6VA) 21 | 22 | > **Примечание:** Учебный курс не был обновлен в соответствии с новым интерфейсом регистрации приложений Azure AD, а также с использованием обновленной библиотеки `Microsoft. Identity 2.7.1`. 23 | 24 | ## Участники 25 | 26 | | Роли | Авторы | 27 | | -------------------- | ---------------------------------------------------------------- | 28 | | Обновления для руководств | Ирвин Сандей (Майкрософт) @irvinesunday | 29 | | Лабораторные руководства / слайды | Эндрю Коннелл (Microsoft MVP, Воитанос) @andrewconnell | 30 | | ВОПРОСЫ И ОТВЕТЫ | Джули Тернер (Майкрософт MVP, Симпраксис Консалтинг) @juliemturner | 31 | | Спонсор / Поддержка | Йина Аренас (Microsoft) @yinaa | 32 | 33 | ## Журнал версий 34 | 35 | | Версия | Дата | Комментарии | 36 | | ------- | ------------------ | ---------------------------------------------- | 37 | | 1.5 | 04 апреля 2019 | Обновление контента 2019Q2 | 38 | | 1.4 | 18 декабря 2018 года | Обновление контента 2019Q2 | 39 | | 1.3 | 14 сентября 2018 | Обновление контента 2019Q1 | 40 | | 1.2 | 28 июня 2018 | Добавлен скринкаст. | 41 | | 1.1 | 22 июня 2018 | Переписан, чтобы использовать последние руководства. | 42 | | 1.0 | ~ 24 ноября 2017 г. | Добавить продукты связанные c Microsoft Graph. | 43 | 44 | ## Заявление об отказе 45 | 46 | **ЭТОТ КОД ПРЕДОСТАВЛЯЕТСЯ *КАК ЕСТЬ* БЕЗ КАКОЙ-ЛИБО ЯВНОЙ ИЛИ ПОДРАЗУМЕВАЕМОЙ ГАРАНТИИ, ВКЛЮЧАЯ ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ ПРИГОДНОСТИ ДЛЯ КАКОЙ-ЛИБО ЦЕЛИ, ДЛЯ ПРОДАЖИ ИЛИ ГАРАНТИИ ОТСУТСТВИЯ НАРУШЕНИЯ ПРАВ ИНЫХ ПРАВООБЛАДАТЕЛЕЙ.** 47 | 48 | -------------------------------------------------------------------------------- /README-Localized/README-zh-cn.md: -------------------------------------------------------------------------------- 1 | # Microsoft Graph 培训模块 - 使用 Microsoft Graph REST API 生成应用 2 | 3 | 本模块将介绍如何使用 Microsoft Graph REST API 访问 Office 365 中的数据。 4 | 5 | ## 实验 - 使用 Microsoft Graph REST API 生成应用 6 | 7 | 在此实验中,你将利用 Microsoft Graph REST API 以使用 Azure AD v2 身份验证终结点和 Microsoft 身份验证库 (MSAL) 创建 Android 应用程序,用于访问 Office 365 中的数据。还将学习如何通过 Azure AD 执行手动身份验证,并使用原始 HTTP 调用来调用 Microsoft Graph REST API 终结点。 8 | 9 | * [实验手册](./Lab.md) 10 | 11 | ## 演示 12 | 13 | * [使用应用注册门户创建 Azure AD Web 应用程序](./Demos/01-arp-app) 14 | * [使用 Postman 中的 Microsoft Graph REST API](./Demos/02-create-app) 15 | * [创建并配置 ASP.NET MVC Web 应用程序以及针对 MSAL 进行相应配置](./Demos/03-create-aspnet-mvcapp) 16 | * [更新 ASP.NET MVC 应用程序以利用 Microsoft Graph REST API](./Demos/04-leverage-msgraphsdk) 17 | 18 | ## 观看此模块 19 | 20 | 此模块已录制,并可在 YouTube 上的 Office 开发频道中找到:[使用 Microsoft Graph REST API 生成应用](https://youtu.be/GF4JSTeR6VA) 21 | 22 | > **注意:**该视频教程尚未更新,无法反映新的 Azure AD 应用注册体验以及对更新版 `Microsoft 2.7.1` 库的使用。 23 | 24 | ## 参与者 25 | 26 | | 角色 | 作者 | 27 | | -------------------- | ---------------------------------------------------------------- | 28 | | 手册更新 | Irvine Sunday (Microsoft) @irvinesunday | 29 | | 实验手册/幻灯片 | Andrew Connell (Microsoft MVP, Voitanos) @andrewconnell | 30 | | QA | Julie Turner (Microsoft MVP, Sympraxis Consulting) @juliemturner | 31 | | 发起人/支持 | Yina Arenas (Microsoft) @yinaa | 32 | 33 | ## 版本历史记录 34 | 35 | | 版本 | 日期 | 备注 | 36 | | ------- | ------------------ | ---------------------------------------------- | 37 | | 1.5 | 2019 年 4 月 4 日 | 2019Q2 内容更新 | 38 | | 1.4 | 2018 年 12 月 18 日 | 2019Q2 内容更新 | 39 | | 1.3 | 2018 年 9 月 14 日 | 2019Q1 内容更新 | 40 | | 1.2 | 2018 年 6 月 28 日 | 添加了屏幕录制 | 41 | | 1.1 | 2018 年 6 月 22 日 | 重写以使用最新版指南 | 42 | | 1.0 | 大约 2017 年 11 月 24 日 | 添加了与 Microsoft Graph 相关的产品分支 | 43 | 44 | ## 免责声明 45 | 46 | **此代码*按原样*提供,不提供任何明示或暗示的担保,包括对特定用途适用性、适销性或不侵权的默示担保。** 47 | 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [ARCHIVED] Microsoft Graph Training Module - Build apps with the Microsoft Graph REST API 2 | 3 | ## IMPORTANT 4 | 5 | **This project is being archived. As part of the archival process, we're closing all open issues and pull requests.** 6 | 7 | **You can continue to use this sample "as-is", but it won't be maintained moving forward. We apologize for any inconvenience.** 8 | 9 | This module will introduce you to working with the Microsoft Graph REST API to access data in Office 365. 10 | 11 | ## Lab - Build apps with the Microsoft Graph REST API 12 | 13 | In this lab you will leverage the Microsoft Graph REST API to create an ASP.NET MVC application using the Azure AD v2 authentication endpoint and the Microsoft Authentication Library (MSAL) to access data in Office 365. You will also learn how to perform manual authentication with Azure AD and call the Microsoft Graph REST API endpoint using raw HTTP calls. 14 | 15 | * [Lab manual](./Lab.md) 16 | 17 | ## Demos 18 | 19 | * [Create an Azure AD web application with the App Registration Portal](./Demos/01-arp-app) 20 | * [Working with the Microsoft Graph REST API in Postman](./Demos/02-create-app) 21 | * [Create & Configure an ASP.NET MVC Web Application & Configure it for MSAL](./Demos/03-create-aspnet-mvcapp) 22 | * [Update the ASP.NET MVC Application to Leverage the Microsoft Graph REST API](./Demos/04-leverage-msgraphsdk) 23 | 24 | ## Watch the Module 25 | 26 | This module has been recorded and is available in the Office Development YouTube channel: [Build apps with the Microsoft Graph REST API](https://youtu.be/GF4JSTeR6VA) 27 | 28 | > **Note:** 29 | The video tutorial hasn't been updated to reflect the new Azure AD App registration experience and the use of the updated `Microsoft.Identity 2.7.1` library. 30 | 31 | ## Contributors 32 | 33 | | Roles | Author(s) | 34 | | -------------------- | ---------------------------------------------------------------- | 35 | | Manuals Updates | Irvine Sunday (Microsoft) @irvinesunday | 36 | | Lab Manuals / Slides | Andrew Connell (Microsoft MVP, Voitanos) @andrewconnell | 37 | | QA | Julie Turner (Microsoft MVP, Sympraxis Consulting) @juliemturner | 38 | | Sponsor / Support | Yina Arenas (Microsoft) @yinaa | 39 | 40 | ## Version history 41 | 42 | | Version | Date | Comments | 43 | | ------- | ------------------ | ---------------------------------------------- | 44 | | 1.5 | April 04, 2019 | 2019Q2 content refresh | 45 | | 1.4 | December 18, 2018 | 2019Q2 content refresh | 46 | | 1.3 | September 14, 2018 | 2019Q1 content refresh | 47 | | 1.2 | June 28, 2018 | Added screencast. | 48 | | 1.1 | June 22, 2018 | Rewritten to use latest guidance. | 49 | | 1.0 | ~November 24, 2017 | Add Microsoft Graph related product breakouts. | 50 | 51 | ## Disclaimer 52 | 53 | **THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.** 54 | 55 | 56 | --------------------------------------------------------------------------------