Created
April 27, 2016 21:28
-
-
Save nzpcmad/544c13f9d589e8a4847f7bc0a6c49e7a to your computer and use it in GitHub Desktop.
Daemon and Web API on Server 2016 TP4 ADFS 4.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8" ?> | |
<configuration> | |
<startup> | |
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> | |
</startup> | |
<appSettings> | |
<!--ADFS 4.0--> | |
<add key="ida:ClientId" value="bee24b9a-13ac-45fc-988c-8cce06160c07" /> | |
<add key="ida:AppKey" value="wp...nE" /> | |
<add key="todo:TodoListResourceId" value="https://localhost:44326/NativeTodoListService" /> | |
<add key="todo:TodoListBaseAddress" value="https://localhost:44326" /> | |
</appSettings> | |
<system.net> | |
<!--To bypass proxy if applicable - ADFS 4.0--> | |
<defaultProxy useDefaultCredentials="true" /> | |
</system.net> | |
</configuration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//---------------------------------------------------------------------------------------------- | |
// Copyright 2014 Microsoft Corporation | |
// | |
// Licensed under the Apache License, Version 2.0 (the "License"); | |
// you may not use this file except in compliance with the License. | |
// You may obtain a copy of the License at | |
// | |
// http://www.apache.org/licenses/LICENSE-2.0 | |
// | |
// Unless required by applicable law or agreed to in writing, software | |
// distributed under the License is distributed on an "AS IS" BASIS, | |
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
// See the License for the specific language governing permissions and | |
// limitations under the License. | |
//---------------------------------------------------------------------------------------------- | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
// The following using statements were added for this sample. | |
using System.Globalization; | |
using Microsoft.IdentityModel.Clients.ActiveDirectory; | |
using System.Net.Http; | |
using System.Threading; | |
using System.Net.Http.Headers; | |
using System.Web.Script.Serialization; | |
using System.Configuration; | |
namespace TodoListDaemon | |
{ | |
class Program | |
{ | |
// | |
// The Client ID is used by the application to uniquely identify itself to Azure AD. | |
// The App Key is a credential used by the application to authenticate to Azure AD. | |
// ADFS 4.0 | |
private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"]; | |
private static string tenant = ConfigurationManager.AppSettings["ida:Tenant"]; | |
private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"]; | |
private static string appKey = ConfigurationManager.AppSettings["ida:AppKey"]; | |
// | |
// To authenticate to the To Do list service, the client needs to know the service's App ID URI. | |
// To contact the To Do list service we need it's URL as well. | |
// | |
private static string todoListResourceId = ConfigurationManager.AppSettings["todo:TodoListResourceId"]; | |
private static string todoListBaseAddress = ConfigurationManager.AppSettings["todo:TodoListBaseAddress"]; | |
private static HttpClient httpClient = new HttpClient(); | |
private static AuthenticationContext authContext = null; | |
private static ClientCredential clientCredential = null; | |
static void Main(string[] args) | |
{ | |
// | |
// Call the To Do service 10 times with short delay between calls. | |
// | |
// ADFS 4.0 | |
//authContext = new AuthenticationContext(authority); | |
authContext = new AuthenticationContext("https://my-adfs/adfs/", false); | |
clientCredential = new ClientCredential(clientId, appKey); | |
for (int i = 0; i < 10; i++) | |
{ | |
Thread.Sleep(3000); | |
PostTodo().Wait(); | |
Thread.Sleep(3000); | |
GetTodo().Wait(); | |
} | |
} | |
static async Task PostTodo() | |
{ | |
// | |
// Get an access token from Azure AD using client credentials. | |
// If the attempt to get a token fails because the server is unavailable, retry twice after 3 seconds each. | |
// | |
AuthenticationResult result = null; | |
int retryCount = 0; | |
bool retry = false; | |
do | |
{ | |
retry = false; | |
try | |
{ | |
// ADAL includes an in memory cache, so this call will only send a message to the server if the cached token is expired. | |
result = authContext.AcquireToken(todoListResourceId, clientCredential); | |
} | |
catch (AdalException ex) | |
{ | |
if (ex.ErrorCode == "temporarily_unavailable") | |
{ | |
retry = true; | |
retryCount++; | |
Thread.Sleep(3000); | |
} | |
Console.WriteLine( | |
String.Format("An error occurred while acquiring a token\nTime: {0}\nError: {1}\nRetry: {2}\n", | |
DateTime.Now.ToString(), | |
ex.ToString(), | |
retry.ToString())); | |
} | |
} while ((retry == true) && (retryCount < 3)); | |
if (result == null) | |
{ | |
Console.WriteLine("Canceling attempt to contact To Do list service.\n"); | |
return; | |
} | |
// | |
// Post an item to the To Do list service. | |
// | |
// Add the access token to the authorization header of the request. | |
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken); | |
// Forms encode To Do item and POST to the todo list web api. | |
string timeNow = DateTime.Now.ToString(); | |
Console.WriteLine("Posting to To Do list at {0}", timeNow); | |
string todoText = "Task at time: " + timeNow; | |
HttpContent content = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("Title", todoText) }); | |
HttpResponseMessage response = await httpClient.PostAsync(todoListBaseAddress + "/api/todolist", content); | |
if (response.IsSuccessStatusCode == true) | |
{ | |
Console.WriteLine("Successfully posted new To Do item: {0}\n", todoText); | |
} | |
else | |
{ | |
Console.WriteLine("Failed to post a new To Do item\nError: {0}\n", response.ReasonPhrase); | |
} | |
} | |
static async Task GetTodo() | |
{ | |
// | |
// Get an access token from Azure AD using client credentials. | |
// If the attempt to get a token fails because the server is unavailable, retry twice after 3 seconds each. | |
// | |
AuthenticationResult result = null; | |
int retryCount = 0; | |
bool retry = false; | |
do | |
{ | |
retry = false; | |
try | |
{ | |
// ADAL includes an in memory cache, so this call will only send a message to the server if the cached token is expired. | |
result = authContext.AcquireToken(todoListResourceId, clientCredential); | |
} | |
catch (AdalException ex) | |
{ | |
if (ex.ErrorCode == "temporarily_unavailable") | |
{ | |
retry = true; | |
retryCount++; | |
Thread.Sleep(3000); | |
} | |
Console.WriteLine( | |
String.Format("An error occurred while acquiring a token\nTime: {0}\nError: {1}\nRetry: {2}\n", | |
DateTime.Now.ToString(), | |
ex.ToString(), | |
retry.ToString())); | |
} | |
} while ((retry == true) && (retryCount < 3)); | |
if (result == null) | |
{ | |
Console.WriteLine("Canceling attempt to contact To Do list service.\n"); | |
return; | |
} | |
// | |
// Read items from the To Do list service. | |
// | |
// Add the access token to the authorization header of the request. | |
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken); | |
// Call the To Do list service. | |
Console.WriteLine("Retrieving To Do list at {0}", DateTime.Now.ToString()); | |
HttpResponseMessage response = await httpClient.GetAsync(todoListBaseAddress + "/api/todolist"); | |
if (response.IsSuccessStatusCode) | |
{ | |
// Read the response and output it to the console. | |
string s = await response.Content.ReadAsStringAsync(); | |
JavaScriptSerializer serializer = new JavaScriptSerializer(); | |
List<TodoItem> toDoArray = serializer.Deserialize<List<TodoItem>>(s); | |
int count = 0; | |
foreach (TodoItem item in toDoArray) | |
{ | |
Console.WriteLine(item.Title); | |
count++; | |
} | |
Console.WriteLine("Total item count: {0}\n", count); | |
} | |
else | |
{ | |
Console.WriteLine("Failed to retrieve To Do list\nError: {0}\n", response.ReasonPhrase); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Configuration; | |
using System.Linq; | |
using Microsoft.Owin.Security; | |
using Microsoft.Owin.Security.ActiveDirectory; | |
using Owin; | |
namespace TodoListService | |
{ | |
public partial class Startup | |
{ | |
// For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864 | |
public void ConfigureAuth(IAppBuilder app) | |
{ | |
/*app.UseWindowsAzureActiveDirectoryBearerAuthentication( | |
new WindowsAzureActiveDirectoryBearerAuthenticationOptions | |
{ | |
Audience = ConfigurationManager.AppSettings["ida:Audience"], | |
Tenant = ConfigurationManager.AppSettings["ida:Tenant"] | |
});*/ | |
// Added ADFS 4.0 code | |
app.UseActiveDirectoryFederationServicesBearerAuthentication( | |
new ActiveDirectoryFederationServicesBearerAuthenticationOptions | |
{ | |
Audience = "https://localhost:44326/NativeTodoListService", | |
MetadataEndpoint = "https://my-adfs/FederationMetadata/2007-06/FederationMetadata.xml" | |
}); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
<configuration> | |
<appSettings> | |
<add key="webpages:Version" value="3.0.0.0" /> | |
<add key="webpages:Enabled" value="false" /> | |
<add key="ClientValidationEnabled" value="true" /> | |
<add key="UnobtrusiveJavaScriptEnabled" value="true" /> | |
<!--ADFS 4.0--> | |
<!--<add key="ida:Tenant" value="[Enter tenant name, e.g. contoso.onmicrosoft.com]" /> | |
<add key="ida:Audience" value="[Enter App ID URI of TodoListService, e.g. https://contoso.onmicrosoft.com/TodoListService]" />--> | |
</appSettings> | |
... | |
{Rest is the same} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
http://nzpcmad.blogspot.co.nz/2016/04/adfs-daemon-and-web-api-on-server-2016.html