Skip navigation
All People > Sascha Preibisch > Sascha Preibisch's Blog
1 2 3 Previous Next

Sascha Preibisch's Blog

41 posts

Hello everyone!

 

Please be aware that the IETF's OAuth working group is now recommending not to use any implicit flow anymore. This includes the response_type=token and any other that issues an access_token as part of the response.

 

Torsten Lodderstedt, member of the working group, has written a good article about this, please have a look:

Why you should stop using the OAuth implicit grant!

 

Please let me know if you have any questions via email of comments.

Hello everybody!

In the week of 22. October 2018 I attended IIW 27 (Internet Identity Workshop) in Mountain View/ California. IIW is the place to go when it comes to identity related topics such as OAuth, OpenID Connect and many others. At this IIW a few topics came up that I have thought about in the past, too. For example, "how to prevent data leakages where access_token are lost?".

Interestingly, the week before I went, I had a meeting with a few colleagues of mine. In that meeting I asked the following:

 

What, if the client issues the access_token itself?

 

This is my high level thought:

If a client is known by a trusted authorization server, it should be good enough for any resource server to accept a token that was issued by the client, if that token is based on a grant that was given to the client by the trusted authorization server! Something like this:

 

Dear Resource Server, I, the Authorization Server, vouch for the authenticity of the client and you may accept its request!

 

Pre-Requisites

To make this happen a few pre-requisites need to be satisfied:

  1. the client must be able to validate and create JWT
  2. the client is registered at the authorization server
  3. the client has registered potential SCOPEs it may use at the authorization server
  4. the client has registered a public cert or a jwks_uri at the authorization server
  5. the client has registered its redirect_uri(s) at the authorization server

 

How does the message flow look like?

Here are the three main steps in a default message flow, assuming the client registration has been done.
(for more or less all details, please see this sequence diagram):

  1. A client requests an authorization grant, similar to requesting an authorization code today. But instead of receiving a plain text string as 'code' it receives a 'grant'. This 'grant' is a JWT, signed by the authorization server.
  2. The client generates an access_token itself, which is also a JWT. This JWT includes the grant and other details. The JWT is signed by the clients private key and includes the public cert in the JWT header 'x5c'.
  3. When the resource server receives the access_token it decodes it and validates the 'grant' first. Once that is done it validates the JWT access_token. If it is valid, it accepts the request.

 

Main advantages of this approach

This list explains why I think this is an idea worth discussing. Terms such as 'grantId' are explained further down in the text:

  1. The authorization server does not need to support a token endpoint and with that no grant_types. This massively simplifies the overall system
  2. The client can proof to the resource server that it 'owns' the given grant
  3. The 'proof-of-possession' check does not require mutual TLS connections. This removes any complications where, for example, loadbalancers terminate SSL connections. I know, some of you may say: 'The token could still be given by a client that stole it'. I know, but, at least for now, I think this is good enough
  4. The 'grant' and the 'access_token' have 'issued at' timestamps. It is entirely up to the resource server to accept token by their calculated age (without exceeding 'max_age')
  5. Resource servers may accept requests of completely unknown clients. Self-signed certificates can be used by the client for signing their JWT-based access_token
  6. The 'grantId' represents an active 'consent'. The AS /introspection endpoint can be used to check if a 'consent' has been revoked. Since this 'grantId' has no other purpose it is a 'low-risk-item'
  7. No access_token are persisted at any authorization server. Data leaks are not possible (at least not in a large scale)

 

What is the main difference at the authorization request?

For once, the client uses response_type=grant, which is completely new. In addition, the request may include a kid (KeyID). This is used to tell the authorization server which public certificate this client will use during this session. The parameter target contains the target endpoint (resource) the client wants to consume. For the moment, this may be omitted or specified for particular use cases.

 

The other difference is the response. It contains a grant. It, more or less, contains, what an oauth introspection endpoint would return. One of the very important values inside of it is the cnf.x5t#S256 value. It can later be used as proof-of-possession at the resource server.

 

Another new value is the grantId. Whenever a resource owner grants a client access to resources, this is created at the authorization server. If a resource owner would revoke the grant for this client, that value would be invalidated. This decouples grant (or consent) from any access_token or refresh_token and has no value of any sort otherwise. Resource servers may provide this value to the authorization servers introspection endpoint to verify that this 'grant' is still active.

 

Content of the 'grant':

