OAuth 2.0 is an open standard for delegated authorization supported by WebSphere® Liberty. In this example a Liberty
server is configured to use the OAuth 2.0 authorization code flow to authorize access to a protected
web application.
About this task
The following procedure covers how to:
- Define an OAuth service provider.
- Grant an OAuth 2.0 token using the authorization code flow.
- Use this token to access a protected resource in a Liberty web application.
Procedure
- Add the
oauth-2.0 and the cicsts:security-1.0 features
to the featureManager element in server.xml.
<featureManager>
<feature>oauth-2.0</feature>
<feature>cicsts:security-1.0</feature>
</featureManager>
...
OAuth is an HTTP-based protocol and a web application is supplied by Liberty to secure
access to the authorization and token endpoints. The web application is built in and is started
automatically when you specify the oauth-2.0 feature.
- Set up role mapping for the Liberty OAuth web application by using the
oauth-roles element.
Map the authenticated role to one or more users, groups, or special subjects. Additional roles,
clientManager and tokenManager, are supplied but it is not
necessary to map these roles for OAuth authorization to function. The following example shows the
special subject of ALL_AUTHENTICATED_USERS being used to grant access to the OAuth web
application.
<oauth-roles>
<authenticated>
<special-subject type="ALL_AUTHENTICATED_USERS"/>
</authenticated>
</oauth-roles>
- Configure an OAuth 2.0 provider and a client using
the
oauthProvider element. The provider must have at least one client defined.
You can define clients in any of the following ways:
- Locally with the
localStore and client elements. This is the approach this
example uses.
- In a relational database with the
databaseStore element.
- In a custom
OAuthStore implementation with the customStore element.
Restriction: Db2® JDBC type 2 connectivity is not
supported for persistent OAuth 2.0 services.
In the following example, a client named
ClientApp is defined locally and the
OAuth provider specifies a scope of email and secures access to the URL
oauthapp. This ensures that only clients with a valid access token can be
authorized to access the protected resource.
<oauthProvider id="myProvider" filter="request-url%=oauthapp" oauthOnly="true" >
<localStore>
<client name="ClientApp" secret="mySecret" scope="email" redirect="https://client.example.ibm.com/webapp/redirect" />
</localStore>
</oauthProvider>
The provider must have at least one client defined, with a unique name, a secret password, and
the redirect URI of the application.
Important:
Although it is not shown in this example, it is important to encode passwords and limit access to
server.xml configuration. Passwords can be encoded by using the Liberty
securityUtility, found in USS_HOME/wlp/bin/securityUtility. For
more information, see securityUtility command.
-
To initiate the authorization code flow, the client application accesses the authorization
endpoint, passing in the
response_type of code and the
client_id, client_secret, redirect_uri,
scope configured in Step 3 as query parameters on a HTTP GET request.
This flow is normally performed programmatically in the client application. The following
query shows an example web request.
https://zos.example.ibm.com/oauth2/endpoint/myProvider/authorize?response_type=code&client_id=ClientApp&client_secret=mySecret&redirect_uri=https://client.example.ibm.com/webapp/redirect&scope=email
- Upon receiving the request, the Liberty authorization server redirects the resource owner
(user) to authenticate using a customizable login form, and then prompts the resource owner to
confirm the email authorization scope should be granted.
- The user is then redirected back to the redirect URI. The Liberty authorization endpoint returns the authorization
code as a query parameter of the URI.
The client application must store this authorization code to
request an access token.
- The client application requests an access token by sending the authorization code that
was received from the authorization endpoint, along with the
client_id and the
pre-defined secret password in an HTTP POST request to the token endpoint. This flow is normally performed programmatically in the client application. The following
example shows the parameters required.
POST https://zos.example.ibm.com/oauth2/endpoint/myProvider/token HTTP/1.1
Content-Type: application/www-form-urlencoded
grant_type=authorization_code&
code=<code>&
client_id=ClientApp&
client_secret=mySecret&
redirect_uri=https://client.example.ibm.com/webapp/redirect
- The authorization server returns a JSON document that contains the access token, its
expiry time, and its authorized scope.
For
example:
{
"access_token": "AvTQKrK6H6Uqw4E5ffATHRHuq7d7PEmqP5ss32Mr",
"token_type": "Bearer",
"expires_in": 7199,
"scope": "email",
"refresh_token": "8X5cwCDUClYRw8nbCTEHkciGLozne9woR1tCXNAMQ4aGVSZlGY"
}
- You can then use this token to access the protected resource on the resource server by
passing the request as a bearer token in an HTTP Authorization header.
Liberty then uses
the OAuth access token to create a security subject, which can then be used to authorize access to
the protected resource.
Note: In
Enterprise Java™ applications, roles are used to authorize access to application URIs or Java methods. When using OAuth2.0, you need to define appropriate role security rules to authorize access to the protected resource based on the security subject created from the access token. See
Role authorization.
Results
The OAuth 2.0 access token can be used by the client application to access a protected web application running in the resource server. Requests to the web application are mapped to the Java security subject that was created when the resource owner authenticated with the authorization server. By using the CICS® security feature, you ensure that the SAF user ID associated with the security subject is used as the CICS task user ID for any subsequent CICS security authorization checks for the CICS transaction that runs the web request.