According to the following documentation, I understand that OAuth2 is an Authorization protocol:
https://learn.microsoft.com/en-us/azure/active-directory/develop/authentication-vs-authorization#authorization
Considering that OAuth 2.0 authorization code flow is an authorization protocol, why in many application types and scenarios (including the code example below), authorization code flow is used to authenticate a user (using its password) then provides an access token to the application.
https://github.com/Azure-Samples/active-directory-b2c-dotnet-desktop
The confusion I have is that most OAuth2 flows use a user's password to identify her/him then provide an access token to the application.
As another example, I learned that PowerApps portal uses OAuth2 PKCE to identify users through B2C. It seems that PowerApps uses OAuth2 PKCE to authenticate users, not authenticate them. I was expecting OpenID Connect should be used for such a scenario.
Is OAuth2 Authorization Code flow an authentication or authentication protocol or both of them?
Yes, OAuth2 is an authorization protocol.
It did not provide a consistent way to authenticate and the social providers e.g. Facebook, Twitter etc. then rolled their own authentication models to provide this service.
As a result, OpenID Connect was developed. This provides a standard way to authenticate and is built on top of OAuth2.
(There was an earlier standard called OpenID for authentication but that is not often used now).
As per this:
"OpenID Connect (OIDC) is an authentication protocol built on OAuth 2.0 that you can use to securely sign in a user to an application. When you use the Microsoft identity platform's implementation of OpenID Connect, you can add sign-in and API access to your apps.
OpenID Connect extends the OAuth 2.0 authorization protocol for use as an authentication protocol, so that you can do single sign-on using OAuth.
OpenID Connect introduces the concept of an ID token, which is a security token that allows the client to verify the identity of the user.
The ID token also gets basic profile information about the user. It also introduces the UserInfo endpoint, an API that returns information about the user".
PKCE is for "OAuth 2.0 public clients utilizing the Authorization Code Grant.
These are susceptible to authorization code interception attacks.
This specification describes the attack as well as a technique to mitigate against the threat through the use of Proof Key for Code Exchange (PKCE, pronounced "pixy")".
So after authenticating with OIDC, PKCE makes the Authorization Code Grant flow more secure.
Related
My application is mainly based on spring boot micro services. Currently it uses OAuth with password grant_type which is deprecated in the latest spring security authorization server release. For receiving JWT token, it stores client id and client secret in React JS frontend which is not secure and not recommended. Users need to register to access certain resources and application maintains login credentials in mysql DB
I am trying to upgrade spring security and want 'account service' to act as authorization server to issue JWT tokens.
Am I correct in my understanding that I need to use authorization_code grand type with PKCE?
If I use PKCE then I do not need users to provide passwords while registering, is that correct? Storing only username/email should suffice because users just need to pass client ID and code_challenge to get authorization code?
Am I correct in my understanding that I need to use authorization_code grand type with PKCE?
The newest version of Spring Security mode introduces a new project for the Authorization server in the scope of Spring Security:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-authorization-server</artifactId>
<version>0.3.1</version>
</dependency>
The authorization server from spring implements OAuth2.1 where as you mentioned, both PASSWORD and IMPLICIT grant types were removed comparing it to OAuth 2.0.
Gran types supported in OAuth 2.1: 1
Authorization code + PKCE
client credentials
device grant type
OAuth 2.1 provide authorization code + PKCE grant type but it's a little bit different from the previous.
"The key difference between the PKCE flow and the standard
Authorization Code flow is users aren’t required to provide a
client_secret. (...) In place of the client_secret, the client app
creates a unique string value, code_verifier, which it hashes and
encodes as a code_challenge. When the client app initiates the first
part of the Authorization Code flow, it sends a hashed
code_challenge."
2
That type of grant type is recommended for SPA application so if you want to use the newest version of spring security you need to use it, because e.g. client credentials are reserved for machine-to-machine communication when one service needs to communicate with another service without of user's knowledge.
If I use PKCE then I do not need users to provide passwords while registering, is that correct?
Users need to authenticate themselves and that's a part of this grant-type flow.
Storing only username/email should suffice because users just need to pass client ID and code_challenge to get an authorization code?
ClientID and generated code_challenge (should be generated by the client) is something that identifies the client not the resource owner, so user while authorized shouldn't provide this type of info.
Authorizing client request
With OAuth2, clients (your React app) must authorize requests to protected resources, that is provide an access-token as Bearer Authorization header.
When acting on behalf of a user, clients should use authorization-code flow (with PKCE) to fetch such an access-token from authorization-server.
Also, use an OAuth2 client library in your React app. It will help you to:
redirect users to authorization-server
handle redirection back from authorisation-server with authorization code
exchange authorization code for tokens (access, refresh and ID)
Some libs even handle:
access token silent refresh before it expires
request Authorization to configured routes (add access token as header)
automatically trigger login when a user tries to access protected parts of the app.
I have not enough experience with React to recommend a specific lib, but you can search with "OpenID", "OIDC" or even "OAuth2" keywords
Configuring spring REST APIs
REST APIs secured with OAuth2 are "resource-servers". You can use spring-boot-starter-oauth2-resource-server directly as done in the first of those tutorials, but it is quite some Java conf.
Instead, you can use one of the spring-boot starters from the same repo. They are thin wrappers around spring-boot-starter-oauth2-resource-server with sensible defaults and most security conf from properties:
<dependency>
<groupId>com.c4-soft.springaddons</groupId>
<!-- replace "webmvc" with "webflux" if your app is a servlet -->
<!-- replace "jwt" with "introspecting" to use token introspection instead of JWT decoding -->
<artifactId>spring-addons-webmvc-jwt-resource-server</artifactId>
<!-- this version is to be used with spring-boot 3.0.0-RC2, use 5.x for spring-boot 2.6.x or before -->
<version>6.0.5</version>
</dependency>
#EnableMethodSecurity
public static class WebSecurityConfig { }
com.c4-soft.springaddons.security.issuers[0].location=https://localhost:8443/realms/master
com.c4-soft.springaddons.security.issuers[0].authorities.claims=realm_access.roles,ressource_access.some-client.roles
com.c4-soft.springaddons.security.cors[0].path=/some-api
Configuring the gateway
Basically, nothing to do in regard to authentication and OAuth2: inbound requests to secured resources should have an authorization header already and resource-servers will respond with 401 if authentication is missing or invalid (expired, wrong issuer, ...) or 403 if access is denied (valid identity but not allowed to access that resource)
authorization-server
Any OAuth2 authorization-server would do, but you might choose an OIDC implementation.
Authorization-server will handle users registration, login and logout. It will issue access, refresh and ID tokens, using mainly:
authorization-code flow for clients acting on behalf of a user
client-credential flow for trusted programmatic client acting in their own name (not on behalf of a user)
refresh-token: if offline_access scope is requested when authenticating (with any flow), a refresh-token is returned in addition to access-token and can be used to silently get a new access-token when current expires (or just before it does)
You can use Spring authorization-server framework to build your own authorization-server, but could also prefer to pick one "off the shelf": there are plenty out there with a lot of features implemented
connect to LDAP and "social" identity providers (Google, Facebook, Github, etc.)
enhance security with multi-factor authentication
provide with admin UI for stuff like user roles or tokens content
...
And this either on premise (Keycloak is a quite popular sample) or SaaS (like Auth0 and many others: almost any cloud provider has its own solution).
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.
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.
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.
Anybody know the difference between Federated authentication and Delegated authentication in salesforce? Can you explain the flow of request in these two methods?
The main difference is the use of Security Assertion Markup Language (SAML) on Federated Authentication.
Delegated Authentication Use delegated authentication if you have mobile users in your organization, or if you want to enable
single-sign on for partner portals or Customer Portals. You must
request that this feature be enabled by salesforce.com. This recipe
explains delegated authentication in more detail.
Federated Authentication using SAML Federated authentication uses SAML, an industry standard for secure integrations. Investing in SAML
with Salesforce.com can be leveraged with other products or services.
If you use SAML, you don't have to expose an internal server to the
Internet: the secure integration is done using the browser. In
addition, Salesforce.com never handles any passwords used by your
organization. For more information, see “Configuring SAML Settings for
Single Sign-On” in the Salesforce.com online help.
Difference
Delegated authentication has a few drawbacks with respect to federated authentication. First, delegated authentication is inherently **less secure than federated authentication**. Even if encrypted, delegated authentication still sends the username and password (possibly even your network password) over the internet to Force.com. Some companies have policies that preclude a third party for handling their network passwords. Second, delegated authentication **requires much more work for the company implementing it**. The Web services endpoint configured for the org must be developed, hosted, exposed on the Internet, and integrated with the company's identity store.
More detailed flow and code example on delegated
More detailed flow on SSO width SAML