Identity Server and Active Driectory - active-directory

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.

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.

Authentication flow Service to Service Microsoft Graph and Bookings API

I am building a custom mobile application that has a client, custom backend server (I'm building) and interacts with numerous other api's. One of these api's is Microsoft bookings.
The problem I'm facing is I need to be authenticated via server to server, with a shared client secret. I'm aware of the numerous docs from MS but have yet to find a solution. I'm wondering if Server to server is even possible with Bookings.
I am able to get an access_token server to server with these permissions. (I have granted 'all permissions' to this app in Azure AD already).
"roles": [
"Calls.JoinGroupCall.All",
"OnlineMeetings.Read.All",
"OnlineMeetings.ReadWrite.All",
"Application.ReadWrite.OwnedBy",
"Calendars.Read",
"People.Read.All",
"Application.ReadWrite.All",
"Calls.InitiateGroupCall.All",
"Directory.ReadWrite.All",
"Calls.JoinGroupCallAsGuest.All",
"Sites.Read.All",
"Sites.ReadWrite.All",
"Sites.Manage.All",
"Files.ReadWrite.All",
"Directory.Read.All",
"User.Read.All",
"Calendars.ReadWrite",
"Mail.Send",
"ProgramControl.Read.All",
"ProgramControl.ReadWrite.All",
"Calls.Initiate.All"
],
Those are the permissions from the decoded token. When I go to make calls to the Bookings api I receive 401.
I can however use this token to access different graph endpoints no problem.
I will note, that I am able to make successful calls to the bookings api through Graph Explorer with my account, not related to this 'Application in Azure AD'.
Does this resource in Azure AD need a bookings License?
Is this even possible S2S?
Are there any other ways to bypass this without user credentials?
Thanks.
So I spent over a week trying to solve this problem due to the MS doc nightmare. I'm only posting to help others!
Bookings doesn't support service to service yet. So if you wan't to implement this without a user physically signing in, IE. If you have a dedicated booking admin account credentials you have to hard code the clients credentials.
I found my answer here https://stackoverflow.com/a/49814924/9105626
Microsoft Bookings API doesn't seem to support "Application Permissions" so far.
Only permissions available are "Delegated Permissions", which means your token has to be acquired with the context of a signed-in user.
Here are two Microsoft documentation sources that I came across:
Microsoft Graph Permissions Reference - Please look at the "Bookings Permissions" section.
Microsoft Bookings Samples
I know you mention Server to Server authentication using a client secret. AFAIK, that case will NOT work directly, because clientId and clientSecret only provide an application's identity (which can't be assigned any permissions because there are no relevant application permissions available for this API).
Just in case you can have some User context involved, here is code from bookings samples link above, to acquire the token in a Native application using ADAL
var authenticationContext = new AuthenticationContext("https://login.microsoftonline.com/common/");
var authenticationResult = await authenticationContext.AcquireTokenAsync(
"https://graph.microsoft.com/",
clientApplication_ClientId,
clientApplication_RedirectUri,
new PlatformParameters(PromptBehavior.RefreshSession));
// The results of this call are sent as the Authorization header of each HTTPS request to Graph.
var authorizationHeader = authenticationResult.CreateAuthorizationHeader();
Suggestions on ways to make this scenario work
On Behalf Of Flow
Your mobile application client could prompt a user for credentials to act on Behalf of the user and call your backend web API, which in turn calls the downstream API like Bookings API. This is called Service to Service Calls on behalf of the User
Here is a code sample which shows exactly this with a native application (WPF) and an SPA. In your case, just replace the WPF application with your mobile client application for understanding purposes and rest of the scenario becomes very similar.
Calling a downstream web API from a web API using Azure AD
ROPC Grant (Not Recommended)
Resource Owner Password Credentials grant can help as your application will have end user password available to it, but it has multiple issues and any security guidance will discourage you from using it.
ROPC opens up security risks, doesn't follow best practices and has functionality issues as well. ROPC doesn't work with MFA enabled users as well as federated authentication users.
For all practical purposes, you should avoid ROPC as long as possible. You can find the same recommendation in ADAL documentation itself and multiple other documentations from Microsoft or even generally about OAuth 2.0.

