How to authenticate a Windows Forms client using SAML? - winforms

I have been looking into using an identity provider (IDP) to provide user authentication for a Windows Forms client. The user credentials will be hosted by Auth0. After creating a trial account with Auth0 I have downloaded a sample C# Windows Forms client application that can be used to authenticate to the Auth0 IDP using OpenID Connect ("OIDC"). The WinForms sample application pops up a web browser component, displays the Auth0 login screen, I login to the Auth0 IDP (having setup some test credentials in Auth0) and the WinForms application then is sent an authentication token. All well and good, and if I try to login a second time I no longer need to enter my credentials.
However... the company that I will be fetching authentication data from in production would like to use SAML. Is there any way to do this? Based on what I have read, SAML needs a "Service Provider" that will receive credentials from the IDP. The Service Provider is (typically?) a web site. That does not seem to match very well with what I am trying to do (authenticate a windows client). Is there any way of using SAML to do essentially what I have done using OIDC (fetch authentication information for a user from an IDP)? Would I need to develop a separate Service Provider component for this?

Sounds like what you've done so far is fine architecturally:
A modern desktop app following OIDC standards
This puts you in a good position architecturally, where:
Your app gets tokens from Auth0 using OIDC
Auth0 can reach out and do federated authentication with other standards based identity providers, which could be SAML, OIDC, WS-Federation or anything else
This can be done without changing any code in your app - and your app does not need to understand SAML
Feels like you need to set up a federated connection from Auth0 to the SAML Service Provider, and most commonly this involves these steps:
You give the partner your Entity Id and Response URL, to post tokens to
They give you am Entity Id, Public Key Certificate and request URL
You configure rules around account linking, so that users can be matched between their system and yours
There are prerequisites though, and the external identity provider needs to be SAML 2.0 compliant. My Federated Logins Article may help you to understand the general concepts, though I do not drill into SAML details here.

Related

Use IdentityServer4 to allow Employee Login via ADFS using SAML2 and then issue a JWT

