Understanding Two types of OAuth2 Authorization Workflows
OAuth provides machine/client to machine/resource communication with trusted connections. Resource validates client through a access token from client.
OAuth client needs to acquire access token first and then talk to resource by providing the token to identify the client and what the client can do. whoever has the access token can access resource with allowed permissions defined in the token.
OAuth2 client gets access token via authorization workflow with OAuth2 server. There are multiple workflows/grant types but two main flows: 1) resource owner password flow and 2) authorization code flow.
Resource owner password flow is simple: client provides target resource owner’s username and password when requesting access token from OAuth server. It means client is trusted by the resource owner.
Note, OAuth server has to authenticate resource user/password. Usually this OAuth server acts as IDP for resource as well. For example, ServiceNow OAuth server and ServiceNow tables, Snowflake internal OAuth server and Snowflake databases.
Client issues following command to OAuth token endpoint to get access token.
curl -d "grant_type=password"
--data-urlencode "client_id=xxxx"
--data-urlencode "client_secret=yyyy"
--data-urlencode "username=servicenow_user1" # ServiceNow user
--data-urlencode "password=zzzz"
-X POST https://app1.service-now.com/oauth_token.do # ServiceNow OAuth Server
Output:
{"access_token":"kM37xxxxxxxxx-Q",
"refresh_token":"HIuxw5yyyyyyyyVsVA",
"scope":"useraccount",
"token_type":"Bearer","expires_in":1800}
Authorization code flow is mainly for web application client or mobile app client. Client gets authorization code first and then redeem code for access token.
Following diagram shows the data flow from client to OAuth server (Azure, Okta) and target resource (Snowflake Data Cloud). And components in OAuth server, target resource.
1> Client asks access token providing its client ID/secret, scope to OAuth endpoint
Client gets its client ID/secret from OAuth server in advance. This is when an “OAuth app” is created at OAuth server end — one “OAuth app” serves one single client with unique client ID and secret. When creating this “OAuth app” client’s “redirect URL” needs to be provided so future access token can be returned to.
Client also sends “scope” that indicates what data client want to access.
Note, client is just an request source entity — it can be a Python app, postman desktop or Tableau public etc.
2> and 3> OAuth server ask client to authenticate with known credential in a popped out web page. In case of Okta as OAuth server, we then need to key in Okta user and password.
4> and 5> Once authentication is done, another popped out web page asks for consent to the requested scope — allow this client to represent this user to access given data: only user’s email info or full access as this user?
6> Once consent is given, OAuth server generates “authorization code” and redirect to client’s “redirect URL” with this code. Client then will ask back to redeem this code to be an access token. This logic has it’s reason for better security: code returns from front end (a browser URL) even though it’s using TLS and then access code will be communicated at backend between client and server.
7> Client then passes this access code (as bearer token usually) to resource data access endpoint.
Resource end like Snowflake looks at this access token for issuer so it matches for a Snowflake external OAuth security integration. Then it maps user name info in the token (sub for token generated by Okta, upn for tokens from Azure) to “login_name” in Snowflake user credentials.
8> So now Snowflake knows the user name in Snowflake and it’s role and permissions. Snowflake is able to return requested data that this user has access permission to.
Happy Reading!