What databases are needed for IdentityServer4 AD provider

Currently I have a working IdentityServer4 service that allows users to authenticate to active directory only. They authenticate and then they have no issue accessing the api. I'm using the the IDP server from IdentityServer4 Quickstart with all the local user account stuff stripped out. Here is my database:
My question is this, were are tokens stored? Only in the browser? Am I doing something wrong? Should there be some sort of database that holds tokens for SSO? It is working but I'm worried I'm missing out on some sort of functionality.
The PersistedGrants table stores the following type of tokens: authorization_code, refresh_token, reference_token, and user_consent.
Regular id_tokens and access_tokens are not persisted in the database, they will be passed to the client to be handled as it sees fit.
SSO is achieved when your IDP server creates a cookie contain identity and session information for your browser to reuse.

Programmatic (API calls) User Authentication using Azure AD B2C instead of login.microsoftoneline.com form

New to Azure AD... So please don't be too harsh if this is off target. :-)
Technology Stack - Latest Angular 2 with C# Middle tier and latest .Net Framework.
Ideally, What we want to do is use Azure AD B2C to store user credentials and to do the authentication - but we want our 'own' forms on our site to do the login Forms capture and logging - then pass the credentials through an API (REST?) Call (using MS Graph SDK?) to Azure AD B2C and then check the call return for the Authorization content message.
Couple of reasons - control of the application flow, Logging and the "flickering of the URL" (i.e. going from our site URL to login.microsoft... URL and then back to our sites URL).
Is this doable without doing a hack?
Thank you in advance for your help and patience!
You are looking for the "Resource Owner Password Credentials".
This is not currently supported for Azure AD B2C, but you can give user feedback to the B2C team that you want this through the Azure Feedback Forum: Add support for Resource Owner Password Credentials flow in Azure AD B2C and headless authentication in Microsoft Authentication Library
You should also see updates at that location if and when they implement this feature.
The resource owner password credentials flow is now in preview.
In Azure Active Directory (Azure AD) B2C, the following options are
supported:
Native Client: User interaction during authentication happens when
code runs on a user-side device. The device can be a mobile
application that's running in a native operating system, such as
Android, or running in a browser, such as JavaScript.
Public client flow: Only user credentials, gathered by an application, are sent in
the API call. The credentials of the application are not sent.
Add new claims: The ID token contents can be changed to add new claims.
The following flows are not supported:
Server-to-server: The identity protection system needs a reliable IP
address gathered from the caller (the native client) as part of the
interaction. In a server-side API call, only the server’s IP address
is used. If a dynamic threshold of failed authentications is exceeded,
the identity protection system may identify a repeated IP address as
an attacker.
Confidential client flow: The application client ID is
validated, but the application secret is not validated.
From here.
Note that one disadvantage of doing what you're requesting is precisely that you can do "login forms capture and logging", so your application has a chance to see the credentials and perhaps take copies of them; thus your users have to trust you to behave.
The normal web-based flow means that your application doesn't need to be trusted; it never even sees the password at all.

API authentication with ADFS and Angular.js

I'm tried to build a new rich application and i'm having some problems designing the authentication process.
I've only two requirements :
An API needs to be available
An ADFS needs to be used to authentication
My first thoughts was to build the API and to use Angular.js for the frontend. However, I can't see how the authentication should work.
My API needs to be available though scripts. As far as I saw, the ADFS authentication always display t the webpage for the authentication process.
API are usually secured with OAuth2. We used an client id and a client secret to generate a token. But I can't have this behavior with an ADFS.
The only solution I see is to provide two authentications behavior with my application. One with the ADFS for the web access and in the web interface, add a possibility to generate a client id and a client secret associated with an user account that could be used for the API to the headless authentication.
Someone has already faced this kind of scenario?
Thanks a lot!
I assume the 'ADFS needs to be used for authentication' really means 'users should be able to use their Active Directory domain credentials to authenticate'.
If that is the case, you should take a look at Thinktecture IdentityServer. It's an OAuth2 authorization server that you can use with a Active Directory identity provider.
P.S. ADFS 3.0 that comes with Windows 2012R2 only supports the authorization code grant, which is not suitable for JavaScript apps.

Resources