In this post, we will describe the implementation in a bit more detail.
First we will describe the database schema for the OAuth.
Then we will describe the logic in the controllers that will validate and filter out the bad requests and those explicitly prohibited.
Then we will describe the tests for the webUI Integration. All along the implementation we will use the features available from the existing proxy and stage the changes needed to remove the proxy.
First among these is the schema for the token table. This table requires a mapping for the userId and the clientId together with the issued token. This table is entirely for our compliance with OAuth security caveats and hence user, clients and proxy are unaware of this table and will not need to make any changes on their side due to any business rules associated in this table as long as they are OAuth compliant. Since the token is issued by the proxy, we will need to keep token request and response information in this table. In addition, we will record the apiKey and clientId from the client along with the token even though the proxy may be enforcing this already. (Note clientId is internal and apiKey is public and they are different.) This as described in the previous post helps us know who the token was originally intended for and whether, if any, misuse occurs by a third client. And we will keep the user mapping as optional or require a dummy user since some clients may request credentials only to access non-privileged resources. It could be interesting to note that the userId is entirely owned by our API and retail company but the check for an access token issued on behalf of one user to be used with only that user's resources is currently enforced by the proxy. That means the proxy is keeping track of the issued token's with the user context or is passing the user context back to the API with each incoming token.
But we have raised two questions already. First - Should we treat user context as nullable or should we default to a dummy user. Second - Does the proxy pass back the user context in all cases or should the API implement another way to lookup user given a token for non-proxy callers ?
Let us consider the first. The requirement to have a non-nullable field and have a default value for client credential only calls, is certainly improving validation and governance. Moreover, we can then have a foreign key established with the user table so that we can lookup user profile information directly off the token after token validation. This leads the way to removing the ugly "/user/me" resource qualifier from all the apis that access user privileged resources. The userId is anyways internal usage only so the APIs look cleaner and we can internally catalog and map the APIs to the type of access they require. This means having another table with all the API routes listed and having classified access such as user privileged or general public. This table is not just an API-Security table but also provides a convenient placeholder for generating documentation and checking correctness of listings elsewhere. Such additional dedicated resources for security could be considered an overhead but we will try to keep it minimal here. Without this table we will assume that each API internally applies the UserId retriever ActionFilterAttribute to those that require to access privileged resources and the retriever will apply and enforce the necessary security.
We will also answer the second question this way. The proxy provides user information via "X-Mashery-Oauth-User-Context" in the request header. This lets us know that the token has been translated to a user context and the proxy has looked it up in a token database. This token database does not serve our API Security otherwise we would not be discussing our schema in the first place. So lets first implement the schema and then we will discuss steps 2 and 3.
First we will describe the database schema for the OAuth.
Then we will describe the logic in the controllers that will validate and filter out the bad requests and those explicitly prohibited.
Then we will describe the tests for the webUI Integration. All along the implementation we will use the features available from the existing proxy and stage the changes needed to remove the proxy.
First among these is the schema for the token table. This table requires a mapping for the userId and the clientId together with the issued token. This table is entirely for our compliance with OAuth security caveats and hence user, clients and proxy are unaware of this table and will not need to make any changes on their side due to any business rules associated in this table as long as they are OAuth compliant. Since the token is issued by the proxy, we will need to keep token request and response information in this table. In addition, we will record the apiKey and clientId from the client along with the token even though the proxy may be enforcing this already. (Note clientId is internal and apiKey is public and they are different.) This as described in the previous post helps us know who the token was originally intended for and whether, if any, misuse occurs by a third client. And we will keep the user mapping as optional or require a dummy user since some clients may request credentials only to access non-privileged resources. It could be interesting to note that the userId is entirely owned by our API and retail company but the check for an access token issued on behalf of one user to be used with only that user's resources is currently enforced by the proxy. That means the proxy is keeping track of the issued token's with the user context or is passing the user context back to the API with each incoming token.
But we have raised two questions already. First - Should we treat user context as nullable or should we default to a dummy user. Second - Does the proxy pass back the user context in all cases or should the API implement another way to lookup user given a token for non-proxy callers ?
Let us consider the first. The requirement to have a non-nullable field and have a default value for client credential only calls, is certainly improving validation and governance. Moreover, we can then have a foreign key established with the user table so that we can lookup user profile information directly off the token after token validation. This leads the way to removing the ugly "/user/me" resource qualifier from all the apis that access user privileged resources. The userId is anyways internal usage only so the APIs look cleaner and we can internally catalog and map the APIs to the type of access they require. This means having another table with all the API routes listed and having classified access such as user privileged or general public. This table is not just an API-Security table but also provides a convenient placeholder for generating documentation and checking correctness of listings elsewhere. Such additional dedicated resources for security could be considered an overhead but we will try to keep it minimal here. Without this table we will assume that each API internally applies the UserId retriever ActionFilterAttribute to those that require to access privileged resources and the retriever will apply and enforce the necessary security.
We will also answer the second question this way. The proxy provides user information via "X-Mashery-Oauth-User-Context" in the request header. This lets us know that the token has been translated to a user context and the proxy has looked it up in a token database. This token database does not serve our API Security otherwise we would not be discussing our schema in the first place. So lets first implement the schema and then we will discuss steps 2 and 3.
No comments:
Post a Comment