My goal is to provide an internet facing application that can be used by both corporate employees and external users. I would have 2 ADFS instances behind an IdentityServer4 instance, one for external users and one for corporate employees.
In general all users(employees or external) should always get an oAuth2 Token to call internet facing APIs, but when there are internal calls between SAML dependent corporate systems, the internal calls should be able to get a SAML2 token or impersonate a corporate corporate user.
No problem with external users, using openid and oAuth2. The main focus is employee login via SAML2.
The setup is as below:
IdentityServer4 sits in the front backed by ADFS
Client applications should connect with IdentityServer4 using OpenId specs (/connect/authorize? end point. I know how to do that
IdentityServer4 should connect to ADFS for external users setup via Ws-Fed. I know how to get till here.
IdentityServer4 should connect to internal ADFS for corporate employees over SAML2. It would be nice to be able to switch between the two ADFS' instances based on user's email address. Just like on Azure you get a message: we are taking you to your employer's login page, if user entered a known corporate email domain. This switch should happen via IdentityServer UI though, probably mimicking Home Realm Discovery feature.
IdentityServer4 should issue oAuth tokens in either case.
6 When connecting to corporate ADFS via SAML2, IdentityServer4 should receive a signed, encrypted SAML2 token response and it should then issue regular oAuth token for external APIs
Some external APIs might want to call internal corporate SAML based APIs, (*only for corporate users) There must be a way to impersonate the user, get his SAML token and pass to corporate APIs.
If all of that makes sense,
- how can I achieve step 5,6 and 7?
- Is there a middleware that can exchange SAML2 token with ADFS?
- Is it just possible to pass this SAML2 token directly to internal SAML
supporting systems?
I have never used SAML2 token before so I am a little lost as to how does it look like, is it something like an access token or is it something to be built using the assertions in ADFS response?
I know I asked a lot of questions but everything is related. I am exploring SustainSys but haven't been able to find way to plug it in to do what I want to do.

Authentication redirection to login page on IdentityServer

I have IdentityServer 4 and an MVC application that gets the identity from IdentityServer. Everything works fine.
My question is why do I have to login on IdentityServer and not on the MVC project?
I would prefer to stay in my MVC project, instead of being redirected to IdentityServer and back to my MVC project. Can somebody please explain why it has to work like that?
The redirects takes time, are not instant, and creates a lot of traffic that is unnecessary. I understand this redirection when there is an external provider like Facebook, but in my case I think it is useless.
And is it possible with IdentityServer 4 to login/create user on the Mvc app and call the api functions from IS4 server for Login/Create User?
The behavior you don't like is just a protocol. The protocol called OpenId Connect. And Identity Server just implements that protocol. The idea is that only Identity Provider itself can authenticate a user secure enough. There is a workaround called Resource Owner password flow or grant, where you ask a user for credentials in you client app and then transfer that credentials to IdP. The flow is not recommended for general use, but you may use it whenever you own both client app and IdP. One more possible solution for you (in case you own the only app and by some, really strange, reason would like to use Identity Server as an IdP) is to host Identity Server inside of your app. Then using IdentityServerTools helper class you can access the IdSrv internals without network calls.You can find much more information on both these approaches in Identity Server Docs and OpenId Connect specification.

Is Azure OAuth 2 auth code grant an authentication protocol

Sorry I am still very confused, read everywhere telling me oath is a authorisation protocol but it appears using the azure ad oauth code grant, it does promote a login screen to authenticate against the directory, so is it not an authentication process? what is the relationship between the open id connect? thanks!!
the OAuth2.0 protocol has several flows that an identity provider (in your case Azure AD) may implement to support auth.
The Auth Code flow is in fact one of these used by apps to get access tokens for some api. The flow is quite simple, an app redirects the user to the identity providers /authorize endpoint. At this point the user enters their credentials, and the site redirects back to your application with an authorization code and can also issue an ID Token that represents a user (This is the OpenID Connect part). The app takes this code, and POSTs it to the /token endpoint and will be issued an access token and refresh token. With the access token, your app can access whatever api you've requested access for.
For Azure AD specifically, Microsoft has built libraries that handle all these flows and token caching so most of the complexity is abstracted away. There's some simple code samples that you can checkout that you may find helpful. The authentication protocols and scenarios doc for Azure AD may also be really helpful for conceptual information.

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.

What OpenID Connect authorization flow to authenticate mobile app users?

I am building a cross-platform mobile app that interacts with a RESTful API, and I want to use OpenID Connect to authenticate my users. I will be building my own OpenID Connect provider server.
OpenID.net claims that:
OpenID Connect allows for clients of all types, including browser-based JavaScript and native mobile apps, to launch sign-in flows and receive verifiable assertions about the identity of signed-in users.
However, I can't find any documentation explaining how to actually authenticate for a mobile app client.
This StackExchange answer makes it clear that OpenID Connect does not support the "resource owner password-based grant" flow or the "client credentials" flow.
That just leaves the "authorization code" flow (normally used by server-side apps) and the "implicit grant" flow (normally used by client-side apps). Both of these seem to rely on redirecting the user to the provider's authorisation endpoint, and having the provider redirect back to the client URL. I don't see how this can apply to a mobile app.
Can anyone explain to me (or even better, point me at a tutorial or some example code) which explains how to do this?
Update
To clarify: OpenID Connect relies on the client redirecting the user to the Authorization Endpoint, and then the provider redirecting the user back to the client. In the case where the client isn't a web app, how can this work?
Mobile apps, at least on iOS and Android, can register custom URL schemes so that a redirect from a browser can send the user back to your app along with some query parameters.
So, you can use these flows in a native mobile app, but it involves sending the user to a web browser (either an external browser app or a web view built into your application) in order for them to authenticate with the OP.
A complete article presenting how to implement the "Authorization Code Grant" flow securely on a native mobile app is available here : Building an OpenID Connect flow for mobile. It is based on latest IETF OAuth 2.0 Security Best Current Practice.
Please also note that the use of the "Implicit Grant" flow is now highly discouraged.
I think that the Hybrid flow from the OpenID Connect spec is probably the one which you want to use. OpenID Connect Core Spec.
This does rely upon having a configured return URI, but as James says you would use a custom URI scheme to enable the mobile OS to redirect after login to your own app. Your app would then have an access code which it can use to obtain access tokens as needed (assuming that you are using Oauth2 to protect your back-end API services which the mobile app uses).
There is a vulnerability which would allow a malicious app to hijack your URI scheme and grab the tokens, There is a draft spec to overcome that Proof Key for Code Exchange by OAuth Public Clients which is worth considering implementing.
Using an app scheme URL is the correct answer as noted above. I wanted to add additional clarification since some responses above include links to an article that makes incomplete assertions about a compliant SSO design, and make it unnecessarily complicated for a simple SSO use case. I think google's model is secure and so I might model OIDC interactions with a homegrown IDP after how theirs works.
https://medium.com/klaxit-techblog/openid-connect-for-mobile-apps-fcce3ec3472
The design in this article linked above, as depicted in the diagram on the article, does not work for google's oAuth/OIDC implementation on Android. There are two reasons for this:
Google will not vend any client_secret for an oAuth client that is typed "Android"
Suppose I switch to "Web" application which does have a secret: Google will not allow a redirect_uri other than 'http' or 'https' for an oAuth client that is typed "Web"
Instead, google officially recommends letting the typical mobile flow (and you should also be using PKCE) drop an ID Token on the client, who can then exchange it for a session with the App server:
https://developers.google.com/identity/sign-in/android/backend-auth
This is secure because your IDP should be signing the JWT ID Token with a private key so it can be validated by your system's apps/services and used to assert validated (unexpired) identity intended for a particular OIDC client & audience.
** Do not pass ID Token as authorization on every request, but rather exchange it once with your backend for a secure session context as managed by your application.
Check out MITREid project on github:
MITREid Connect
This project contains an OpenID Connect reference implementation in
Java on the Spring platform, including a functioning server library,
deployable server package, client (RP) library, and general utility
libraries. The server can be used as an OpenID Connect Identity
Provider as well as a general-purpose OAuth 2.0 Authorization Server.

Resources