Migrating B2C OWIN service from "login.microsoft.com" to "b2clogin.com" - azure-ad-b2c

So I've been migrating an older app service and Xamarin mobile application away from the old versions of MSAL to the latest as well as re-directing my app from 'login.microsoft.com' to the new(er) 'b2clogin.com' issuer URIs. I've been following this guide to migrate to the new issuer URI while still remaining backwards compatible with applications currently out in the field.
However, I'm running this service as an Azure App Service and in the 'Authentication / Authorization' section of my service I have my Active Directory configured with the correct B2C Application 'Client ID' and there's another text box for 'Issuer URL'. I can't seem to get away with not having a URI in that text box whether it be:
https://[id].b2clogin.com/[app id]/B2C_1_SignInUp/v2.0/.well-known/openid-configuration
or
https://login.microsoftonline.com/[app id]/v2.0/.well-known/openid-configuration?p=B2C_1_SignIn
Now this does authenticate just fine as long as I have one issuer or the other issuer but in my code I have:
TokenValidationParameters tvps = new TokenValidationParameters
{
// Accept only those tokens where the audience of the token is equal to the client ID of this app
ValidAudience = ClientId,
AuthenticationType = Startup.DefaultPolicy,
ValidIssuers = new List<string> {
"https://login.microsoftonline.com/[app id]/oauth2/v2.0/",
"https://[id].b2clogin.com/[app id]/oauth2/v2.0/"
}
};
Which I believe should mean that both issuers should be valid (backwards compatible. I've put in a little bit of debug code to verify that this code is being executed at startup. It almost seems like the Azure service is overriding the multiple issuer code but I'm not sure?
Does this documentation work in the Azure App service or is there something more you have to do to configure it? Thanks!

The Azure Authentication / Authorization aka Easy Auth runs before your app code.
So it will only accept one issuer.
I would suggest doing authentication only in your code, and turning off Easy Auth as it cannot fulfill your requirements here.

Related

Getting "unauthorized_client" when trying to login using Microsoft account

In my IS4's Startup.cs:
services.AddAuthentication()
.AddMicrosoftAccount(o =>
{
o.SignInScheme = IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme;
o.ClientId = "clientId";
o.ClientSecret = "clientSecret";
});
I have defined the scope:
openid
profile
And I get the error after I tried to login:
unauthorized_client: The client does not exist or is not enabled for consumers. If you are the application developer, configure a new application through the App Registrations in the Azure Portal at https://go.microsoft.com/fwlink/?linkid=2083908.
It's a web app. So what am I doing wrong here:
I assume the client ID is this:
And my client secret is this:
I have also set up the redirect URI:
The error means the Supported account types are not set for the personal account(Microsoft account in your case).
To solve the issue, navigate to the Manifest of your App registration, set the two properties accessTokenAcceptedVersion and signInAudience like below.
"accessTokenAcceptedVersion": 2,
"signInAudience": "AzureADandPersonalMicrosoftAccount"
When you save the setting, make sure your app meets the requirement of the validation, otherwise there will be some errors.

MS Identity Azure app registered but sends unauthorized_client in implicit flow

I have registered an app in Azure for Microsoft Identity platform. I configured it to allow MS Accounts (e.g. outlook.com) and have basically done everything in a few of the quickstarts online here and here (except for "add credentials to your web app"). I have also checked the boxes that enable implicit flow.
I redirect my React application to the URL to sign in (using implicit flow), I get to enter my username but then I see
unauthorized_client: The client does not exist or is not enabled for consumers. If you are the application developer, configure a new application through the App Registrations in the Azure Portal at https://go.microsoft.com/fwlink/?linkid=2083908
Like I mentioned above, I've gone through several quick starts and read about implicit flow here and followed their examples for my code.
I also tried just deleting the app registration and starting over. No luck.
JS Code attempting to implement Implicit Flow
JS code that redirects the browser to a Url that looks like Microsoft's first example on their implicit flow page
goSignIn() {
const tenant = 'common'; // (for us with MS accounts)
const clientId = '*****';
const redir = encodeURIComponent('http://localhost:3000/signin');
const nonce = Math.round(Math.random() * 10000, 0);
const uriTemplate = 'https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?client_id={clientId}&response_type=id_token+token&redirect_uri={redirect}&scope=openid&response_mode=fragment&state={state}&nonce={nonce}';
const filledTemplate = uriTemplate
.replace('{tenant}', tenant)
.replace('{clientId', clientId)
.replace('{redirect}', redir)
.replace('{nonce}', nonce)
.replace('{state}', nonce);
console.log(filledTemplate);
window.location = filledTemplate;
}
App Configuration in Azure:
Azure -> Identity -> App Registrations -> MyApp -> Authentication
Redirect Uri: http://localhost:3000/signin (React app runs on 3000 and I have a route configured for /signin)
Not using any suggested Redirects.
Checked Implicit checkboxes for ID Token and Access Token
Live SDK support enabled
Supported account types is set to "Accounts in any organizational directory and personal Microsoft accounts (e.g. Skype, Xbox, Outlook.com)"
Azure -> Identity -> App Registrations -> MyApp -> API Permissions
MS Graph
User.Read
Email
Profile
openid
From the docs I read, I thought I had done enough to the id token. I'm not sure what tweak must be made in order to get it to work.
I experienced an issue like this one. The mistake I made has to do with the App ID: when you create the client secret the Azure UI will present the secret and the secret ID. This secret ID is not the one to use in your app's configuration. Rather, you need the Application ID found on the Overview page.
I imagine that there are many configuration problems which can produce this error message. In general: pay close attention to the App ID, if the error is that the app is not found.
It seems that you have done enough to get the token. I have tested this on my side, it works well. Here I provide you with my screenshot for you to check again.
Also, here is my working request url, you can login with your msa to have a test.
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?
client_id=5fd66168-7ba3-4bbc-a155-bff662eed9f7
&response_type=id_token+token
&redirect_uri=http://localhost:3000/signin
&scope=openid
&response_mode=fragment
&state=12345
&nonce=678910

GetExternalLoginInfoAsync always returns null when using Okta for authentication

I'm currently trying to get Okta to work with our MVC based application. Unfortunatly I am not the original designer or author of original code. However after some digging I have found that my predecessors work was based on the sustainsys example app "SampleOwinApplication" and this certainly seems to provided the functionality that we require. So I have based my query on this sample that can be obtained from https://github.com/Sustainsys/Saml2
This works with the sustainsys saml stub but now a genuine authentication provider (in this case Okta)
If I configure the application to use the sustainsys stub authentication provider and using Chrome with a plugin to view SAML tokens. I can see the SAML token come back and is presented to the call back as expected:
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
and when it runs loginInfo gets filed in and all works as expetced.
However when I change to configuration to use my Okta app, I get redirected to log in to Okta (as expecected) and I can see successful authentication and a SAML token comes back to my application (as seen in the Chrome plugin). However the above consumer for the callback ends up with a null value in loginInfo.
Further digging into the issue shows that in the Statup.Auth.cs there is the following code:
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
// Configure the sign in cookie
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
and then the Saml2 authentication is added
app.UseSaml2Authentication(CreateSaml2Options());
So it looks like cookie authentication is being used rather than saml2. If I check for cookies from the sustainsys site I can see them added to the browser and authentication works as expected. However, if I use Okta for authentication, no such cookies get set and the authentication fails.
Removing all the cookie authentication references results in:
A default value for SignInAsAuthenticationType was not found in IAppBuilder Properties. This can happen if your authentication middleware are added in the wrong order, or if one is missing.
So clearly this is required, shifting the call to app.UseSaml2Authentication(CreateSaml2Options()); before app.UseCookieAuthentication in the vain hope of it changing the priority and therefore picking up the SAML token fails and whilst the code runs authentication and the call to AuthenticationManager.GetExternalLoginInfoAsync, always results in a null value being returned regardless of the authentication provider.
So I either need to completely remove the cookie authentication so it is forced to use the saml packet, get Okta to set the necessary cookies or be able to parse the saml 2 token independently rather than relying on AuthenticationManager.GetExternalLoginInfoAsync to do the work.
Any clues/advice is appreciated
See the working configuration I am currently using successfully with Okta for a service provider initiated login:
AuthenticateResult.Succeeded is false with Okta and Sustainsys.SAML2
Unfortunately, it is still not working with an identity provider initiated login.
See: IdP Initiated Login with Sustainsys.SAML2 - AuthenticateResult Has No Information

Azure App Services User Claims AAD Missing ObjectId

I'm in the process of migrating from Azure Mobile Services to App Services and currently struggling to find the AAD User objectidentifier with the new OWIN authentication configured in Startup.MobileApp.cs. `
MobileAppSettingsDictionary settings = config.GetMobileAppSettingsProvider().GetMobileAppSettings();
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
TokenValidationParameters = new TokenValidationParameters { ValidAudience = ConfigurationManager.AppSettings["MS_AadClientID"]},
Tenant = ConfigurationManager.AppSettings["MS_AadTenants"]
});
Previously I was looking for:
claim.Type.Contains("urn:microsoft:credentials")
but none of the Claims on the User.Identity provide an objectidentifier.
Claims
The objectidentifier is available on https://myapp.azurewebsites.net/.auth/me.
{"typ":"http:\/\/schemas.microsoft.com\/identity\/claims\/objectidentifier",
"val":"xxxxxxxx-xxxx-xxxx-xxxxx-xxxxxxxxxxxx"}
Does anybody know if it's possible to access the value without making a call to the URL?
Thanks,
Viv
After digging through both the iOS and .NET server code, I found a method in the Microsoft.Azure.Mobile.Server.Authentication IPrincipalExtensions class.
by making a call to user.GetAppServiceIdentityAsync<AzureActiveDirectoryCredentials>(request);
you can get the AzureActiveDirectoryCredentials.ObjectId.
Be warned though as this is not available if you authenticate directly through the webservice.