The grant should contain all details that are required by a resource server to validate a clients request as 'valid'. Therefore it should contain the claims listed below:

  • iss: the issuing oauth server/ openid connect provider
  • scope: the granted SCOPE for this session
  • aud: the client_id that has requested this grant
  • iat: issued at, in seconds (10 digits)
  • nbf: not-before timestamp, in seconds (10 digits)
  • grantId: Whenever a resource_owner grants a client for a given SCOPE and client_id the authorization server generates an identifier to refer to that event
  • max_age: the maximum age for this grant. This grant must not be accepted if it has passed its lifetime. In general, the resource server may decide based on 'iat' if it wants to accept this grant. However, this value cannot be ignored. The value is calculated using: now.seconds - iat
  • aud_alg: The algorithm the requesting client has to use for the JWT-based access_token creation. This is known since the client has registered its supported algorithm. Without this the resource server would have to somehow know beforehand which algorithm to use. This is impractical and in some cases impossible
  • cnf: A value containing a SHA-256 thumbprint of the clients public certificate. It appears as this: '{..."cnf": {"x5t#S256":"aSha256Value"}}'
  • target: the target resource. This may be an absolute URI or just the server location (i.e.: https://example.com/*) This depends on the use case. If this value is empty no assumptions are made.
  • nonce: a random value to mitigate replay attacks

 

NOTE: The grant may also include a 'sub' (subject) or an id_token of the granting user. This depends on the use case and/or requested SCOPEs! 

Other changes at the authorization server include an updated /introspection endpoint to support validations of client-side issued access_token. The authorization server also has to create and issue the 'grantId'.

 

What is the main difference for clients when sending a request to a resource server?

After receiving the 'grant', the client has to create a JWT-based access_token. This 'grant' has to be part of the access_tokens payload. When signing the JWT, the client has to use a private key 'that matches' the registered public key or the one identified via 'kid'. The goal is to provide a way for the client to proof to the resource server that it is the correct entity who received the grant. It enables the resource server also to accept a client's public key which would not be accepted otherwise (i.e.: self-signed).

Clients may use the same grant multiple times. As long as the required SCOPE does not change and the 'max_age' of the grant has not passed 'it is good to go'. Nevertheless, the resource server should check regularly if the given grant (consent) is still active!

 

Content of the 'access_token':

  • grant: the grant given by the authorization server
  • iat: issued at, in seconds (10 digits)
  • max_age: the maximum age for this access_token. This access_token must not be accepted if it has passed its lifetime. In general, the resource server may decide based on 'iat' if it wants to accept this access_token. However, this value cannot be ignored. The value is calculated using: now.seconds - iat
  • nonce: a random value to mitigate replay attacks

 

What is the main difference for resource servers?

If the resource server leverages the authorization servers /introspection endpoint, more or less nothing changes. That endpoint will return details that can be used for validation purposes. But, if the resource server wants to validate the access_token locally, it has to run JWT-based validations:

  1. decode the JWT-based access_token
  2. extract and decode 'grant'
  3. validate the 'grant' (iss, nbf, max_age, signature)
  4. extract 'grant.scope' and check if it meets local requirements
  5. extract 'grant.target' and check if it is meant for this resource. To be ignored if empty

 

If the first validation was successful the resource owner can now check if the provided grant was actually made for this client:

  1. compare: access_token.jwt-header.alg == grant.aud_alg
  2. compare: base64url(S256(access_token.jwt-header.x5c)) == grant.cnf.x5t#S256
  3. validate the access_token (max_age, signature)

 

What are known threats that may be mitigated using this solution?

This list gives just an indication of what is preventable:

  1. code interception attack: this is mitigated by providing a proof-of-possession check. Unless a client has 'lost' his private key (or potentially a shared secret) this should not be possible. See RFC 7636 for more details on how its being prevented today
  2. oauth mix up attack: this is mitigated by not requiring a seconds api call (/token endpoint). See OAuth 2.0 Mix-Up Mitigation for more details
  3. access_token data leaks: no token are stored at a central location and therefore they cannot be 'lost' or 'stolen'

 

What about existing grant_types, can they be supported?

Overall, my gut tells me that not all existing grant_types are still needed. But this has to be evaluated a little later.

 

How could this be started?

I think that most OpenID Connect providers already have a lot of required implementations in place. For example, clients can already register with jwks_uri's. In addition, adding a new response_type should be simpler than modifying existing ones. Overall response_type=grant should be similar to response_type=code, at least up to the point where the code (grant) gets issued.

Persisting the introduced grantId should be small effort, at least for any implementation that already manages given 'consent' decisions without leveraging issued token.

For resource servers, they need to support JWT which they may already do today. In addition, it may be useful to change the type of token definition. If resource servers support bearer token, jwt-based access_token and now client-issued-jwt-access_token, there should be an indicator. For example, something like:
Authorization: Grant {token} instead of Authorization: Bearer {token}

 

Links

I took the name 'cnf.x5t#S256' from here, to not introduce yet another term for the same thing!

 

Feedback

I hope this post is at least good enough to start a discussion on this topic. Please leave a comment or send me an email at: sascha.preibisch@ca.com. I will also place this post at my private homepage (https://www.oauth.blog) in the next few days to have it available at any given time.

Hello everybody!

 

I am very happy to share with you that I have completed my first book on API development:

 

Title: API Development: A Practical Guide for Business Implementation Success

ISBN978-1484241394

 

The book discusses different topics around API development and is based on real-world experiences.

Topics such as OAuth, OpenID Connect, who are the stakeholders, do's and don'ts are covered.

 

It will be published by Apress and is available very soon! Amazon already accepts pre-orders!

 

If you have any questions leave a comment or send me an email: sascha.preibisch@ca.com

 

Thanks!

Sascha Preibisch

Azure AD Integration

Posted by Sascha Preibisch Employee Sep 12, 2018

Hello everybody!

 

This is the first part of a series that shows how to integrate Azure AD (azure) with CA API Gateway (gateway). At the end you will have all details that are required to leverage Azure AD with OTK (CA API Management OAuth Toolkit). This has been requested often, and, since we like our customers, we have listened!

 

All content is available in GitHub. You only need a gateway license and Docker and that is practically everything.

 

Part 01 - Small steps first

This first part is all about configuring a first application in Azure AD that can be used to authenticate users in the gateway. The image below indicates what will be included:

 

 

This is what you get in this part:

  • Azure AD configured for one application
  • A simple website taking the user through an authorization flow with Azure AD (response_type=id_token)
  • A simple website displaying the username provided by Azure AD

 

All instructions are in GitHub. Please follow the instructions for the tutorial found here Azure AD Tutorial!

 

Completed parts

At this time (12. September 2018) part one has been provided. This blog post will be extended and more parts will be added.

 

As always, please let me know what you liked and what not!

Hi everybody!

 

First of all, thanks to everybody who participated in the OTK + IFTTT webcast of last week. I hope it was useful!

 

In the meantime I have updated the artifacts and placed them in GitHub so that anybody can try the tutorial themselves. It contains the following:

  • a docker-compose file. Using that will launch a CA API Gateway 9.3 including OTK and the IFTTT APIs of the webcast. Note: OTK is ready to go, no need for any configurations!
  • a SOAPUI project which can be used to verify that the CA API Gateway is up and running. It includes tests for the IFTTT APIs but also a test suite for OTK. Feel free to leverage that in other OTK related projects
  • Instructions for configurations

 

As an existing customer it should only take you a few minutes to get the system up and running, otherwise you will have to request a CA API Gateway license first. How to get it is described in the tutorial.

 

Content of the tutorial

The tutorial is built around the virtual bank 'CA OTK Tutorial Bank' that wants to engage more with customers. For that reason it has created an application called 'Account Monitor'. 'Account Monitor' allows customers to get notified if a selected account has changed with a given amount. One feature includes the ability for customers to receive an email notification. The other one enhances the usability of the online banking web site. If the account has changed and the user logs into his online banking system, he finds himself directly at the referenced account, no need to choose it first.

 

The setup looks something like this (taken from the presentation):

 

Something to keep in mind

It is very easy to get started with OTK and IFTTT. However, it is important to remember how IFTTT works. IFTTT is a platform that allows anyone to build an applications. Endusers are then able to combine them in many different means. IFTTT itself is an oauth client of any application. With that, IFTTT is always part of the communication flow between combined applications. For that reason, no sensitive data should be exchanged or exposed via an application.

 

In the tutorial, the 'Account Monitor' notifies endusers about the account, the amount, and a transaction id. In a real life scenario 'Account Monitor' should just notify the user that a change has happened, with minimum details included. What to expose is very much a per-use case question. It architecture of IFTTT just needs to be considered.

 

Download

The tutorial can be found in GitHub,  right here! Clone or download the project and switch into the directory ca-apim-otk-and-ifttt. The easiest way to use it, is to have the README.md file of that directory open in a browser while setting up the system. 

 

The presentation and the replay are located here: [RECAP] OAuth integration with IFTTT - June 19, 2018 

 

As always, any feedback is welcome!

Hi everybody!

 

I am excited to share with you that we have organized a webcast showing how to integrate OTK and IFTTT. We have been asked by customers to share the general approach on how to do this and we have listened!

 

The link below takes you to a page with more details:

[COMMUNITY WEBCAST] - OAuth integration with IFTTT - June 19, 2018 @ 12 p.m. ET 

 

If you have got a specific question or request please leave a comment or send me an email at: sascha.preibisch@ca.com.

 

Have a good day and I hope you'll join!

 

Update, 19. June 2018

 

Hi all!

 

The replay, the presentation and the Q&A answers of the webcast are now available here:

OTK + IFTTT

 

The sources (policy, soapui project) will be available in this GitHub - CA APIM/Tutorials repository Wednesday or Thursday.

 

Thank you for joining the today's session, I hope it was useful!

 

If you have got other ideas for this type of event, please let us know!

Hi everybody!

 

Today, after a 10 day vacation at a sunny place, I got back to work and got confronted with basic questions on oauth. Very basic. Questions like these:

  • why am I not getting an authorization code when I use 'response_type=token'?
  • why is 'SCOPE=openid' ignored when I am using 'grant_type=password'?

If you are asking the same questions, which is nothing to be a shamed about, this blog post is for you.

 

OAuth request scenarios

To get started we have listed response_types and grant_types at our official CA documentation. Take a look to get an idea when to use what and how to create a request: OAuth request scenarios

 

OAuth - OpenID Connect - tips

Here are a few tips:

  1. OpenID Connect requires a flow that starts with a response_type. This means a request is send to the /authorize endpoint. You know that you are not using OpenID Connect if the initial client request includes one of these values:
    1. request send to the /token endpoint (wrong endpoint)
    2. ...&grant_type=...& (initial request NEVER with grant_type)
    3. ...&response_type=token&... (unsupported response_type for OpenID Connect. Find valid response_types here: OpenID Connect response_types)
  2. OpenID Connect requests MUST include 'SCOPE=openid'. Some of you may say 'I have seen implementations that do not require that'. Yes, but in my personal view that is wrong. The OpenID Connect specification states this:
    1. OpenID Connect AuthRequest: ... OpenID Connect requests MUST contain the openid scope value. If the openid scope value is not present, the behavior is entirely unspecified ... For me the second sentence is a loop hole and therefore a bad excuse to support OIDC without requiring SCOPE=openid
  3. OAuth by itself will usually NOT provide information about the current user! If you want your client to display a message such as 'Hello Sascha' you need to leverage OpenID Connect

 

OAuth - OpenID Connect - rule of thumb

To make it simpler to get an idea what you need to support/ leverage here is a short list with 'Daumenregeln':

  1. you are exposing an API that does not require an authenticated user: grant_type=client_credentials
  2. you are maintaining the users credentials (your employee with an enterprise account): grant_type=password
  3. you want to leverage social login or you do not want the client to provide a login screen: response_type=code
  4. you want your client to know who the current user is: response_type=code AND scope=openid email profile

You have to answer other questions (like client_type=public or confidential?) but this is a starting point.

 

OpenID Connect & grant_type=password

Often I get asked how to use OpenID Connect with grant_type=password. By now you should have realized that this is an unsupported combination! However, in most cases the actual requirement is not to combine those two but to also issue an id_token. That, my dear readers, you have to implement yourself! You will not find this as a feature of any certified OpenID Connect provider. To customize OTK you can get help via services or support or a blog post (if there is a high demand).

In any case, please ask yourself: why do I need this? You should not have this requirement! You should be able to use access_token and refresh_token in a combination so that your users are not asked for credentials over and over again.

Please remember, if this is about getting user details, you can include any user information when issuing token since you are in control of the user details anyways!

 

I hope this short post helps you to get a little head start when looking into these topics. As always, please leave a comment if it was helpful or if you need more help.

Hi everybody!

 

Some of you may have read my blog post on OAuth vs. LDAP. That topic seems to be interesting for quite some time now. I think it may be a topic people talk about because it may not be too simple to see the difference of those two. Just recently I was told that it would be good to get a comparison between OAuth, LDAP and OpenID Connect.

 

This post is providing that comparison.

 

LDAP (Lightweight Directory Access Protocol)

An LDAP server (full disclosure: I am not an expert on LDAP) is a directory that contains details, attributes about users. It may contain a username, firstname, lastname, password (or the hash of a password), address, certificates, date of birth, roles, all kinds of stuff. The data of an LDAP gets accessed for different purposes:

  • authenticate a user: compare the given username and password against values found in the LDAP
  • retrieve attributes: retrieve firstname, lastname, role for a given username
  • authorize users: retrieve access level for directories for a given username

I believe that most developers, at some point in time, had to deal with an LDAP server. So I also believe that most developers will agree with what I just described.

 

OAuth

OAuth is a framework that enables applications (clients) gain access to resources without receiving any details of users they are being used by. To make it a little more visual I am introducing an example:

 

The very cool app 'FancyEMailClient'

 

In the old days:

  • for each email provider the user provides details such as smtp server, pop3 server, username, password on a configuration page within FancyEMailClient
  • FancyEMailClient now accesses all configured email accounts on behalf of the user. More precise, FancyEMailClient is acting AS the user!
  • The user has shared all details with FancyEMailClient ... I must say, it feels a little fishy ... don't you agree?

 

In the days of OAuth:

  • FancyEMailClient is an oauth client and gets registered at each email provider that should be supported
  • FancyEMailClient does not ask users for any email provider details whatsoever
  • FancyEMailClient delegates authentication and authorization to the selected email provider via a redirect_uri
  • FancyEMailClient retrieves an access_token and uses this token at an API such as /provider/email to retrieve the users emails. The access_token may be granted for 'scope=email_api'
  • FancyEMailClient has no clue who the user is and has not seen any details such as username or password
  • This is perfect in regards to the users privacy needs ... However, FancyEMailClient would like to display a message such as 'Hello Sascha' if 'Sascha' is the user ... but it cannot ...

OpenID Connect

As I explained above a client does not get any details about the current user. But since most applications would at least like to display a friendly message such as 'Hello Sascha' there needs to be something to help them.

To stick to the email provider example, before OpenID Connect (OIDC) was born, these providers simply created oauth protected APIs (resources) that would return details about the current user. Users would first give their consent, afterwards the client would get the username or firstname and would display 'Hello Sascha'.

 

Since this became a requirement for almost any oauth clients we now have a common way of doing that, specified in OpenID Connect. OIDC has specified SCOPE values, a /userinfo API and an 'id_token' which represents an authenticated user.

 

In order to enhance the oauth version of FancyEMailClient the developer of it would only have to do a few little things:

  • when requesting access to emails, also request access to user details. The request would now have to include something like '...&scope=openid+profile+email+email_api&...' (scope == permissions like access control)
  • during the authentication and authorization flow the user would not only grant access to his emails but also to his personal details
  • FancyEMailClient would now receive an access_token which could not only be used at /provider/email but also at /provider/userinfo
  • FancyEMailClient can now display 'Hello Sascha'!

 

Now the big question: how does it all come together?

LDAP servers are the only component that exists without OAuth and OpenID Connect. LDAP servers are always the source of users (and maybe also clients and other entities). LDAP servers have always been used to authenticate users and authorize them for resources. OAuth and OpenID Connect cannot be supported if no LDAP server is available. OAuth and OpenID Connect are protocols only, not systems to manage users.

 

Below is a picture which I have created to show an example system:

 

OAuth, LDAP, OIDC

My former manager Jay would now lean back in his chair, put his hands behind his head, put his feet onto a table and would say: Let me explain!

 

Case: OAuth

  1. When a user selects an email provider within FancyEMailClient his browser gets redirected to that provider. It is an OAuth authorization request and includes oauth SCOPE values.  To access the API /provider/email a SCOPE value such as 'email_api' may be included. I say 'may' because there is no standard SCOPE for that. To also gain access to the user details other SCOPE values need to be included. That is more straight forward since they have been specified within OpenID Connect. 'openid profile email' would be sufficient and are supported at practically all OIDC providers. In the end of the flow FancyEMailClient gets back an OAuth authorization_code.
  2. The user only shares his credentials with EMailProvider. He types them into the EMailProviders login page and EMailProvider will validate them against his LDAP server. (LDAP server may be a database or any other system that maintains user details)
  3. After receiving the OAuth authorization_code FancyEMailClient exchanges this short lived token for an OAuth access_token. That access_token provides access to resource APIs. I hope it is obvious that this 'exchange' request is a backchannel request, no browser is involved!
  4. FancyEMailClient accesses /provider/email and /provider/userinfo by providing the OAuth access_token which it received earlier. Although both APIs require an access_token, there is one difference. /provider/userinfo is an OpenID Connect API where as /provider/email is an API proprietary to the EMailProvider. Let's call it a plain OAuth protected API
  5. In this area I wanted to emphasize the role of the LDAP server. As you can see, it is almost involved during all requests.

 

Case: The old days

The same app without using OAuth would probably look something like this:

LDAP only

 

A user would share his credentials with FancyEMailClient. And he would do this for each single provider he has an account with. FancyEMailClient would probably also ask for other details so that an API such as /provider/userinfo would not even be necessary. FancyEMailClient would now collect all this sensitive data and could do whatever it wants with it. That is a big disadvantage!

Another disadvantage is the fact that the users credentials are now used for each single request. That increases the chances for them being exposed.

 

Summary

OAuth, OpenID Connect and LDAP are connected with each other. But I hope it becomes visible which component plays which role and one cannot replace the other. You may say that my explanation is very 'black & white', but I still hope that it clarifies the overall understanding.

As usual, let me know if you have any questions, positive feedback or constructive criticism.

 

Best regards!

Hi everybody!

 

I just uploaded my first youtube video. Nothing crazy and not wild, it is about OAuth. It is a short video explaining how the authorization_code flow works. You will find it here:

 

OAuth 2.0 - Authorization Code flow - YouTube 

 

Enjoy!

Sascha Preibisch

Persistent Consent

Posted by Sascha Preibisch Employee Dec 18, 2017

Hi everybody!

 

This blog post is dedicated to Paul who represents one of our customers. He has asked me to give him an idea on how he could implement persistent consent in OTK until OTK supports that feature out of the box.

 

Persistent Consent vs. Session Consent

In OpenID Connect clients can use parameters such as prompt=none to advise the server to not request consent from the resource_owner again if he has already granted access to his resources in the past. Today OTK remembers a given consent as long as an active refresh_token is available (I call this Session Consent, not sure if there is an official term for that). The token must have been granted for the combination of resource_owner, client_id and scope.

In comparison, Paul and others have said: well, Sascha, the server should remember the decision independently of an active refresh_token (Persistent Consent).

 

Interim solution

We have listened and will provide this feature in a future release of OTK. In order to make this available today I am providing an interim solution which you can implement yourself today.

DISCLAIMER: the official implementation in future OTK may look different so please be prepared to have your users see the consent screen again. Also, my version did not go through QA so please do some testing for yourself before deploying this in production. The status of this provided implementation is this: works on my machine!

 

Implementation for OTK-4.1

Only two policies need to be updated:

  1. /auth/oauth/v2/authorize/login: find a given consent
  2. /auth/oauth/v2/authorize/consent: persist consent

 

In OTK a client can have multiple client_ids. For example, your client SuperCoolApp may have a client_id for the mobile app and one the the JavaScript version of it. In that case you may want to remember the given consent decision not only for the current client_id but for any of that client. This means giving consent for the mobile app will also prevent the resource_owner from seeing the consent screen when using the JavaScript version.

 

Changes in /auth/oauth/v2/authorize/login

Extract the value client_ident from the active session object by adding the two lines below. That value represents the client, not only one single client_id (the line numbers may not match but the 'area' should be correct).

 

Extract client_ident

  • line 121:
    • XPath: /authorize/client_ident
    • Variable Prefix: authorizeClientIdent

 

Next, make up your mind if you want to respect consent decisions of the past only in conjunction with prompt=none or always. By default prompt is required! If you want to ignore the given prompt value disable the branch that checks for it:

Ignore prompt

I am not encouraging you to ignore prompt but I know that I have received this request!

 

Now move existing policies into an All assertions ... container:

Before:

Before using all container

After (moving lines 167, 168, 169 from above into the new All assertions ... on line 167 below):

After using all container

When adding container assertions such as All assertions must ... or At least one assertion ... ALWAYS add comments on the right side that start with // .... This helps reading the policy.

 

The behaviour has not changed yet. Now we are adding logic to look up a consent decision without caring if an active refresh_token exists. This includes the introduction of an At least one assertion ... block. That is required if you want to continue to support Session Consent!:

Logic to support persistent consent

 

Let's go through this line by line:

  • line 169: new At least one assertion ... block
    • this block contains the All assertions ... blocks of line 170 and line 177
    • line 170 handles persistent consent
    • line 177 is the one from above where we moved existing assertions into a new block
  • line 171: find existing consent decision
    • we are using the assertion OTK Session GET which is part of OTK
    • Details:
      • Max age for cache values: 3600
      • Name of cache to be used: otkPersistentConsentCache
      • Key for cache entry: ${resource_owner}${client_ident}
  • line 172 - 173: check if consent exists, extracting the JSON consent message
    • creating the initial consent message is handled further down in this post
    • Details line 173:
      • Encode/ Decode: URL Decode
      • Source Variable: sessionValue.result
      • Target Variable: consentMessage
      • Data Type: Message
      • Content Type: application/json
  • line 174: find granted scope
    • its important to present the Consent screen if the client has not requested the SCOPE in the past (no matter what)! 
    • Details:
      • Expression: granted_scope
      • Other Message Variable: consentMessage
      • Variable Prefix: xpathScope
        • we are not using xpath, but using this name allows us to reuse a few lines of policy further down
  • line 175: find the client
    • to be fail safe extract the client_ident of the past
    • Details:
      • Expression: granted_client
      • Other Message Variable: consentMessage
      • Variable Prefix: granted_client
  • line 176: compare the current client against the one from the past
    • ${client_ident} equlasTo(${granted_client.result})

 

It should look like this:

Result for changes at login

 

Changes in /auth/oauth/v2/authorize/consent

The good news: its just a 2 liner! Look for the block on line 96 of the screenshot below:

Finding the right spot

 

Open that block and go right to the end. It ends with an assertion named OTK Session - Delete. Right after that we will add 2 assertions:

New assertion in consent

 

Lines 155 and 156 are the new ones.

  • line 155: Set Context Variable. This is where we are creating the content for a given consent. You can certainly add other values as you desire
    Consent message
  • line 156: Creating the persistent session
    Consent session

 

That is all there is. Here are some thoughts though:

  • Get an idea on how many consent decisions you want to persist. Specify the value Max. number of entries in the dialog above appropriately
  • Max. database age vs. Max. age for cache: the database age is the persistent memory (this example: 90 days). During this time a consent screen will not be displayed.
    The Cache age is simply the one that helps avoiding accessing the database.
    IMPORTANT: The cache age here has to match the cache age used at /auth/oauth/v2/authorize/login when using OTK Session GET
  • Although this solution works out of the box you could certainly choose to build you own assertion that works with your own, dedicated database table that you may have or want to create for this purpose
  • Client vs. Client_id: if your client has multiple client_ids which are registered for different valid SCOPE values you may not want to use client_ident but the current client_id as part of your session key
  • Revoking Persistent Consent was not covered here. Please think about the scenario on how you want to support resource_owners revoking their given consent. If you are leveraging the revocation endpoint you can add logic there to support it

 

Summary

I hope this post gives you an idea on how you can implement Persistent Consent rather than Session Consent. Even if you are not going for the solution described here it may still give you an idea on how features as these can be implemented very easy. If you are looking forward to see this feature in OTK in the future please give us feedback so that we can build it the way you want it.

 

Paul, I hope this is what you were looking for!

 

As always, thanks for positive feedback and constructive criticism.

Best regards, Sascha

Hi everyone!

 

Just in time for the weekend I have published a new tutorial that shows in detail how to build APIs that retrieve resources from a local datasource or a remote API. As an example I am accessing a database.

 

The shown building blocks allow a developer to implement APIs without having to know where the resources are located. The source for this tutorial is available as RESTMan bundle and can easily be imported into a CA API Gateway using the RESTMan API. 

 

Here are two images to give you an idea what is being shown:

 

Service and Data APIs:

APIs for local or remote resource retrievel

 

Encapsulated assertions that transparently retrieve data from a local database or via a data API:

Retrieve data from local database or remote API

 

Find the tutorial in the project Tutorials here: CA APIM on github.

Open the file index.html and select Encapsulating access to resources.

 

As always, let me know if it helps and what you like and do not like.

Hello everyone!

CA World 2017 was a very good event. We had good times showing our products and very good discussions with our customers and to-be customers.

At the pre-conference session that was about news in OTK-4.1 I was using a SOAPUI project and promised to make it available for everyone.

Well, I am excited to announce that we now have a new project in our public GitHub repository that is dedicated to tutorials. Hopefully, over time, we are able to add more helpful content, maybe also with help of our user community.

 

Please find the repository here: CA APIM - Open Source and select the project Tutorials.

 

To have this becoming a successful way of providing tutorials and examples its important that you take a moment to have a look at the REAME content.

 

As always, please let us know if this is helpful!

Sascha Preibisch

CA World 2017

Posted by Sascha Preibisch Employee Nov 9, 2017

CA World 2017 (13.11.2017 - 17.11.2017)

 

Another year has passed and next week I am off to Las Vegas for another great event! Just as many of my colleagues.

 

I am writing to share with you which talks I am presenting:

 

  1. A pre-conference session (DO1X106E) about news in our OpenID Certified OTK implementation (CA APIM OAuth Toolkit 4.1). This includes a demo for which I am using SOAPUI. Since many of you have asked me about example SOAPUI projects I am taking the chance to provide it to you
  2. A pre-conference session (DO1X118E) about microservices security including a very cool preview of an upcoming feature
  3. A pre-conference session (DO1X117E) about scalable microservices environments
  4. A TechTalk (D01T52T) during the actual conference days in the DevOps API area. The topic is the same as for the 3. pre-conference session, but more compressed to include only the highlights

 

I would be happy to see you there to meet and chat and pick up your thoughts on what we are doing good and what we should improve! Come and find me at the SMART bar in the DevOps API area if not during the sessions.

Hi everybody!

This weeks tip is meant for anybody implementing oauth protected API's on the CA API Gateway or CA Mobile API Gateway. With both products the OAuth Toolkit (OTK) will be leveraged.

 

Here is the tip: Use variables set by 'OTK Require OAuth 2.0 Token'

When implementing oauth protected API's the main assertion to use is named OTK Require OAuth 2.0 Token. That assertion finds an incoming access_token and validates it. If the given token is invalid the assertion fails and returns an error. If the token is valid a few variables are being set. And those can be very useful when it comes to requiring more than just the token itself.

Here is a list of those variables and what they contain:

  • access_token: the token that was used by the client. This is mainly for informational purposes
  • session.client_id: the client_id of the client that has requested the token initially. This is for informational purposes but it could also be used to look up other associated values of this client
  • session.scope: the granted SCOPE for this token. The content is a space separated list of values. It is useful to implement branches within an API that retrieves data based on the SCOPE. An example can be found at /openid/connect/v1/userinfo. That API first requires the SCOPE=openid (configured in OTK Require OAuth 2.0 Token). Further down it checks if the granted SCOPE includes values such as email or profile. Have a look how this variable is used with OTK SCOPE Verification
  • session.subscriber_id: this is the username of the resource_owner that has granted the initial authorization request. If no consent was required during the token issuing process (e.g.: grant_type=password) it's simply the authenticated user. If the token was issued via grant_type=client_credentials the value will be the name of the client
  • session.expires_at: the timestamp at which the token expires
  • session.custom: this contains a JSON structure. The content contains values that were specified when the oauth client was registered in OAuth Manager. It also contains runtime information. In order to learn about the content, and since it varies, do the following during development: Use an Audit Detail assertion to log the content of '${session.custom}'. Afterwards extract values using the Evaluate JSON Path Expression assertion when you know what you want to extract. By default values such as the following are available:
    • client_type: either 'confidential' or 'public'
    • grant_type: the grant_type used to obtain the token

What to do with those variables

Now that you know about these variables you can implement use cases such as the following:

  • grant access only if the token was obtained via a specific grant_type
  • extract attributes of the current user to pass them on to the backend service
  • grant different access to resources depending on the client type
  • implement rate limiting based on the access_token for special cases

 

I hope this helps, and as usual, let me know if you need more information or details or if you have got other related questions!

I am happy to share with you that OAuth Toolkit 4.1 (OTK-4.1) has been released last week. 

 

If you have previously installed OTK-4.0 you are now able to upgrade to OTK-4.1 without loosing your customization. We are happy that this is now supported! (Please read the documentation when doing that).

 

Here are a few links that I think are useful to get started:

 

As usual, please let us know how you like this version and share any suggestions for future enhancements you would like to see.