I want to learn how to use the oauth2 Authorization Code Flow in Go. The example code is based on the github.com/okta/samples-golang/tree/develop/okta-hosted-login repository and modified for an production ready example.
Follow these steps to run the example client + backend on your localhost:
- Okta prerequisites
- Set the
Audiencein your OKTA Authorization server totesting-client(under /admin/oauth2/as) - Create a new scope in your OKTA Authorization server called groups, add a new claim for the access token which maps the user groups into the token.
- Create a new Group called
Adminand assign your user to it. - Create an
.envfile in the root dir of the project with the following variables:Note that you can find the issuer URI on theOKTA_CLIENT_ID= OKTA_CLIENT_SECRET= OKTA_ISSUER= BACKEND_URL=http://backend:8081 ENCRYPTION_KEY=fyjt3DYF
<your-okta-url>/admin/oauth2/aspage - Build and run via docker-compose
docker-compose up --build
The first step of the Authorization Code Flow is to redirect the user to the OIDC provider (also called the issuer) login page. Your application has to send the following required parameters in order to proceed the login.
These are the query parameters:
client_id: The ID of the used client which is configured/present at the issuers site.response_type: Tells the authorization server which grant to execute. For the Authorization Code grant, use response_type=code to include the authorization code. For the Implicit grant, use response_type=token to include an access token. An alternative is to use response_type=id_token token to include both an access token and an ID token.response_mode: (Optional) How the result of the authorization request is formatted.scope: A space-delimited list of permissions that the application requires.state: An opaque value, used for security purposes. If this request parameter is set in the request, then it is returned to the application as part of the redirect_uri. The state has to be verified by the call-back handler.redirect_uri: Holds a URL. A successful response from this endpoint results in a redirect to this URL.nonce: The nonce will be added into the access token as a claim and should be verified by the server.
After a user successfully logged in, the issuer will redirect the user to the defined redirect_url. The issuer added the following query parameters to the redirect request which will be used to exchange an valid access_token and ìd_token:
code: This is short living token which will be used to request the issuerstoken endpointto issue anaccess_tokenandìd_token.state: This string has be the same as thestatesend in the previous request to the issuer. If the state values differs the auth flow should be aborted due to integrity is not given.
When requesting the token endpoint of the issuer via a POST request in order to get an access_token and ìd_token the following headers & query parameter are required:
grant_typequery parameter: The Authorization Code grant type is used by confidential and public clients to exchange an authorization code for an access token.codequery parameter: Its the short living token provided by the issuer. In combination with theclient_idandclient_secretthe issuer can validate the request and is able to issue the correctaccess_tokenandìd_tokenfor the user.redirect_uriparameter: The value of the redirect_uri parameter included in the original authentication request.Authorization Basic <CLIENT_ID:CLIENT_SECRET>header: Setting a authorization header to verify the applications identity.Content-Type application/x-www-form-urlencodedheader: Tells the server to lookup the http query parameters for the required information
On a successful request the issuer response with the access_token, id_token and other additional information:
type Exchange struct {
Error string `json:"error,omitempty"`
ErrorDescription string `json:"error_description,omitempty"`
AccessToken string `json:"access_token,omitempty"`
TokenType string `json:"token_type,omitempty"`
ExpiresIn int `json:"expires_in,omitempty"`
Scope string `json:"scope,omitempty"`
IdToken string `json:"id_token,omitempty"`
}Both received tokens have to validated by the server. Please read the following for more details: