How can I provide the username/email to the identity provider to be pre-filled in the IdP’s username box? - itfoxtec-identity-saml2

I am using itfoxtec-identity-saml2 library to integrate with OneLogin SSO, so How can I send the username/email to the identity provider to be pre-filled in the IdP’s username box?
I know we can use the optional Subject/NameID field in the AuthnRequest message sent from the SP to the Idp to request a specific subject from the Idp. Have you guys done this using ITfoxtec SAML 2.0 MVC?

The currently ITfoxtec Identity SAML 2.0 version do not support the Authn Request Subject element with NameID.
The Subject with NameID is supported from version 3.1.0-beta1 https://github.com/ITfoxtec/ITfoxtec.Identity.Saml2/releases/tag/3.1.0-beta1. This beta version also adds support for Azure Key Vault.
Please let me know if the beta version works for you.
The selected NameID is added to the Subject on the Saml2AuthnRequest:
[Route("Login")]
public IActionResult Login(string returnUrl = null)
{
var binding = new Saml2RedirectBinding();
binding.SetRelayStateQuery(new Dictionary<string, string> { { relayStateReturnUrl, returnUrl ?? Url.Content("~/") } });
return binding.Bind(new Saml2AuthnRequest(config)
{
Subject = new Subject { NameID = new NameID { ID = "abcd" } },
}).ToActionResult();
}
* Update *
Version 4.0.0 is released supporting Subject with NameID.

Related

How do I check to see if my AzureAD version is V1 or V2? with middle ware

AZURE AD V1 V2
above all agree but v1.0 tokens contain both the x5t and kid claims, v2.0 tokens contain only the kid claim. and i m using ISecurityTokenValidator custom token validator
public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
var principal = _tokenHandler.ValidateToken(securityToken, validationParameters, out validatedToken);
will this be going to be impacted ?? after i will start using V2 end point and token ??
Token validation will keep working fine. You might need to change JWT claim type mapping though.

IdentityServer4 and Azure AD - Getting blank page 404 to login.live after entering credentials

I am trying to setup Azure AD as an external provider for IdentityServer4 in a development environment. Google and Facebook providers already are hooked up successfully.
I'm directed to the login page on login.microsoft.com where I enter my login id and select an MS account, it then directs me to login.live.com as a blank page (404) instead of redirecting back to my IdentityServer instance.
I've tried a bunch of things but have had no luck.
Do I need to enable Enterprise Applications in Azure?
Am I missing something?
IdentityServer URL:
http://localhost:5000
IdentityServer URL:
http://localhost:47740
...
app.UseOpenIdConnectAuthentication(CreateAzureAdOptions(clientId, tenantId));
...
public static OpenIdConnectOptions CreateAzureAdOptions(string clientId, string tenentId)
{
return new OpenIdConnectOptions
{
DisplayName = "Azure Active Directory",
AuthenticationScheme = "Azure",
ClientId = clientId,
Authority = string.Format(CultureInfo.InvariantCulture, "https://login.microsoftonline.com/{0}", tenentId),
ResponseType = "id_token",
Scope = { "openid" },
SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme,
AutomaticChallenge = true,
AutomaticAuthenticate = true,
RequireHttpsMetadata = false,
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false
}
};
}
This probably is related to the size of the url when returning from AAD. This is actualy a 404.15 IIS specific status code. If you have a lot of claims returned from your External identity provider (ie a profile image base64) then you will always hit the cap in url length HTTP Error 404.15 - query url too long RSS.
IdenitityServer4 has a topic in the docs that addresses this issue by using the distributed cache underneath. It is located under Sign-in with External Identity Providers - State, URL length, and ISecureDataFormat
Abstract:
Fortunately, IdentityServer provides an implementation of this for you, backed by the IDistributedCache implementation registered in the DI container (e.g. the standard MemoryDistributedCache). To use the IdentityServer provided secure data format implementation, simply call the AddOidcStateDataFormatterCache extension method on the IServiceCollection when configuring DI. If no parameters are passed, then all OpenID Connect handlers configured will use the IdentityServer provided secure data format implementation.

