Azure B2C custom policy external datasource authentication - azure-active-directory

I'm trying to configure Azure B2C in such a way that it prompts the user for a login id and password, these are then authenticated using an external REST call, and it returns an OIDC token containing whatever claims I wish to return in the REST call.
I can make the REST call work and add claims to an existing example policy no problem. The problem is removing the superfluous Azure AD behaviour without breaking the policy.
If the user doesn't exist in the Azure AD Directory, I don't care, I'm not interested in the user having an Azure profile at all, I want all the user data to come from the application's own database, but I haven't found a way to stop Azure from redirecting the user to create a new local AD account if one doesn't already exist.
The documentation is very dense and has a few walk-throughs of how to do a few of the things it expects you to want to do, but nothing like what I want to do. It points to a startup pack and some samples, but again these are very fully featured and not what I want to do, and trying to work backwards from them is proving intractible.
What's lacking is something that describes how to create a custom policy from scratch and take full control of the process of authenticating the user.
Does anyone have any suggestions of how to go about this, or know of some good documentation about this kind of thing?

There's an example here.
Basically, self-asserted screen to get credentials, verify against API, send JWT to application.

Related

Linking External Identity Users With Existing Users

I'm adding an external identity provider, Azure multi-tenant, as a login option. I have local accounts right now and they know nothing about Azure AD users.
I want to create an Azure Enterprise App that other tenants can use to set up SSO using OpenID Connect. Also I want the app to support User Provisioning by setting up a SCIM API.
I can't really find any documents on how to handle linking Azure AD users with the existing accounts in my IDP. I've seen examples where users can login using their local account, authenticate with Azure, and then their local account is updated to have the Azure AD User ID. This approach still seems pretty manual. Another thought was to have a step in the login journey, where if no local account has the Azure AD User ID then find a local account with the same email. I don't like this approach either since the emails might not always match. Is there an approach where an admin can automatically link all accounts with a sync or upload?
SYSTEMS
First it's worth clarifying roles:
Role
Details
Authorization Server (AS)
Your UIs and APIs receive tokens from this. It is where accounts and linked accounts are stored. It is where you use SCIM to update account records. It is where you apply account linking logic.
Identity Provider (IDP)
There can be multiple of these. When your apps call the AS it manages connections to them, and exchanges IDP tokens for AS tokens that are returned to apps. It is not usual to use SCIM against an IDP.
You are using IdentityServer as the AS so your UIs and APIs will continue to use IdentityServer tokens and remain simple. Meanwhile Azure AD will become an alternative IDP. So on the data side of things your architecture is in a good place.
AUTHENTICATION ACTIONS
I would aim to solve your problems via custom authentication actions, and to design this in a vendor agnostic way. Not all providers support these concepts, but IdentityServer has some pretty good extensibility features, so hopefully it has what you need.
A bit of code, configuration and technical investigations in IdentityServer feel like the correct direction, with no complexity added to your applications. I will describe techniques in terms of Curity (where I work), but the same principles can apply to any system.
USERNAME AUTHENTICATOR
A great way to deal with user specific differences is to make the initial screen prompt only for an email. See this example for how that looks. Later, when authentication has completed, you could set a cookie so that this screen is not shown on subsequent logins.
Then, before asking for credentials, apply some scripted logic, eg to look up existing account attributes, and decide how the user should authenticate. You might decide to route unknown users to Azure AD or do something based on business partner email suffixes.
DATA UPDATES
Something simple that might work in advance of adding Azure AD support is to assign all users a Tenant ID, and perhaps existing users get a Tenant ID of 1. Only those users are allowed to sign in with Identity Server - all others have to use Azure AD.
SCRIPTED LOGIC AND ACCOUNT LINKING
For a worked example of how this looks, see this Account Linking with Facebook tutorial. In this example the objective is to update the main account with a new linked account. This account linking doc may give you some additional ideas for your scenario. It should be possible to run custom logic before triggering authentication or once your have the Azure IDP attributes.
INVOLVE THE USER IF NEEDED
It may also be useful to present a custom screen to ask the user if they have an existing account when they first login via Azure AD. If not then an Azure AD login can create the primary account in IdentityServer data in addition to a linked account.
USERS AND PARTNERS
How users onboard is interesting, and discussed in this detailed article. I always start by getting a feel for the type of assets involved:
Type
Description
Personal Assets
You allow any user to sign up and they only have access to their own assets
Corporate Assets
Users are provisioned by an administrator, eg a banker is granted access to financial data according to business rules
In your case it feels like users are from the second category, so to enable a user to fully sign up you need data from the partner, either fed in manually or by getting them to call your API, before you can assign the user the correct tenant ID. This might eventually result in TenantID=23, but there is nothing to stop you initially allowing users to onboard and placing them in a default TenantID=0 bucket.
Ultimately this all comes down to data, claims and API authorization. Eg APIs could return certain data to TenantID=0 users but only return privileged data to users whose tenant ID has been asserted by an administrator. Not sure if these thoughts of mine match your scenario but hopefully they provide a useful hint or two.
SUMMARY
Reliable account linking is tricky, but it should be solvable via the building blocks of the Authorization Server, using the above techniques. The end result should be deterministic user data, with no duplicate users.

