How to avoid the error "oauth2: server response missing access_token"




I’m trying to configure [auth.generic_oauth] and then write java code to login Grafana, but I got a error prompt from grafana.log, it said “t=2021-03-21T14:22:22+0800 lvl=eror msg=login.OAuthLogin(NewTransportWithCode) logger=context userId=0 orgId=0 uname= error=“oauth2: server response missing access_token””

===============================================================
this is [auth.generic_oauth] part I configured in defaults.ini:

[auth.generic_oauth]
name = OAuth
enabled = true
allow_sign_up = true
client_id = clientId
client_secret = clientSecret
scopes = user:email
email_attribute_name = email:primary
email_attribute_path =
role_attribute_path =
auth_url = http://localhost:8082/oauthserver/responseCode
token_url = http://localhost:8082/oauthserver/responseAccessToken
api_url = http://localhost:8082/oauthserver/userInfo

===============================================================
I entered Grafana login page and clicked “Sign in with OAuth” button, The auth_url was called successfully and then token_url is also called without any exception, but grafana showed "error=“oauth2: server response missing access_token” in log, so it can’t go to api_url, this is the code for token_url:

package edu.ynmd.cms;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.oltu.oauth2.as.issuer.MD5Generator;
import org.apache.oltu.oauth2.as.issuer.OAuthIssuer;
import org.apache.oltu.oauth2.as.issuer.OAuthIssuerImpl;
import org.apache.oltu.oauth2.as.request.OAuthTokenRequest;
import org.apache.oltu.oauth2.as.response.OAuthASResponse;
import org.apache.oltu.oauth2.common.OAuth;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.OAuthResponse;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class AccessTokenController {

@RequestMapping(value="/responseAccessToken", method = RequestMethod.POST)
public HttpEntity token(HttpServletRequest request) {
	OAuthIssuer oauthIssuerImpl = null;
	OAuthResponse response = null;
	
	try {
		OAuthTokenRequest oauthRequest = new OAuthTokenRequest(request);
		
		String authCode = oauthRequest.getParam(OAuth.OAUTH_CODE);
		String clientSecret = oauthRequest.getClientSecret();
		System.out.println("........authCode = " + authCode);
		System.out.println("........clientSecret = " + clientSecret);
		
		if(clientSecret != null || clientSecret != "") {
			oauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());
			final String accessToken = oauthIssuerImpl.accessToken();
			System.out.println("........generate accessToken = " + accessToken);
			
			response = OAuthASResponse
					.tokenResponse(HttpServletResponse.SC_OK)
					.setAccessToken(accessToken)
					.setTokenType("SSO")
					.setRefreshToken(authCode)
					.setExpiresIn("60000")
					.buildJSONMessage();
		}
		
		System.out.println("........response.getBody() = " + response.getBody());
		ResponseEntity entity = new ResponseEntity(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));
		System.out.println("........entity.toString() = " + entity.toString());
		return entity;
	} catch (OAuthSystemException e) {
		e.printStackTrace();
	} catch (OAuthProblemException e) {
		e.printStackTrace();
	}

	return null;
}

}

===============================================================

The following information was shown in Eclipse console:

…authCode = authorizationCode
…clientSecret = clientSecret
…generate accessToken = 60acf87776bda95357c7564e21e0b69b
…response.getBody() = {“access_token”:“60acf87776bda95357c7564e21e0b69b”,“refresh_token”:“authorizationCode”,“token_type”:“SSO”,“expires_in”:60000}
…entity.toString() = <200 OK OK,{“access_token”:“60acf87776bda95357c7564e21e0b69b”,“refresh_token”:“authorizationCode”,“token_type”:“SSO”,“expires_in”:60000},[]>
…authCode = authorizationCode
…clientSecret = clientSecret
…generate accessToken = aa5eeab46712594b427b7fb8234ebbe5
…response.getBody() = {“access_token”:“aa5eeab46712594b427b7fb8234ebbe5”,“refresh_token”:“authorizationCode”,“token_type”:“SSO”,“expires_in”:60000}
…entity.toString() = <200 OK OK,{“access_token”:“aa5eeab46712594b427b7fb8234ebbe5”,“refresh_token”:“authorizationCode”,“token_type”:“SSO”,“expires_in”:60000},[]>

===============================================================

From the log I’ve returned the access_token to Grafana, why log always give error=“oauth2: server response missing access_token” in log?

I also tried to directly return response.getBody() as a json string instead of HttpEntity object, but still faied.

So What object should I return to Grafana in this method?

You can find/debug it in the source code of used lib: