It is also possible to replace the authorization servlet in any version of OA4MP with a customized version. You may then, for instance, use LDAP or Shibboleth for authentication. The protocols require that your module occupy the authorize endpoint. The assumptions then are that
If you have a Tomcat only service, then you must protect this endpoint. A typical security security constraint is the following, which should be added to the deployment descriptor (web.xml file)
<security-constraint> <web-resource-collection> <web-resource-name>Lockdown_initiate_endpoint</web-resource-name> <url-pattern>/authorized</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> <http-method>PUT</http-method> <http-method>DELETE</http-method> </web-resource-collection> <auth-constraint/> </security-constraint>
which will prevent all access to the authorized endpoint except from Tomcat itself. If you access the service from Apache, you will have to limit access to this endpoint at the server level to calls from localhost only. The authorized servlet comes with this security constraint enabled by default since it is better to have the authentication fail if there is any question about the setup.
<servlet> <servlet-name>authorized</servlet-name> <servlet-class>edu.uiuc.ncsa.myproxy.oa4mp.server.servlet.AuthorizedServlet</servlet-class> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>authorized</servlet-name> <url-pattern>/authorized</url-pattern> </servlet-mapping>
The specification requires that the call to your module has the oauth_token present, which you must pass on to the authorized servlet -- this the internal identifier linking the user to their request. A common method of deployment, e.g for Shibboleth, is to use Apache with ProxyPass for Tomcat and only allow localhost access to Tomcat. Your module can then call Tomcat. The expected request to the server consists of 4 parameters:
localhost://oa4mp.bigstate.edu:8080/authorized?oauth_token=sj38GHTYf24354&username=bob&password=somepassword&lifetime=100000000
status=ok redirect_uri=https%3A%2F%2Fportal.example.edu%2Foauth%2Fready%3Foauth_token%3Dhdk48Djdsa%26oauth_verifier%3Dhfdp7dh39dks9884
The servlet used in this case is named OA2AuthorizedServlet. So a typical entry would look like
<servlet> <servlet-name>authorized</servlet-name> <servlet-class>edu.uiuc.ncsa.myproxy.oa4mp.oauth2.servlet.OA2AuthorizedServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>authorized</servlet-name> <url-pattern>/authorized</url-pattern> </servlet-mapping>
Note that the name of this servlet may be altered without changing the protocol. Some installation prefer to call it /init since authorize and authorized are very similar.
The very first step in the OAuth 2.0 protocol is that the user goes to the authorize endpoint which will then simply call the end authorized endpoint by passing along verbatim the original request your authorization module received. For instance, if your server got the following request
https://your.server.edu/oauth2/authorize?state=s0jByyFvSNeoDUZ1GbyRy&nonce=ABC75344A&...
You do the authorization and once completed successfully, you call the authorized servlet:
https://localhost/oauth2/authorized?state=s0jByyFvSNeoDUZ1GbyRy&nonce=ABC75344A&...
All state and error checking will be done for you. You will simply receive the standard response (with HTML status code of 200, since 302 is reserved for error conditions -- see below for more) in JSON of the token and the state (if that was passed in the initial request) -- simply pass this response back to the client in the standard OIDC redirect. For instance
{"code":"urn:oauth2:aMQ53UmEtb5cM6WF/ps7wOmYQoJTTKAW9","state":"s0jByyFvSNeoDUZ1GbyRy"}
The authorized servlet supports all of the same error codes as the standard OAuth 2.0/OIDC specification. This means that there will be an HTML status code of 302 (a redirect) to the callback url that the client supplied (in the request and at registration). This may again be passed along directly to the client which is required to process it. For example, if the above request were invalid and had consequently, failed then if the base url of the error is https://your.client.org/cb your authorize module would get the following redirect, as per the OA4MP/OIDC spec:
Location: https://your.client.org/cb? error=invalid_request &error_description= the%20request%20is%20not%20valid%20or%20malformed &state=s0jByyFvSNeoDUZ1GbyRy