EasyAuthModule_32 bit Error 401 in xamarin forms aad authentication

please kindly help me out with my attempt to implement client side authentication for a xamarin forms aplication i am developing. i have followed every single tutorial on how to integrate Azure active directory into xamarin when using azure mobile services. the error is always thrown at the point of calling loginAsync. on futher investigation using the azure log i found out that the error was coming from the easyauthmodule. please help like i said i have followed every single tutorial on this issue and i have been on it now everyday for the past one week
please find my code below
try
{
AuthenticationContext ac = new AuthenticationContext(authority);
ac.TokenCache.Clear();
AuthenticationResult ar = await ac.AcquireTokenAsync(resource, clientId, new Uri(returnUri), new PlatformParameters(this));
JObject payload = new JObject();
payload["access_token"] = ar.AccessToken;
// DataRepository.DefaultManager.CurrentClient.Logout();
user = await DataRepository.DefaultManager.CurrentClient.LoginAsync(MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory,payload);
}
catch (Exception ex)
{
CreateAndShowDialog(ex.Message, "Authentication failed");
}
EasyAuth is incompatible with Azure Mobile Services. Are you sure you are using the right service moniker?
Make sure you are using the following NuGet for Azure Mobile Apps: https://www.nuget.org/packages/Microsoft.Azure.Mobile.Client/
EasyAuth is only available in Azure App Service. You need to configure the App Service Authentication / Authorization module. Assuming you have already integrated ADAL into your Xamarin app and have an access token from ADAL, your code is pretty close. However, I've found that configuration of AAD for mobile apps is complex. So I wrote a couple of blog posts about it.
Here is the server flow edition: https://shellmonger.com/2016/04/04/30-days-of-zumo-v2-azure-mobile-apps-day-3-azure-ad-authentication/
Here is the client flow edition: https://shellmonger.com/2016/04/06/30-days-of-zumo-v2-azure-mobile-apps-day-4-adal-integration/
Both are using Cordova as a mobile client, but the configuration of the service is identical. The client details (aside from the obvious language differences) are similar as well.

Resources