How to do role based authorization in Azure with Asp.net webapi backend and front end as Angular

How I can do Azure role based authentication in webapi backend. I see tons of example for Asp.net MVC but none for webapi with front end as Angular. I have hosted my website developed in angular with backend as webapi and hosted it on Azure and enabled the Authentication/authorization as Azure Active directory in Azure website. Also I have done the setup for AD application for roles in its manifest files. After I hit website, I have to authenticate and then after authentication it redirects to my website . During my website load it calls my webapi and the Authentication token with claims is passed to my webapi. In webapi I am checking for InRole or [Authorize(Roles = "admin")] and based on that I am allowing access. However in token roles do not flow by default . So I query graph api to get roles by extracting the information from token and pass it to graph api to get roles. I am doing query in Owin Startup class to fetch role, But I am not able to get success. Is there anything wrong with the code, Please help . The code is copied below. Also I could have used ADAL JS library in Angular to authenticate with AD but I don't need to do so as I have enabled authentication in Azure website using the option "Authentication/Authorization". The layer of Authentication in website will do all token validation and forward it to webapi.
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IdentityModel.Tokens;
using System.Linq;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.ActiveDirectory;
using Owin;
using System.Security.Claims;
using System.Net;
using System.Web;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.Owin.Security.OAuth;
using Microsoft.Azure.ActiveDirectory.GraphClient;
using System.Threading.Tasks;
namespace OneMap.Web
{
public partial class Startup
{
// Apply bearer token authentication middleware to Owin IAppBuilder interface.
private void ConfigureAuth(IAppBuilder app)
{
var tenantId = Common.Configuration.GetConfigurationSetting("ida:Tenant");
// ADAL authentication context for our Azure AD tenant.
var authenticationContext = new Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext(
$"https://login.windows.net/{tenantId}", true, TokenCache.DefaultShared);
// Secret key that can be generated in the Azure portal to enable authentication of a
// specific application (in this case our Web API) against an Azure AD tenant.
var applicationKey = Common.Configuration.GetConfigurationSetting("ida:Password");
// Root URL for Azure AD Graph API.
var azureGraphApiUrl = "https://graph.windows.net";
var graphApiServiceRootUrl = new Uri(new Uri(azureGraphApiUrl), tenantId);
var clientId = Common.Configuration.GetConfigurationSetting("ida:ClientId");
// Add bearer token authentication middleware.
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
// The id of the client application that must be registered in Azure AD.
TokenValidationParameters = new TokenValidationParameters { ValidAudience = clientId },
// Our Azure AD tenant (e.g.: contoso.onmicrosoft.com).
Tenant = tenantId,
Provider = new OAuthBearerAuthenticationProvider
{
// This is where the magic happens. In this handler we can perform additional
// validations against the authenticated principal or modify the principal.
OnValidateIdentity = async context =>
{
try
{
// Retrieve user JWT token from request.
var authorizationHeader = context.Request.Headers["Authorization"];
var userJwtToken = authorizationHeader.Substring("Bearer ".Length).Trim();
// Get current user identity from authentication ticket.
var authenticationTicket = context.Ticket;
var identity = authenticationTicket.Identity;
// Credential representing the current user. We need this to request a token
// that allows our application access to the Azure Graph API.
var userUpnClaim = identity.FindFirst(ClaimTypes.Upn);
var userName = userUpnClaim == null
? identity.FindFirst(ClaimTypes.Email).Value
: userUpnClaim.Value;
var userAssertion = new UserAssertion(
userJwtToken, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName);
// Credential representing our client application in Azure AD.
var clientCredential = new ClientCredential(clientId, applicationKey);
// Get a token on behalf of the current user that lets Azure AD Graph API access
// our Azure AD tenant.
var authenticationResult = await authenticationContext.AcquireTokenAsync(
azureGraphApiUrl, clientCredential, userAssertion).ConfigureAwait(false);
// Create Graph API client and give it the acquired token.
var activeDirectoryClient = new ActiveDirectoryClient(
graphApiServiceRootUrl, () => Task.FromResult(authenticationResult.AccessToken));
// Get current user groups.
var pagedUserGroups =
await activeDirectoryClient.Me.MemberOf.ExecuteAsync().ConfigureAwait(false);
do
{
// Collect groups and add them as role claims to our current principal.
var directoryObjects = pagedUserGroups.CurrentPage.ToList();
foreach (var directoryObject in directoryObjects)
{
var group = directoryObject as Group;
if (group != null)
{
// Add ObjectId of group to current identity as role claim.
identity.AddClaim(new Claim(identity.RoleClaimType, group.ObjectId));
}
}
pagedUserGroups = await pagedUserGroups.GetNextPageAsync().ConfigureAwait(false);
} while (pagedUserGroups != null);
}
catch (Exception e)
{
throw;
}
}
}
});
}
}
}
AFAIK, the roles claim only issued in the id_token. After you change the manifest of app(refer here), you can using the SPA get the id_token and access the web API according the roles via the id_token.
And there is no need to using the Authentication/authorization since you have protect the web API using the Microsoft.Owin.Security.ActiveDirectory OWIN middleware. To authenticate the SPA you can refer this code sample.

