You must register the app with an OpenID Provider such as Google or Amazon.
This will give you a Client ID and Client Secret.
Once set up you must also register all the possible URI’s for your webapp with the path /j_security_check
so that the OpenId Provider will allow redirection back to the webapp.
These may look like
To enable OpenID support, you first need to activate the openid
module in your implementation.
java -jar {JETTY_HOME}/start.jar --add-to-start=openid
To configure OpenID Authentication with Jetty you will need to specify the OpenID Provider’s issuer identifier (case sensitive URL using the https
scheme) and the OAuth 2.0 Client ID and Client Secret.
If the OpenID Provider does not allow metadata discovery you will also need to specify the token endpoint and authorization endpoint of the OpenID Provider.
These can be set as properties in the start.ini
or start.d/openid.ini
files.
The web.xml
file needs some specific configuration to use OpenID.
There must be a login-config
element with an auth-method
value of OPENID
, and a realm-name
value of the exact URL string used to set the OpenID Provider.
To set the error page, an init param is set at "org.eclipse.jetty.security.openid.error_page"
, its value should be a path relative to the webapp where authentication errors should be redirected.
Example:
OPENID
https://accounts.google.com
org.eclipse.jetty.security.openid.error_page
/error
If the OpenID Provider allows metadata discovery then you can use.
OpenIdConfiguration openIdConfig = new OpenIdConfiguration(ISSUER, CLIENT_ID, CLIENT_SECRET);
Otherwise you can manually enter the necessary information:
OpenIdConfiguration openIdConfig = new OpenIdConfiguration(ISSUER, TOKEN_ENDPOINT, AUTH_ENDPOINT, CLIENT_ID, CLIENT_SECRET);
LoginService loginService = new OpenIdLoginService(openIdConfig);
securityHandler.setLoginService(loginService);
Authenticator authenticator = new OpenIdAuthenticator(openIdConfig, "/error");
securityHandler.setAuthenticator(authenticator);
servletContextHandler.setSecurityHandler(securityHandler);
Claims about the user can be found using attributes on the session attribute "org.eclipse.jetty.security.openid.claims"
, and the full response containing the OAuth 2.0 Access Token can be found with the session attribute "org.eclipse.jetty.security.openid.response"
.
Example:
Map claims = (Map)request.getSession().getAttribute("org.eclipse.jetty.security.openid.claims");
String userId = claims.get("sub");
Map response = (Map)request.getSession().getAttribute("org.eclipse.jetty.security.openid.response");
String accessToken = response.get("access_token");
The OpenID scope is always used but additional scopes can be requested which can give you additional resources or privileges.
For the Google OpenID Provider it can be useful to request the scopes profile
and email
which will give you additional user claims.
Additional scopes can be requested through the start.ini
or start.d/openid.ini
files, or with OpenIdConfiguration.addScopes(…);
in embedded code.
If security roles are required they can be configured through a wrapped LoginService
which is deferred to for role information by the OpenIdLoginService
.
This can be configured in XML through etc/openid-baseloginservice.xml
in the Distribution, or in embedded code using the constructor for the OpenIdLoginService
.
LoginService wrappedLoginService = ...; // Optional LoginService for Roles
LoginService loginService = new OpenIdLoginService(openIdConfig, wrappedLoginService);
When using authorization roles, the setting authenticateNewUsers
becomes significant.
If set to true
users not found by the wrapped LoginService
will still be authenticated but will have no roles.
If set to false
those users will be not be allowed to authenticate and are redirected to the error page.
This setting is configured through the property jetty.openid.authenticateNewUsers
in the start.ini
or start.d/openid.ini
file, or with OpenIdLoginService.setAuthenticateNewUsers(…);
in embedded code.