How can I change the azure directory when I am using the login.windows.net page

This url uses one of the azure active directory I can access. Unfortunately, it's not the good one. How can I change this behavior to point it to the good one or to give me the choice after login ? Changing the directory in the Azure Portal Subscription Filter doesn't work.
I would prefer a solution that works without changing the url (I will have to use Skype for Business Online Application Registration Portal and I have the same problem with it).
If I understand you correctly you want to use the OAuth2 authorization endpoint specific to your tenant. In order to get the authorization token specific to tenant you need to simply write :
https://login.windows.net/{yourtenantname}.onmicrosoft.com/oauth2/authorize?api-version=1.0
or
https://login.windows.net/{tenantid}/oauth2/authorize?api-version=1.0
Please refer to this blog for additional details.

How to aquire access token without UI with Microsoft.Identity.Client and Integration Testing

I have an API locked down by Azure B2C. Everything is configured correctly for my client app that consume this API. My question relates to the integration tests that accompany the API. While it's pretty obvious that authentication triggers a UI to sign in, how would one go about requesting a token for tests cases that require authentication without popping a UI up?
Right now I have to have a utility that allows me to grab an access token (by popping up a UI) and then using that in my test project. Ultimately it expires so all the tests fail. This makes sense but I'm wondering if anyone has come up with a way to automate the process of acquiring tokens using this library so that the test cases can acquire them without popping up a UI. Screen scraper?
It looks like you want the Resource Owner Password Grant Flow. B2C does not officially support this, but Azure Active Directory does.
Read these:
Can I use "Resource Owner Password Grant" flow with Azure AD B2C
https://blogs.msdn.microsoft.com/wushuai/2016/09/25/resource-owner-password-credentials-grant-in-azure-ad-oauth/
Note that in the scenarios where B2C is simply acting like AAD (local accounts), you can use this flow. But for other social identity providers like Facebook and Google, you cannot use this flow.
I like your original method which is to generate an access token outside the app, and paste it in. I recommend adding to that the Refresh Token you got, and code to acquire a new token using an existing refresh token. Something like this.
Let me know if this helps.

Identity Server and Active Driectory

My current setup is a fairly simple one. I am running Identity Server 3 which is used to provide oauth access tokens which can be used against and a number of our web api endpoints. The identity server has custom user service which authenticates requests against a custom user table in our sql database.
We have a new 3rd party software provider, this provider requires that our users (staff in our call centre) logon to their application via a proprietary login, not against our existing user accounts. We have built an api for this 3rd party which they required for their integration, as with the rest of our api's this is secured using oauth bearer tokens via identity server.
Our staff are all locally logged on to an active directory domain. Is it possible to configure identity server to issues auth tokens for a user who is already authenticated against active directory? I like to achieve this without prompting the user for their credentials again.
I've read around and at this point I'm very lost as to the correct approach, some form of federation seems appropriate, but I couldn’t find a reasonable introduction / walkthrough to help me get started.
What is an appropriate approach and are they any relatively easy to consume primers on the subject?
Yes, you should be able to make it work. The samples contain a windows auth provider. Using this, your identity server would authenticate people in without prompting for a password. Once authenticated, it would then issue tokens same as any other auth. You may need to a bit of experimenting to get it working, but from what you've said it should work in your situation.

Connect a salesforce user to another salesforce user in another org without any user intervention

We would like to connect a salesforce user to another salesforce user in another org without any user intervention from a service.
We have tried SAML Bearer Flow (using Remote Access Application) to connect to salesforce to retreive Access Token for one of our product. We are referring to the follwoing article.
http://help.salesforce.com/help/doc/en/remoteaccess_oauth_SAML_bearer_flow.htm
As referred by the SF article for this flow, it uses a previous user authorization to connect and retreive Token. In case the user (for whom Token is requested) has not already authorized the App, SF takes you to the Authorization page first and app will get the access token once app is authorized. This is working fine too. However it has this painful step of users authorizing the app before we can use this flow for the product. It would be good and simplified if this step can be done once for an org and the article does mentions that either User or Admin can authorize the app. However I am not able to find how an Admin can authorize the remote access application.
Does anyone knows and can guide how can an Admin authorize an App or is thre any other way we can achieve our requirement. Any thoughts will be really appreciated.
OAuth1 and OAuth2 require user intervention by design. Anything you do to defeat this would be circumspect and not best practice. You could make it easy on the user, but you will always have the initial "Authorize this app" message.
If you are trying to make it easy for the user to login to either org, then you may want to consider a hub-and-spoke SSO solution. See this doc.
If you are trying to pass information between two Salesforce instances, then you may want to consider Salesforce2Salesforce, or outbound workflow. However, this is done at system context, not user context.
If you want to maintain user context and security, you should consider the new Salesforce Canvas API. Canvas allows you to call an outbound service, and pass credentials to the service so that it can communicate back. There is no reason the foreign service could not be a Salesforce instance.

Resources