If you wish to add support to an OA4MP OIDC server, you may do this by specifying scopes that are supported in the server configuration file. The client must request these. If you do not specify the additional scopes in the server configuration, then requests for these from a client will cause the server will reject the request. This blurb is about implementing your own handler.
Remember that if you specify a custom scope handler, it will always be called and replaces the BasicScopeHandler which is the default. Even if you do not have a custom scope, this will let you completely rewrite all claims.
The lifecycle of the handler is simple. It is created at server startup and is called whenever needed. This may either be a full implementation of the ScopeHandler interface or, more easily, an extension of the BasicScopeHandler class. In both cases you implement or override the process methods. There are two of these:
public UserInfo process(UserInfo userInfo, ServiceTransaction transaction) throws UnsupportedScopeException; public UserInfo process(UserInfo userInfo, HttpServletRequest request, ServiceTransaction transaction) throws UnsupportedScopeException;
This receives a UserInfo object which has been populated by the server with the default claims. The service transaction has all of the information that the system has on the current user. Simply set whatever values you want returned in the UserInfo object and return that. If you choose the method with the servlet request, then you will be passed the current request, which includes the headers and other information.
Note especially that the UserInfo object has many, many convenience mutators. If you have some specific claims you need to return, simply set them using the put methods or if you need something more exotic, get the underlying JSON object with the getMap call and set the key/value pair directly. The response to the client will take the underlying JSON object and serialize it.
The easiest way to do this is to extends the environment and simply specify the handler. This consists of 4 steps as follows
public class MyScopeHandler extends BasicScopeHandler{ @Override public UserInfo process(UserInfo userInfo, ServiceTransaction transaction) throws UnsupportedScopeException { // Set whatever you need in the userInfo object then return it return userInfo; } @Override public UserInfo process(UserInfo userInfo, HttpServletRequest request, ServiceTransaction transaction) throws UnsupportedScopeException { // Set whatever you need in the userInfo object then return it return userInfo; } }
public class MyConfigurationLoader<T extends OA2SE> extends OA2ConfigurationLoader<T>{ public MyLoader(ConfigurationNode node){ super.node(); } public myLoader(ConfigurationNode node, MyLoggingFacade logger) { super(node, logger); } @Override public ScopeHandler getScopeHandler() throws ClassNotFoundException, IllegalAccessException, InstantiationException { scopeHandler = new MyScopeHandler(); scopeHandler.setScopes(getScopes()); // this is a complete list of scopes from the configuration file, if needed. } }
public class MyBootstrapper extends OA2Bootstrapper{ @Override public ConfigurationLoader getConfigurationLoader(ConfigurationNode node) throws MyConfigurationException { return new MyLoader(node); } }
<listener> <listener-class>path.to.MyBootstrapper</listener-class> </listener>
When the server boots, it should find everything and your handler should be used.