oauth
51 TopicsEvaluating common integrations between Azure AD and APM - Part 1
Identity as a Service providers (IDaaS) are exploding in adoption rate, Azure AD being one that I encounter most frequently. Given that, I am often asked what options are available for integration between Azure AD and BIG-IP APM, including implementation steps. In this 4-part series, I will first summarize and contrast the integration options, including the pros and cons of each, then in each subsequent article we will dive into the requirements and implementation details for each method of integration. Please note that there may be additional integrations and authentication flows, this article series is however only covering 3 in particular. The 3 authentication flows we will discuss in this article series are: Network Policy Server (NPS) Azure MFA extension** SAML federation ROPC Oauth grant authentication flow **This replaces the legacy integration with Azure MFA Server which is no longer supported: https://devcentral.f5.com/s/articles/heres-how-i-did-it-integrating-azure-mfa-with-the-big-ip-19634 Method 1: Azure NPS Extension The method we will be examining in the first article of this series is integration between BIG-IP APM and Azure AD via a Network Policy Server (NPS) extension. This method is used to achieve Azure AD Multi-factor Authentication (MFA) capabilities for user authentication which is most often the primary business requirement for integration. User authentication requests are sent from BIG-IP APM to the NPS server where the NPS extension for Azure MFA will then inform Azure AD to initiate the MFA challenge. The NPS extension for Azure MFA does NOT support any conditional access policies, as the source of every authentication request from Azure AD's perspective will be that of the NPS server itself.By using this method, we can capture the username and password on the APM logon page for seamless password-based Single Sign-On (SSO), plus we get the MFA capabilities of Azure AD, truly the best of both worlds. Architecture and authentication flow: User requests a resource protected by BIG-IP APM and is presented with an APM logon page where they enter their credentials. BIG-IP captures these credentials as session variables and sends them to the predefined RADIUS AAA server, in this case that would be the NPS server with Azure MFA extension. The RADIUS server first validates user credentials, if successful then the 'AzureMFA' extension will notify Azure AD of the incoming user authentication request and initiate MFA challenge. The user is challenged using the chosen MFA method. Azure AD notifies the NPS extension of the MFA challenge result. The NPS extension responds back to the BIG-IP with a RADIUS response based on the outcome of the MFA challenge. If successful, the user is granted access to the protected application, webtop or resource. Pros: BIG-IP APM can capture both the username and password as session variables as part of the logon process, making password-based Single Sign-on (SSO) viable Requires no federation between BIG-IP and Azure AD Cons: Requires external infrastructure dependencies (Redundant NPS infrastructure) Azure AD Conditional access policy support is limited ***This however can be augmented with conditional policies on BIG-IP APM Method 2: SAML federation with Azure AD SAML is a well understood and adopted standard for federation between identity domains. By federating BIG-IP APM with Azure AD as the Identity Provider (IDP) we direct all user authentication requests to Azure AD. This means that all authentication features supported by Azure AD, such as Conditional Access Policies and MFA will work as intended, as the user is interfacing directly with Azure AD during authentication. By its very design, SAML federation limits the SAML Service Provider (SP), which is the role of BIG-IP APM in this case, from receiving the user's password as part of the authentication flow; this means we must use passwordless Single Sign-On (SSO) methods such as Kerberos or SAML for seamless access to applications and resources. Architecture and authentication flow: **Above depicts SP-initiated SAML authentication flow where BIG-IP APM is the Service Provider (SP) and Azure AD is the (IDP) User requests a resource protected by BIG-IP APM. APM responds to the user with a SAML request and directs them to the IDP (Azure AD). The user browser relays the SAML request to Azure AD. It is at this point that the user authenticates DIRECTLY with Azure AD. Once successfully authenticated (including MFA, if applicable), Azure AD responds to the user with a SAML response containing an Assertion and directs the user back to the BIG-IP APM. The user browser relays the SAML response to the BIG-IP and is provided access to the protected application or resource. Pros: Widely deployed and understood + very easy implementation Full support for conditional access policies and authentication functionality in Azure AD Cons: BIG-IP APM will not receive a password as part of the logon process - this means that password-based Single Sign-On (SSO) will not work out of the box ***We will explore options to get around this further in Article #3 Method 3: ROPC Oauth Grant The Resource Owner Password Credentials (ROPC) grant allows an application or intermediary to sign a user in by directly handling their password. Put simply, BIG-IP APM first captures the user credentials with a standard logon page and then validates them with Azure AD directly. This authentication flow may resemble that of traditional authentication flows such as Active Directory domain controllers or RADIUS servers. In most cases, ROPC grant flows are not highly recommended, as the user credentials are provided to the Oauth 2.0 client (BIG-IP) directly instead of to the Authorization Server (Azure AD) which arguably introduces additional risk.By using this method however, we capture the username and password on the APM logon page for password-based Single Sign-On (SSO) without requiring any on-premises infrastructure such as domain controllers or AAA servers to handle authentication. Architecture and authentication flow: User requests a resource protected by BIG-IP APM and is presented with an APM logon page where credentials are input. BIG-IP captures these credentials as session variables and sends them to the predefined Oauth Authorization Server (AS), Azure AD. If the credentials are correct, Azure AD responds to the BIG-IP with an ID token, Access token and optionally a refresh token. If successful, the user is granted access to the protected application or resource. Pros: BIG-IP APM can capture both the username and password as session variables as part of the logon process, making password-based Single Sign-on (SSO) viable Requires no on-premises infrastructure such as Active Directory or RADIUS/NPS for authentication Cons: Not recommended by Microsoft for Security reasons. No direct support for Azure AD MFA No support for Azure AD conditional access policies ***This however can be augmented with conditional policies on BIG-IP APM Summary In the first article of this series we reviewed 3 unique options for integration between BIG-IP APM and Azure AD. We also described the authentication flow as well as the pros and cons for each method. In each subsequent article, we will dive deeper into these three methods, providing detailed implementation instructions, caveats, and requirements as well as some anecdotal wisdom from the field!1.2KViews7likes4CommentsBasic OAuth concept and OAuth with F5 solutions
In my previous article [Overview of API Access Control and implementing API key access control with BIG-IP APM] , I explained the ‘API-Key based Access Control’ method and we could see how a user implements it easily and securely using BIG-IP APM. However, although the ‘API-Key’ method has its advantages, it also has some limitations when we use it in the enterprise-grade API access control implementation. Problems of the API-Key Access Control API Key compromise Although some improved API-Key systems can set an expiration time for API keys, the expiration time for keys has to be set for a longer time such as weeks, months, or a year. This is because the issued key should be configured manually to API clients or API G/W or API endpoints. This manual process requires extra operational overhead, thus it is normally recommended to use a long expiration time for keys. However, a longer expiration time may bring security problems as well. Let’s say the issued key is stolen without recognition by the organization, then what happens? Since the key’s expiration time might be set to months or a year, the attacker who stole the key can access the corporate resources until the key reaches its expiration time, a year in the worst case. 3rd party integration Since the API-key method doesn’t have any pre-defined flow or format of the key, it could be challenging to integrate the enterprise’s API system with 3rd party client applications. For example, if Google, AWS, Dropbox, and Open banking services were to provide all different API access control methods, application developers would need to create all different modules for their applications to integrate each service. This is not a scalable solution to integrating the organization’s APIs with other 3rd party applications. OAuth 2.0 An OAuth 2.0 standard protocol was introduced in 2012 to solve these challenges and was defined in RFC6549. It was designed to implement API access control and is one of the most widely adopted methods for API access control purposes. The common misunderstanding of an OAuth is that it is considered an ‘Authentication protocol’. But it’s not an authentication protocol. While OAuth can provide authentication capability with its well-known extension – ‘OIDC(OpenID Connect)’, OAuth itself can work without OIDC and it primarily solves the access delegation problem. If a user wants to delegate third-party application access to their Gmail profile, OAuth can solve this. Many experts explain an OAuth with an example of a hotel key card. Once the key card is issued to the user, the room doesn’t authenticate the user but rather the valid key card. An OAuth works like a hotel key card, thus it is not an authentication protocol. In an OAuth implementation, a token performs the same role as a ‘key’ of the ‘API-Key method’. One of the biggest technical advantages of OAuth is to provide centralized token management, user authentication, and a privilege consent process. This centralized policy management can help an enterprise to expand their API network and organizations more easily integrate their APIs with external applications. An OAuth is a big topic and we can not cover all the details of it in this short article. However, there are some important terminologies and concepts to understand the overall OAuth flow. OAuth roles OAuth standard introduces 4 different roles in a typical OAuth flow. Resource Owner(RO): RO indicates the person who owns the resources. If a fintech app tries to access a user’s banking account, the user is the resource owner(RO). Resource Server(RS): RS is the place to host protected resources. In the above banking example, the server which hosts the banking API is the resource server and the banking API itself is the resource. OAuth Authorization Server: OAuth AS is the centralized system to manage and issue the access token to OAuth clients. OAuth Client Application: The OAuth client indicates the application which wants to access a resource on behalf of the resource owner. In the banking example, the fintech app is the OAuth client. OAuth grant types OAuth grant types define how an OAuth client can obtain a grant from a resource owner to access their resources on their behalf. An OAuth 2.0 defines 4 different grant types. 1) Authorization Code Grant The application(=client) obtains the ‘authorization code’ first from the authorization server and the client exchange the code for an access token. This allows the access token to be never exposed to the resource owner’s user-agent. 2) Implicit Grant Optimized for in-browser JS clients. Instead of an authorization code, an access token is issued immediately without client authentication. 3) Resource Owner Password Credential Grant Username and password are used instead of an authorization code to obtain an access token. Should only be used for highly trusted clients or when other types are not available. Username and password are only used to get an access token and are not stored. 4) Client Credential Grant The client supplies its own credentials to get an access token. Support OAuth in F5 solutions Since OAuth is a key protocol for the enterprise-grade API implementation, F5 solutions support OAuth widely as well. F5 BIG-IP APM and NGINX Plus support various OAuth roles and grant types. Organizations can build their own secure OAuth framework using F5 solutions. Integrating with partner solutions Since OAuth is a standard protocol, one of its strong benefits is to be supported by different vendor solutions. While F5 provides all types of OAuth roles in our product portfolio, we also provide tight integrations with our partner’s platforms, this includes leading vendors of IDaaS solutions – Microsoft Azure AD, Okta, and Ping. F5 BIG-IP APM has built-in OAuth configuration sets for these vendors already, so customers easily can configure their BIG-IP APM device to work with these vendor’s solutions. That means a customer can deploy Microsoft Azure AD or Okta or Ping Identity as their OAuth Authorization Server, and they can configure the BIG-IP APM and NGINX Plus API Gateway as their OAuth Resource Server. Both BIG-IP APM and NGINX Plus can work with those IDaaS vendor’s solutions to build an enterprise-level of OAuth for an organization. Summary An OAuth is an essential component to implement API access control to protect the enterprise’s API endpoints. However, the OAuth standard includes different roles, grant types, and extensions. Because of its complexity, some organizations may have some difficulty adopting the technology. F5 solution can help an organization adopt OAuth more easily. For example, F5 supports different roles of OAuth with multiple solutions – BIG-IP APM and NGINX Plus API Gateway. A customer can build their own OAuth network using F5 solutions only or they also can configure our solutions to work with industry-leading IDaaS vendors such as Microsoft, Okta, and Ping Identity. With all the flexibility and powerful policy management capabilities of the F5 solution, an organization can implement and operate its OAuth systems more effectively.3.9KViews6likes1CommentRequest and validate OAuth / OIDC tokens with APM
BIG-IP APM is able to request and validate OAuth2.0 and OpenID Connect tokens. It can act as Client, Resource Server and Authorization Server. In this article, I cover the use cases where APM acts as Resource Server (validating the tokens) and Client (requesting the tokens). 1. The tokens : Access Token: this is the Oauth2.0 token (access_token). It is used for Authorization and has to bevalidated by the Resource server. This Resource Server will contact the Authorization server for validation (Out of Path validation - External) Access Token can be either OPAQUE or JWT ID Token: this is the OpenID Token (id_token).It is used by the client onlyin order to know you use the resource owner. For instance, when you see you name and your picture on the top right corner of an app, this comes from the ID_Token. This token is not user/validated by the Resource Server ID Token is JWT only 2. OPAQUE vs JWT tokens : JWT: Decodable Encryptable Can be validated against a preconfigured JWKS in-box or externally OPAQUE: Not decodable (opaque) Proprietary format, might be any length, and must be unique Must be validated in out-of-path HTTP request to the originating provider (the Authorization Server) 3. Token validation : OAuth Scope agentis used to validate anAccess Token either against aninternalJSON web key set (JWKS) if the Access Token isJWTvia an APM provider configuration (Azure AD uses JWT only) orexternallyvia HTTPS if the Access Token isOpaque. JWKS is faster because we don't have an extra HTTP transaction. Oauth Scope agentis used when APM is RS and the request from the client (APM or mobile app) has a authorization bearer header. Either with Opaque (External)or JWT token (Internal). With Opaque token, if the RS needs more information about the user, it needs to request anOpenID Connect UserInfoby presenting theaccess_token to the AS. The opaque scope provides with several information but it depends of the AS. For Google, an OIDC userInfo is needed to get the First and Last names. 4. Token Request : Oauth Client agentis used to request theAccess token and id_tokenwhen APM is deployed asOauth Client. To do so, 2 grant types are available (Code and password) WithAuthorization code grant, the Client agentexchangesan Authorization code for an access_token code + id_token (if OIDC used). When the Oauth Client gets the access_token (and id_token), theOauth scope agent validatesthem.3.6KViews5likes3Commentsoauth server generated jwt token problem
Hi all, We have a customer try to do oauth with a dovecot server, they have the following problems using the f5 as a oauth server: The "typ" jwt header is missing, this should be set to "JWT". F5 set the JWT token nbf (not valid before) to some minutes in the past, this breaks dovecot auth. Customer want to use the following oauth features, are these supported? https://openid.net/specs/openid-connect-frontchannel-1_0.html https://openid.net/specs/openid-connect-backchannel-1_0.html Do you know how the above could be customized in f5 to set to values the dovecot would accept? Thank you for any hint. Peter1.2KViews3likes5CommentsHow to customise Azure AD OIDC user ID token for APM integration
Overview A Service Provider (SP) such as the F5 APM can integrate with Azure AD (AAD) as an Identity Provider (IDP) for federated authentication using OpenID Connect (OIDC). Through this process, a user visiting APM (e.g., https://myapps.acme.corp ) is immediately redirected to AAD for authentication, once authenticated, AAD returns a code to the APM via the user browser. The APM grabs that code, adds additional information, sends them together to AAD, and finally receives an ‘access_token’ and ‘id_token’. This article takes a special focus around what is included in ‘id_token’ that AAD returns, as it is used by APM, and broadly speaking by any relying party SP, for the purpose of session creation. ‘id_token’ (part of OIDC) contains user identity information and is highly customizable. The customization of ‘id_token’ is completely done within AAD. The concept is simple, but not until it is well understood in my experience; especially with the AAD having a bunch of configuration items in the mix, such as ‘Token configuration’, ‘API permissions’ and ‘Expose an API’. This article hopes to cut all the clutter and un-muddy the water so to speak, around this topic. OIDC As a refresher, the difference between oAuth and OIDC lies in that OIDC is an identity piece laying on top of oAuth. Specifically, with oAuth, ‘access_token’ alone is returned, whereas with OIDC, ‘id_token’ is returned in addition to ‘access_token’. Scope To tell AAD we are using OIDC, the APM needs to include a scope named ‘openid’ in its outbound request to the AAD. This is achieved via the following setting. Within AAD, your application must include ‘openid’, as shown below. By default, the ‘openid’ scope comes with a list of claims that will be included in ‘id_token’. However, for certain claims to be available, additional scopes are also required. For example, if you want to have ‘preferred_username’and ‘name’ claims included, ‘profile’ scope needs to be added as well, as is depicted in the following. AAD also lets you add optional claims via ‘Token configuration’ as shown below. If these optional claims need additional scopes, AAD will add those scopes in for you under ‘API permissions’. On the APM ‘OAuth Client’ configuration, make sure to add those scopes in as highlighted below. Once the APM matches scope with AAD, AAD will include all claims in ‘id_token’ it sends back to the APM. The APM is then able to consume those claims based on the use case (e.g., create a session using email) I am hoping that this short article sheds some light around your integration work around this space.1.5KViews2likes0CommentsJSON Web Token (JWT) Parser
Problem this snippet solves: This feature is now native in v13.1 and it is strongly recommended you implement the native solution instead. This code is left only as an example for future use cases, it should not be used for JWT handling because there is no signature validation. This code parses a JWT (JSON Web Token) received by a Big-IP acting as an OAuth client and creates session variables for the JSON parameters in the header and payload. Example use cases might include Azure AD B2C or Azure AD Enterprise integration. This iRule does not perform signature validation. Code from the "Parse and Set Session Variables" section down could be easily harvested for other JSON parsing use cases that do not need the JWT decoding. How to use this snippet: Attach this iRule to the virtual server receiving the JWT that is configured for OAuth. Inside the VPE after the OAuth Client agent add an iRule agent with id jwt-parse. This iRule will set several variables including: session.oauth.jwt.last.header session.oauth.jwt.last.payload session.oauth.jwt.last.signature In addition it will create a session variable for each parameter in the header and payload in the following syntax. session.oauth.jwt.header.last.* session.oauth.jwt.payload.last.* You can then call these session variables elsewhere. Code : when ACCESS_POLICY_AGENT_EVENT { if { [ACCESS::policy agent_id] eq "jwt-parse" } { #log local0. "JWT-Parse: Started" #Get the JWT set jwt [ACCESS::session data get -secure session.oauth.client.last.id_token] #log local0. "JWT-Parse: JWT Received - jwt is $jwt" #Separate the header, payload, and signature set jwt_header [getfield $jwt "." 1] ACCESS::session data set session.oauth.jwt.last.header $jwt_header #log local0. "JWT-Parse: Header extracted - jwt_header and session.oauth.jwt.last.header are $jwt_header" set jwt_payload [getfield $jwt "." 2] ACCESS::session data set session.oauth.jwt.last.payload $jwt_payload #log local0. "JWT-Parse: Payload extracted - jwt_payload and session.oauth.jwt.last.payload are $jwt_payload" set jwt_signature [getfield $jwt "." 3] ACCESS::session data set session.oauth.jwt.last.signature $jwt_signature #log local0. "JWT-Parse: Signature extracted - jwt_signature and session.oauth.jwt.last.signature are $jwt_signature" #Base 64 decode the header and payload #Fix encoding issues in header set jwt_header_modified $jwt_header set tail [string length $jwt_header_modified] if {$tail % 4 == 2} { append jwt_header_modified {==} } elseif {$tail % 4 == 3} { append jwt_header_modified {=} } #log local0. "JWT-Parse: Header encoding fixes complete - jwt_header_modified is $jwt_header_modified" #Fix encoding issues in payload set jwt_payload_modified $jwt_payload set tail [string length $jwt_payload_modified] if {$tail % 4 == 2} { append jwt_payload_modified {==} } elseif {$tail % 4 == 3} { append jwt_payload_modified {=} } #log local0. "JWT-Parse: Payload encoding fixes complete - jwt_payload_modified is $jwt_payload_modified" #Base64 decode set jwt_header_modified [b64decode $jwt_header_modified] #log local0. "JWT-Parse: Header Base 64 decoded - jwt_header_modified is $jwt_header_modified" set jwt_payload_modified [b64decode $jwt_payload_modified] #log local0. "JWT-Parse: Payload Base 64 decoded - jwt_payload_modified is $jwt_payload_modified" #Parse and Set Session Variables #Remove JSON characters set jwt_header_modified [string map {\{ {} \} {} \[ {} \] {} \" {}} $jwt_header_modified] #log local0. "JWT-Parse: Header JSON Characters removed - jwt_header_modified is $jwt_header_modified" set jwt_payload_modified [string map {\{ {} \} {} \[ {} \] {} \" {}} $jwt_payload_modified] #log local0. "JWT-Parse: Payload JSON Characters removed - jwt_payload_modified is $jwt_payload_modified" #Split into field/value pairs set jwt_header_modified [split $jwt_header_modified ,] #log local0. "JWT-Parse: Header Fields split - jwt_header_modified is $jwt_header_modified" set jwt_payload_modified [split $jwt_payload_modified ,] #log local0. "JWT-Parse: Payload Fields split - jwt_payload_modified is $jwt_payload_modified" #Set APM session variables for each header parameter foreach parameter $jwt_header_modified { set variable_name [getfield $parameter ":" 1] set variable_value [getfield $parameter ":" 2] ACCESS::session data set session.oauth.jwt.header.last.$variable_name $variable_value #log local0. "JWT-Parse: Header session variable set - session.oauth.jwt.header.last.$variable_name is $variable_value" } #Set APM session variables for each payload parameter foreach parameter $jwt_payload_modified { set variable_name [getfield $parameter ":" 1] set variable_value [getfield $parameter ":" 2] ACCESS::session data set session.oauth.jwt.payload.last.$variable_name $variable_value #log local0. "JWT-Parse: Payload session variable set - session.oauth.jwt.payload.last.$variable_name is $variable_value" } } } Tested this on version: 13.03.5KViews2likes14CommentsUsing Custom OAuth Client iRules
How do I use iRules with OAuth Server Profile? What are the valid events that will fire to trigger execution. Products docs just say "attach and iRule if you want customization". https://support.f5.com/kb/en-us/products/big-ip_apm/manuals/product/apm-authentication-sso-13-1-0/37.html Under heading "Configuring OAuth servers for APM as a client"611Views2likes2CommentsOAuth SSO
Hi All, we'd like to secure the access to a backend portal with OAuth (F5 Authorization Server and F5 Client/Ressource Server). We aleady configured 2 Virtual Servers and 2 Access Profiles access profile 1 for the backend application (OAuth Client and Scope Agents) access profile 2 for the OAuth AS (Logon Page, LDAP Auth and OAuth AS Agent) The login and the OAuth (OIDC) works with the backend via id_token. Idea was to ask the user ONCE for his LDAP Credentials and then authorize the user in subsequent authorization requests from client applications WITHOUT asking for entering his credentials again. What we see in the session logs is, that the authorization server session always ends with "session deleted (oauth_finished)" once the authorization request has successfully ended, hence the users LDAP information is destroyed together with the "session deleted" Is it possible to get some kind of SSO so that the users credentials is stored in the client for subsequent authorization requests and that the logon page can make use those credentials without prompting the user to login manually again? Thanks Steffen474Views2likes3CommentsAPM JWT Multiple Providers NOT WORKING
Dear F5 community, Using F5 APM 16.1.3 (as an oauth resource server) I am trying to implement a per-request policy that will verify the signature of JWT tokens sent by the client. These JWT tokens can be issued from two differents issuer (Azure AD or STS). I am able to verify JWT tokens for each provider seperatly using a dedicated "JWT provider" with only one Provider attached. When using 2 providers as follow I got following error message: WWW-Authenticate:Bearer error="invalid_token",error_description="Issuer Mismatch : Claim issuer= https://sts.windows.net/ Provider issuer=https://login.microsoftonline.com/v2.0" Based on F5 doc below, the built-in object supports having multiple JWT providers https://clouddocs.f5.com/cli/tmsh-reference/v15/modules/apm/apm_oauth_jwt-provider-list.html Configuration is pretty simple: - 1 Access Policy with "Allow" all ending - 1 Per-Request Policy with "OAuth Scope" set to "Internal" with the "jwt-allowed-providers-list" I guess It is most likely a bug. Anyone was able to make it work with multiple JWT providers ? I can workaround this by parsing the JWT payload, then determining the issuer and based on the issuer make two branches in the VPE: - first branch with the "oauth scope A" that will validate the token using JWT-Provider-A - second branch with the "oauth scope B" that will validate the token using JWT-Provider-B Thanks2.1KViews1like5CommentsOAuth APM as Authorisation server
Hi Got a question I can't seem to get answered. I have a OAuth authorisation server setup. I have applied the oauth profile and I have a per session policy that use oauth authroization to assign claims and scopes. The claims are setup based upon session variables. So the JWT created have 5 in life for access token and 60 min life for refresh token. So at 5min +1 my client/resource server will access the auth server for a new access token using the refresh token. I see this on the APM logs on the auth server and the client/resource server. BUT on the auth server, there is no session alive ! so which auth server session variables is it using. Does it just use the values that were assigned when the original request was made if thats the case. How can I . if possible update the information for each request ? Is it possible779Views1like4Comments