I am trying to create a C# version of a JavaScript Amazon Cognito user pool authentication (see here) but it does not work. The response always shows null. Please find code below:
using System;
using Amazon.Runtime;
using Amazon.CognitoIdentityProvider;
using Amazon.Extensions.CognitoAuthentication;
namespace ConsoleApp1
{
class AmazonCognitoSetup
{
private AuthFlowResponse response;
public AuthFlowResponse Response { get; set; }
public async void AsyncStuff()
{
String userpool_id = "us-west-2_NqkuZcXQY";
String client_id = "4l9rvl4mv5es1eep1qe97cautn";
String username = "username"
String password = "password"
var provider = new AmazonCognitoIdentityProviderClient(new AnonymousAWSCredentials(), Amazon.RegionEndpoint.USWest2);
var userpool = new CognitoUserPool(userpool_id, client_id, provider);
var user = new CognitoUser(username, client_id, userpool, provider);
InitiateSrpAuthRequest initiateSrpAuthRequest = new() { Password = password};
Console.WriteLine("Getting credentials");
response = await user.StartWithSrpAuthAsync(initiateSrpAuthRequest).ConfigureAwait(false);//shows null
var accesstoken = response.AuthenticationResult.AccessToken;
Console.WriteLine(accesstoken);
}
}
}
Fixed it. The issue was that the authentication was asynchronous so I had to find a way to block until the response came back. See redone code below:
using System;
using Amazon.Runtime;
using Amazon.CognitoIdentityProvider;
using Amazon.Extensions.CognitoAuthentication;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class AmazonCognitoSetup
{
private string userpool_id = "us-west-2_NqkuZcXQY";
private string client_id = "4l9rvl4mv5es1eep1qe97cautn";
private string username = "username";
private string password = "password";
private string idToken;
private string refreshToken;
private string accessToken;
public string IdToken { get => idToken; set => idToken = value; }
public string RefreshToken { get => refreshToken; set => refreshToken = value; }
public string AccessToken { get => accessToken; set => accessToken = value; }
public void AsyncStuff()
{
//FileMaker PRO credentials for Amazon
var provider = new AmazonCognitoIdentityProviderClient(new AnonymousAWSCredentials(), Amazon.RegionEndpoint.USWest2);
var userpool = new CognitoUserPool(userpool_id, client_id, provider);
var user = new CognitoUser(username, client_id, userpool, provider);
InitiateSrpAuthRequest initiateSrpAuthRequest = new() {
Password = password
};
//authenticate to get tokens <--- change was here
var task = Task.Run<AuthFlowResponse>(async()=> await user.StartWithSrpAuthAsync(initiateSrpAuthRequest));
//assign tokens from results
this.idToken = task.Result.AuthenticationResult.IdToken;
this.refreshToken = task.Result.AuthenticationResult.RefreshToken;
this.accessToken = task.Result.AuthenticationResult.AccessToken;
}
}
}
Related
I am trying to login to Azure with my c# code and was able to find something like this on the net.
Not sure what to pass in the scope array here and once I get the access token, how can I make the rest call ?
public static string getAccessToken(string[] scopes)
{
var interactiveCredential = new InteractiveBrowserCredential();
return interactiveCredential.GetToken(new Azure.Core.TokenRequestContext(scopes, null)).Token;
}
First create a Azure AD Application:
Follow this link
Then get the Tenant ID , Client ID , Client Secret from the AD Application and use this class to query your azure subscription recourses.
class CustomLoginCredentials : ServiceClientCredentials
{
//Variables
private static string tenantId = "<Tenant ID goes here>";
private static string clientId = "<Client ID goes here>";
private static string clientSecret = "<Client Secret goes here>";
private static string windowsURL = "https://login.windows.net/";
private static string azureManagementURL = "https://management.azure.com/";
private string AuthenticationToken { get; set; }
public override void InitializeServiceClient<T>(ServiceClient<T> client)
{
var authenticationContext =
new AuthenticationContext(windowsURL + tenantId);
var credential = new ClientCredential(clientId, clientSecret);
var result = authenticationContext.AcquireTokenAsync(azureManagementURL,
clientCredential: credential).Result;
AuthenticationToken = result.AccessToken;
}
public override async Task ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", AuthenticationToken);
await base.ProcessHttpRequestAsync(request, cancellationToken);
}
}
Example:
private async void GetAzureResourcesConsumption()
{
var credentials = new CustomLoginCredentials();
ConsumptionManagementClient client = new ConsumptionManagementClient(credentials);
client.SubscriptionId = subscriptionId;
var resources = await client.UsageDetails.ListAsync(null, null, null, top: NumberOfItems);
var results = resources.ToList<UsageDetail>();
}
Do you mean to get access token?
private static string GetAuthorizationToken()
{
ClientCredential cc = new ClientCredential(ClientId, ServicePrincipalPassword);
var context = new AuthenticationContext("https://login.windows.net/" + AzureTenantId);
var result = context.AcquireTokenAsync("https://management.azure.com/", cc);
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the JWT token");
}
return result.Result.AccessToken;
}
I am trying to execute below code:
using System;
using Microsoft.Graph;
using Microsoft.Graph.Auth;
using Microsoft.Graph.Core;
using Microsoft.Identity.Client;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Linq;
namespace AzureActiveDirectory
{
class Program
{
//3. Copy the following code as is to your application.
// Register your app on the Azure AD application registration portal
// Remember to :
// 1. Check the redirect uri starting with "msal"
// 2. Set "Treat application as public client" to "Yes"
const string clientId = "XXXXXX";
const string tenant = "XXXXX";
const string redirectUri = "http://localhost";
// Change the following between each call to create/update user if not deleting the user
private static string givenName = "test99";
private static string surname = "user99";
private static void Main(string[] args)
{
// Initialize and prepare MSAL
//What we want to do
// string[] scopes = new string[] { "user.read", "user.readwrite.all" };
string[] scopes = new string[] { "user.read" };
IPublicClientApplication app = PublicClientApplicationBuilder.Create(clientId)
.WithAuthority(new Uri($"https://login.microsoftonline.com/{tenant}"))
.WithRedirectUri(redirectUri)
.Build();
// Initialize the Graph SDK authentication provider
InteractiveAuthenticationProvider authenticationProvider = new InteractiveAuthenticationProvider(app, scopes);
GraphServiceClient graphServiceClient = new GraphServiceClient(authenticationProvider);
// Get information from Graph about the currently signed-In user
Console.WriteLine("--Fetching details of the currently signed-in user--");
GetMeAsync(graphServiceClient).GetAwaiter().GetResult();
Console.WriteLine("---------");
// Create a new user
Console.WriteLine($"--Creating a new user in the tenant '{tenant}'--");
User newUser = CreateUserAsync(graphServiceClient).Result;
PrintUserDetails(newUser);
Console.WriteLine("---------");
// Update an existing user
if (newUser != null)
{
Console.WriteLine("--Updating the detail of an existing user--");
User updatedUser = UpdateUserAsync(graphServiceClient, userId: newUser.Id, jobTitle: "Program Manager").Result;
PrintUserDetails(updatedUser);
Console.WriteLine("---------");
}
// List existing users
Console.WriteLine("--Listing all users in the tenant--");
List<User> users = GetUsersAsync(graphServiceClient).Result;
users.ForEach(u => PrintUserDetails(u));
Console.WriteLine("---------");
// Delete this user
Console.WriteLine("--Deleting a user in the tenant--");
if (newUser != null)
{
DeleteUserAsync(graphServiceClient, newUser?.Id).GetAwaiter().GetResult(); ;
}
Console.WriteLine("---------");
// List existing users after deletion
Console.WriteLine("--Listing all users in the tenant after deleting a user.--");
users = GetUsersAsync(graphServiceClient).Result;
users.ForEach(u => PrintUserDetails(u));
Console.WriteLine("---------");
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
private static async Task GetMeAsync(GraphServiceClient graphServiceClient)
{
// Call /me Api
var me = await graphServiceClient.Me.Request().GetAsync();
Console.WriteLine($"Display Name from /me->{me.DisplayName}");
var directreports = await graphServiceClient.Me.DirectReports.Request().GetAsync();
foreach (User user in directreports.CurrentPage)
{
Console.WriteLine($"Report's Display Name ->{user.DisplayName}");
}
}
private static async Task<User> CreateUserAsync(GraphServiceClient graphServiceClient)
{
User newUserObject = null;
string displayname = $"{givenName} {surname}";
string mailNickName = $"{givenName}{surname}";
string upn = $"{mailNickName}{tenant}";
string password = "p#$$w0rd!";
try
{
newUserObject = await graphServiceClient.Users.Request().AddAsync(new User
{
AccountEnabled = true,
DisplayName = displayname,
MailNickname = mailNickName,
GivenName = givenName,
Surname = surname,
PasswordProfile = new PasswordProfile
{
Password = password
},
UserPrincipalName = upn
});
}
catch (ServiceException e)
{
Console.WriteLine("We could not add a new user: " + e.Error.Message);
return null;
}
return newUserObject;
}
private static void PrintUserDetails(User user)
{
if (user != null)
{
Console.WriteLine($"DisplayName-{user.DisplayName}, MailNickname- {user.MailNickname}, GivenName-{user.GivenName}, Surname-{user.Surname}, Upn-{user.UserPrincipalName}, JobTitle-{user.JobTitle}, Id-{user.Id}");
}
else
{
Console.WriteLine("The provided User is null!");
}
}
private static async Task<User> UpdateUserAsync(GraphServiceClient graphServiceClient, string userId, string jobTitle)
{
User updatedUser = null;
try
{
// Update the user.
updatedUser = await graphServiceClient.Users[userId].Request().UpdateAsync(new User
{
JobTitle = jobTitle
});
}
catch (ServiceException e)
{
Console.WriteLine($"We could not update details of the user with Id {userId}: " + $"{e}");
}
return updatedUser;
}
private static async Task<List<User>> GetUsersAsync(GraphServiceClient graphServiceClient)
{
List<User> allUsers = new List<User>();
try
{
IGraphServiceUsersCollectionPage users = await graphServiceClient.Users.Request().Top(5).GetAsync();
// When paginating
//while(users.NextPageRequest != null)
//{
// users = await users.NextPageRequest.GetAsync();
//}
if (users?.CurrentPage.Count > 0)
{
foreach (User user in users)
{
allUsers.Add(user);
}
}
}
catch (ServiceException e)
{
Console.WriteLine("We could not retrieve the user's list: " + $"{e}");
return null;
}
return allUsers;
}
private static async Task DeleteUserAsync(GraphServiceClient graphServiceClient, string userId)
{
try
{
await graphServiceClient.Users[userId].Request().DeleteAsync();
}
catch (ServiceException e)
{
Console.WriteLine($"We could not delete the user with Id-{userId}: " + $"{e}");
}
}
}
}
After providing access to app during execution , i got below exception:
Microsoft.Graph.ServiceException: 'Code: generalException
Message: An error occurred sending the request.
'
NullReferenceException: Object reference not set to an instance of an object.
at GetMeAsync(graphServiceClient).GetAwaiter().GetResult();
Please help.
Shortest code to reproduce problem.
using System;
using Microsoft.Graph;
using Microsoft.Graph.Auth;
using Microsoft.Graph.Core;
using Microsoft.Identity.Client;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Linq;
namespace AzureActiveDirectory
{
class Program
{
//3. Copy the following code as is to your application.
// Register your app on the Azure AD application registration portal
// Remember to :
// 1. Check the redirect uri starting with "msal"
// 2. Set "Treat application as public client" to "Yes"
const string clientId = "XXXXXX";
const string tenant = "XXXXX";
const string redirectUri = "http://localhost";
// Change the following between each call to create/update user if not deleting the user
private static string givenName = "test99";
private static string surname = "user99";
private static void Main(string[] args)
{
// Initialize and prepare MSAL
//What we want to do
// string[] scopes = new string[] { "user.read", "user.readwrite.all" };
string[] scopes = new string[] { "user.read" };
IPublicClientApplication app = PublicClientApplicationBuilder.Create(clientId)
.WithAuthority(new Uri($"https://login.microsoftonline.com/{tenant}"))
.WithRedirectUri(redirectUri)
.Build();
// Initialize the Graph SDK authentication provider
InteractiveAuthenticationProvider authenticationProvider = new InteractiveAuthenticationProvider(app, scopes);
GraphServiceClient graphServiceClient = new GraphServiceClient(authenticationProvider);
// Get information from Graph about the currently signed-In user
Console.WriteLine("--Fetching details of the currently signed-in user--");
GetMeAsync(graphServiceClient).GetAwaiter().GetResult();
Console.WriteLine("---------");
// Create a new user
Console.WriteLine("---------");
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
private static async Task GetMeAsync(GraphServiceClient graphServiceClient)
{
// Call /me Api
var me = await graphServiceClient.Me.Request().GetAsync();
Console.WriteLine($"Display Name from /me->{me.DisplayName}");
var directreports = await graphServiceClient.Me.DirectReports.Request().GetAsync();
foreach (User user in directreports.CurrentPage)
{
Console.WriteLine($"Report's Display Name ->{user.DisplayName}");
}
}
}
}
The interactive flow is used by mobile applications (Xamarin and UWP) and desktops applications to call Microsoft Graph in the name of a user. Please go to Azure portal to check if you have added the correct platform.
The code works fine.
I am currently trying to authenticate Graph API using my C#. I am able to query this API and receive the token successfully from Postman.But when I call same API, I get 404 error.
My code is as below:
using System;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace GraphTest
{
public class AuthenticationModel
{
public string grantType { get; set; } = "client_credentials";
public string clientId { get; set; } = "my_ad_app_id";
public string clientSecret { get; set; } = "client_secret";
public string scope { get; set; } = "https://graph.microsoft.com/.default";
}
public class Authentication
{
private static string tenantId = "tenant_id";
private static readonly HttpClient Client = new HttpClient();
public Authentication()
{
var authenticationModel = new AuthenticationModel();
RunAsync().GetAwaiter().GetResult();
}
private static async Task RunAsync()
{
Client.BaseAddress = new Uri("https://login.microsoftonline.com/");
Client.DefaultRequestHeaders.Accept.Clear();
Client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("*/*"));
Client.DefaultRequestHeaders.Add("Host", "login.microsoftonline.com");
Client.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
try
{
var authenticationModel = new AuthenticationModel();
var url = await GetTokenAsync(authenticationModel);
Console.WriteLine($"Created at {url}");
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
}
private static async Task<Uri> GetTokenAsync(AuthenticationModel authenticationModel)
{
var keyValues = authenticationModel.GetType().GetProperties()
.ToList()
.Select(p => $"{p.Name} = {p.GetValue(authenticationModel)}")
.ToArray();
var xUrlEncodedBody = string.Join('&', keyValues);
var response = await Client.PostAsJsonAsync(
$"{tenantId}/oauth2/v2.0/token", xUrlEncodedBody);
response.EnsureSuccessStatusCode();
return response;
}
}
}
So, I recieve this in response: StatusCode:404, ReasonPhrase:Not Found
Please help me in knowing that where I am doing it wrong.
Note: API with same data works fine with Postman. Though, I have replaced some values here for security reasons.
You should not post form URL encoded content as JSON (PostAsJsonAsync). The body needs to have a content type of application/x-www-form-urlencoded.
But backing up a second, you don't need to implement the protocol yourself when there are libraries out there that do it for you :). We provide and support the Microsoft Authentication Library (MSAL) which makes this easy.
var app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
.WithTenantId("{tenantID}")
.WithClientSecret(config.ClientSecret)
.Build();
string[] scopes = new string[] { "https://graph.microsoft.com/.default" };
AuthenticationResult result = null;
try
{
result = await app.AcquireTokenForClient(scopes).ExecuteAsync();
}
catch (MsalServiceException ex)
{
Console.WriteLine($"Error getting token: {ex.Message}");
}
Console.WriteLine($"Token: {result.AccessToken}");
I ran your code and it is wrongly generating query string as below with spaces.
xUrlEncodedBody => grantType = client_credentials&clientId = my_ad_app_id&clientSecret = client_secret&scope = https://graph.microsoft.com/.default
There is space between query parameter name and value, see below line.
.Select(p => $"{p.Name} = {p.GetValue(authenticationModel)}")
Remove the space and try again
.Select(p => $"{p.Name}={p.GetValue(authenticationModel)}")
i am trying an api and receive data. i got the api username and password but when im trying to connect i get an unauthorized request. i thing something is wrong with my request-header -authentication.
here is my code:
using ApiData;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
namespace GetDataFromApi
{
class Program
{
static void Main(string[] args)
{
string uri1 = "https://api.intrinio.com/companies?ticker=AAPL";
ConnectToApi newapi = new ConnectToApi("username", "password", uri1);
Console.ReadLine();
}
public class ConnectToApi
{
public string Username { get; set; }
public string Password { get; set; }
public string Request_url { get; set; }
public ConnectToApi(string username, string password, string url)
{
this.Username = username;
this.Password = password;
this.Request_url = url;
GetAPIToken(Username, Password, Request_url);
}
private static async void GetAPIToken(string userName, string password, string apiBaseUri)
{
try
{
using (var client = new HttpClient())
{
//setup client
client.BaseAddress = new Uri(apiBaseUri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes($"{userName}:{password}")));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//send request
var responseMessage = await client.GetStringAsync(apiBaseUri);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
}
if you have any comments on my code i would love to hear it.
thanks.
lidor
This might Help
you need to get RestSharp for this to work
var client = new RestClient("https://api.intrinio.com/companies?ticker=AAPL");
var request = new RestRequest(Method.GET);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("authorization", "Basic MGU0NWIxZmIwZDFlMGNkMDEzY2Y2Y2I5MmRlNjk2N2M6MjNjYjM3OTQ3ZmFmMjQ0OWI1MWRjMWQ1NGU2ZGE1Zjc=");
IRestResponse response = client.Execute(request);
and you can try to convert it to an object by
try
{
dynamic x = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(response.Content, new Newtonsoft.Json.JsonSerializerSettings() { NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore });
return x;
}
catch (Exception ex)
{
Console.WriteLine(ex);
return null;
}
and i do recommend of using http://json2csharp.com/
to create your C# Object
More Information
To get the Value that is used for authorization you can use this method
public static string Base64Encode(string key)
{
var value = System.Text.Encoding.UTF8.GetBytes(key);
return System.Convert.ToBase64String(value);
}
to get the exact value make sure the username and password are concatenated, (username first , password second) and then passed to the method
I am currently generating SAML tokens from ADFS like this:
WSTrustChannelFactory factory = null;
try
{
// use a UserName Trust Binding for username authentication
factory = new WSTrustChannelFactory(
new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
new EndpointAddress("https://adfs.company.com/adfs/services/trust/13/usernamemixed"));
factory.TrustVersion = TrustVersion.WSTrust13;
factory.Credentials.UserName.UserName = "user";
factory.Credentials.UserName.Password = "pw";
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
AppliesTo = new EndpointReference(relyingPartyId),
KeyType = KeyTypes.Bearer
};
IWSTrustChannelContract channel = factory.CreateChannel();
GenericXmlSecurityToken genericToken = channel.Issue(rst)
as GenericXmlSecurityToken;
}
finally
{
if (factory != null)
{
try
{
factory.Close();
}
catch (CommunicationObjectFaultedException)
{
factory.Abort();
}
}
}
Now let's say I build a web application that uses these tokens for authentication. As far as I know the workflow should be like this:
Generate token
client gets generated token (after valid login)
client caches token
client uses token for next login
web application validates token, does not have to call ADFS
How can I validate that the token the client presents is valid? Do I need the certificate of the ADFS server to decrypt the token?
After looking at the excellent thinktecture identity server code ( https://github.com/thinktecture/Thinktecture.IdentityServer.v2/tree/master/src/Libraries/Thinktecture.IdentityServer.Protocols/AdfsIntegration ) I extracted the solution:
using Newtonsoft.Json;
using System;
using System.IdentityModel.Protocols.WSTrust;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Security;
using System.Text;
using System.Xml;
using Thinktecture.IdentityModel.Extensions;
using Thinktecture.IdentityModel.WSTrust;
namespace SimpleWebConsole
{
internal class ADFS
{
public static void tokenTest()
{
string relyingPartyId = "https://party.mycomp.com";
WSTrustChannelFactory factory = null;
try
{
// use a UserName Trust Binding for username authentication
factory = new WSTrustChannelFactory(
new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
new EndpointAddress("https://adfs.mycomp.com/adfs/services/trust/13/usernamemixed"));
factory.TrustVersion = TrustVersion.WSTrust13;
factory.Credentials.UserName.UserName = "test";
factory.Credentials.UserName.Password = "test";
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
AppliesTo = new EndpointReference(relyingPartyId),
KeyType = KeyTypes.Bearer
};
IWSTrustChannelContract channel = factory.CreateChannel();
GenericXmlSecurityToken genericToken = channel.Issue(rst) as GenericXmlSecurityToken; //MessageSecurityException -> PW falsch
var _handler = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection();
var tokenString = genericToken.ToTokenXmlString();
var samlToken2 = _handler.ReadToken(new XmlTextReader(new StringReader(tokenString)));
ValidateSamlToken(samlToken2);
X509Certificate2 certificate = null;
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
certificate = store.Certificates.Find(X509FindType.FindByThumbprint, "thumb", false)[0];
var jwt=ConvertSamlToJwt(samlToken2, "https://party.mycomp.com", certificate);
}
finally
{
if (factory != null)
{
try
{
factory.Close();
}
catch (CommunicationObjectFaultedException)
{
factory.Abort();
}
}
}
}
public static TokenResponse ConvertSamlToJwt(SecurityToken securityToken, string scope, X509Certificate2 SigningCertificate)
{
var subject = ValidateSamlToken(securityToken);
var descriptor = new SecurityTokenDescriptor
{
Subject = subject,
AppliesToAddress = scope,
SigningCredentials = new X509SigningCredentials(SigningCertificate),
TokenIssuerName = "https://panav.mycomp.com",
Lifetime = new Lifetime(DateTime.UtcNow, DateTime.UtcNow.AddMinutes(10080))
};
var jwtHandler = new JwtSecurityTokenHandler();
var jwt = jwtHandler.CreateToken(descriptor);
return new TokenResponse
{
AccessToken = jwtHandler.WriteToken(jwt),
ExpiresIn = 10080
};
}
public static ClaimsIdentity ValidateSamlToken(SecurityToken securityToken)
{
var configuration = new SecurityTokenHandlerConfiguration();
configuration.AudienceRestriction.AudienceMode = AudienceUriMode.Never;
configuration.CertificateValidationMode = X509CertificateValidationMode.None;
configuration.RevocationMode = X509RevocationMode.NoCheck;
configuration.CertificateValidator = X509CertificateValidator.None;
var registry = new ConfigurationBasedIssuerNameRegistry();
registry.AddTrustedIssuer("thumb", "ADFS Signing - mycomp.com");
configuration.IssuerNameRegistry = registry;
var handler = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection(configuration);
var identity = handler.ValidateToken(securityToken).First();
return identity;
}
public class TokenResponse
{
[JsonProperty(PropertyName = "access_token")]
public string AccessToken { get; set; }
[JsonProperty(PropertyName = "token_type")]
public string TokenType { get; set; }
[JsonProperty(PropertyName = "expires_in")]
public int ExpiresIn { get; set; }
[JsonProperty(PropertyName = "refresh_token")]
public string RefreshToken { get; set; }
}
}
}
It's much simpler! For web sites you use WIF (assuming you are using .NET) and then you federate the app with ADFS. (There's a wizard included in the WIF SDK). Everything is taken care of. Parsing, validation, etc. is done by the framework. Your app would deal with users in the regular way: this.User.Name , this.User.IsInRole("admin"), etc.
The scenario is documented here.