Identity Server 3 AzureAd Claims not returning

I have a working Identity Server application, and I'm setting it up to work with Azure AD. I've got my Azure Ad App registration and I can authenticate with it properly.
Looking at this and trying to do something similar to store the 3rd party user IDs associated with a user, but I'm not getting the sub or nameIdentifier claims back from AAD.
Do I need to request these from AzureAD somehow? - Their docs seem to be to be saying that the "sub" claim is (or at least can be) returned: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-token-and-claims#_subject. This article seems to say that sub isn't returned, but it's for multitenant applications, so I'm not too sure if that's relevant.
I'm sure I'm missing something simple, but can't find anything relevant on Google.
Cheers,
Alex
The article Work with claims-based identities is too old and this Azure AD token reference article should be right about the token claims in the token issued by Azure AD.
Based on the test, I could get the sub claim from Azure AD and it also issued by the IdentityServer3 like figure below:
Here is the code I configed for the IdentityServer3 for your reference:
var webApp = WebApp.Start("https://localhost:44333", app =>
{
app.UseIdentityServer(new IdentityServerOptions
{
SiteName = "NDC Demo",
SigningCertificate = cert,
Factory = factory,
AuthenticationOptions = new AuthenticationOptions
{
IdentityProviders = ConfigureAdditionalIdentityProviders,
EnableAutoCallbackForFederatedSignout = true
}
});
});
public static void ConfigureAdditionalIdentityProviders(IAppBuilder app, string signInAsType)
{
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
AuthenticationType = "aad",
Caption = "Azure AD",
SignInAsAuthenticationType = signInAsType,
Authority = "https://login.microsoftonline.com/{tenantId}",
ClientId = "{clientIdFromAzurePortal}",
RedirectUri = "{redirectUri}",
});
}
If you still have the problem, would you mind sharing the request to Azure AD which you can capture it using Fiddler.

identity server 4 using multiple external identity providers

I would like to use identity server 4 with a bunch of different external identity providers. Not just one.
For example: one business might use ADFS for their EIP another will use AZURE identity and so on. In this scenario there would only be one instance of identity server accessing different External id providers.
Is this possible or has anyone ever tried this. If not, do you know of a service that does do this.
Of course this is possible. You can register as many external IdP's in your Startup class as you like. Be sure to also check out the sample quickstart repositories from Identityserver.
This code will register AzureAd and Google as external IdP's.
In advance to set this up you will have to register your application in developers.google and AzureAd to authorize your application.
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
ClientId = Configuration["AzureAd:clientid"],
Authority = Configuration["AzureAd:authority"],
ClientSecret = Configuration["AzureAd:secret"],
PostLogoutRedirectUri = "/signed-out",
AuthenticationScheme = "AzureAd",
ResponseType = OpenIdConnectResponseType.CodeIdToken,
SaveToken = true,
});
app.UseGoogleAuthentication(new GoogleOptions
{
ClientId = Configuration["Google:clientid"],
ClientSecret = Configuration["Google:secret"],
AuthenticationScheme = "Google",
SaveTokens = true
});

Resources