Add more info return in when invoking oauth/token

When we invoke http://localhost:8080/oauth/token, it returns

{
  "access_token":"roczaiT8LHQDldEBxabzJEv0SBo",
  "token_type":"bearer",
  "refresh_token":"bCkyUzMHrhUwtY3X_4COgolz3DM", 
  "expires_in":43199,
  "scope":"api",
  "OAuth2.SESSION_ID":"30E958C37E51158B240F26FC5B75AA5A"
}

Is it possible if I want it to more info to return here, like the user id or the additional field I added to the user entity?

The reason for that is that I want users logged in Jmix system can automatically log in other system as well.

You’ll have to add the following dependency to the build.gradle file:

implementation 'org.springframework.security.oauth:spring-security-oauth2'

Create custom token enhancer:

import io.jmix.core.session.SessionData;
import io.jmix.securityoauth2.impl.SessionTokenEnhancer;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;

import java.util.HashMap;
import java.util.Map;

public class MyTokenEnhancer extends SessionTokenEnhancer {

    public MyTokenEnhancer(ObjectProvider<SessionData> sessionDataProvider) {
        super(sessionDataProvider);
    }

    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
        DefaultOAuth2AccessToken defaultAccessToken = (DefaultOAuth2AccessToken) super.enhance(accessToken, authentication);

        Map<String, Object> additionalInformation = new HashMap<>(accessToken.getAdditionalInformation());
        additionalInformation.put("my_attr", "my_value");

        defaultAccessToken.setAdditionalInformation(additionalInformation);
        return defaultAccessToken;
    }
}

And BeanPostProcessor that sets this token enhancer into the TokenServices:

import com.company.resttokenenhancer.rest.enhancer.MyTokenEnhancer;
import io.jmix.core.session.SessionData;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.stereotype.Component;

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    private ObjectProvider<SessionData> sessionsDataProvider;

    public MyBeanPostProcessor(ObjectProvider<SessionData> sessionsDataProvider) {
        this.sessionsDataProvider = sessionsDataProvider;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof DefaultTokenServices) {
            ((DefaultTokenServices) bean).setTokenEnhancer(new MyTokenEnhancer(sessionsDataProvider));
        }
        return bean;
    }
}

After that you’ll get the “my_attr” field in the token response:

{
    "access_token": "ZD7hNwoPjk3fHOM4YJpjbkwowtY",
    "token_type": "bearer",
    "refresh_token": "wQ7UH_tOMNf8TM30GUWk0nUTfxk",
    "expires_in": 43173,
    "scope": "api",
    "OAuth2.SESSION_ID": "A61F1DB1385E7FDC2636B8B37AA77679",
    "my_attr": "my_value"
}

The sample project: rest-token-enhancer.zip (162.4 KB)

1 Like

Thanks, that is exactly what I need!