OAuthHandler

Interface for supporting 3rd party oauth2 authentication flows

This interface makes it possible to support secure third-party OAuth2 authentication for your Dexi app.

Source: Github

You can implement OAuth2 authentication for your app by adding a field of type "oauth" to your configuration fields.

The field would look like the following for Google OAuth.

configuration:
    google:
      title: Google
      type: oauth
      help: Connect your google account to get access to your google account
      required: true
      sortOrder: 1
      configuration:
        oauth: #These 2 endpoints are required. The below configuration is correct when using the Dexi App SDK and implementing the OAuthHandler interface
          redirect:
            method: POST
            url: "${baseUrl}/oauth/redirect"
          validate:
            method: POST
            url: "${baseUrl}/oauth/validate"

Secondly you will need to implement the interface itself which could look something like the following - this is again for Google (this is an example from the Google OAuth module made available by Dexi)

package io.dexi.google.handlers;

import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.services.plus.model.Person;
import io.dexi.google.GoogleService;
import io.dexi.oauth.OAuthTokens;
import io.dexi.service.exceptions.UserErrorException;
import io.dexi.service.handlers.OAuthHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ResponseStatusException;

import java.io.IOException;
import java.net.URL;

@Slf4j
@Service
public class GoogleOAuthHandler implements OAuthHandler {

    private static final String OAUTH_PROVIDER = "google";

    private static final String OAUTH_PROVIDER_NAME = "Google";

    private final GoogleService googleService;

    public GoogleOAuthHandler(GoogleService googleService) {
        this.googleService = googleService;
    }

    public URL getRedirectUrl(String state, String returnUrl) {
        return googleService.getRedirectUrl(state, returnUrl);
    }


    @Override
    public String getProviderName() {
        return OAUTH_PROVIDER_NAME;
    }


    @Override
    public OAuthTokens validate(String code, String redirectUri) {
        try {
            final GoogleTokenResponse response = googleService.getTokenResponse(code, redirectUri);

            if (response.isEmpty()) {
                throw new UserErrorException("Could not authenticate with Google");
            }

            OAuthTokens out = new OAuthTokens();
            out.setProvider(OAUTH_PROVIDER);
            out.setValid(true);
            out.setAccessToken(response.getAccessToken());
            out.setRefreshToken(response.getRefreshToken());
            out.setExpiresInSeconds(response.getExpiresInSeconds());
            out.setScope(response.getScope());

            final Person user = googleService.getUser(out);

            for(Person.Emails email : user.getEmails()) {
                if ("account".equalsIgnoreCase(email.getType())) {
                    out.setEmail(email.getValue());
                }
            }

            if (StringUtils.isBlank(user.getDisplayName())) {
                out.setName(out.getEmail());
            } else {
                out.setName(user.getDisplayName());
            }

            return out;
        } catch(GoogleJsonResponseException e) {
            throw new ResponseStatusException(HttpStatus.valueOf(e.getStatusCode()), e.getDetails().getMessage());
        } catch (IOException e) {
            throw new UserErrorException("Error occurred while authenticating with Google", e);
        }
    }


}