added cliend_id and clent_secret parameter passed as Basic Authorization in header to make it oauth2 compliant
git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portal/oauth@178642 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
841a078d43
commit
4f2d348682
|
@ -0,0 +1,23 @@
|
|||
package org.gcube.portal.oauth;
|
||||
|
||||
public class CredentialsBean {
|
||||
|
||||
private String clientId;
|
||||
private String clientSecret;
|
||||
|
||||
public CredentialsBean(String clientId, String clientSecret) {
|
||||
super();
|
||||
this.clientId = clientId;
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public String getClientSecret() {
|
||||
return clientSecret;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -2,19 +2,23 @@ package org.gcube.portal.oauth;
|
|||
|
||||
import static org.gcube.common.authorization.client.Constants.authorizationService;
|
||||
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.FormParam;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
import org.gcube.common.authorization.library.ClientType;
|
||||
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
|
||||
|
@ -26,6 +30,7 @@ import org.gcube.portal.oauth.cache.CacheCleaner;
|
|||
import org.gcube.portal.oauth.input.PushCodeBean;
|
||||
import org.gcube.portal.oauth.output.AccessTokenBeanResponse;
|
||||
import org.gcube.portal.oauth.output.AccessTokenErrorResponse;
|
||||
import org.gcube.smartgears.Constants;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
|
@ -36,6 +41,9 @@ public class OauthService {
|
|||
public static final String OAUTH_TOKEN_GET_METHOD_NAME_REQUEST = "access-token";
|
||||
private static final String GRANT_TYPE_VALUE = "authorization_code";
|
||||
|
||||
private static final String AUTHORIZATION_HEADER = "Authorization";
|
||||
|
||||
|
||||
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(OauthService.class);
|
||||
|
||||
/**
|
||||
|
@ -158,17 +166,29 @@ public class OauthService {
|
|||
@FormParam("client_secret") String clientSecret, // i.e., application token
|
||||
@FormParam("redirect_uri") String redirectUri,
|
||||
@FormParam("code") String code,
|
||||
@FormParam("grant_type") String grantType // it must always be equal to "authorization_code"
|
||||
@FormParam("grant_type") String grantType, // it must always be equal to "authorization_code"
|
||||
@Context HttpServletRequest request
|
||||
){
|
||||
|
||||
Status status = Status.BAD_REQUEST;
|
||||
logger.info("Request to exchange code for token");
|
||||
logger.info("Params are client_id = " + clientId + ", client_secret = " + clientSecret +
|
||||
"*******************"+ ", redirect_uri = " +redirectUri + ", code = " + code + "*******************" + ", grant_type = " + grantType);
|
||||
|
||||
|
||||
|
||||
try{
|
||||
CredentialsBean credentials = new CredentialsBean(clientId, clientSecret);
|
||||
|
||||
if (clientId == null)
|
||||
credentials = getCredentialFromBasicAuthorization(request);
|
||||
else if (request.getHeader(AUTHORIZATION_HEADER)!=null)
|
||||
throw new Exception("he client MUST NOT use more than one authentication method");
|
||||
|
||||
logger.info("Params are client_id = " + credentials.getClientId() + ", client_secret = " + credentials.getClientSecret() +
|
||||
"*******************"+ ", redirect_uri = " +redirectUri + ", code = " + code + "*******************" + ", grant_type = " + grantType);
|
||||
|
||||
// check if something is missing
|
||||
String errorMessage = checkRequest(clientId, clientSecret, redirectUri, code, grantType);
|
||||
String errorMessage = checkRequest(credentials, redirectUri, code, grantType, request);
|
||||
|
||||
if(errorMessage != null){
|
||||
logger.error("The request fails because of " + errorMessage);
|
||||
return Response.status(status).entity(new AccessTokenErrorResponse(errorMessage, null)).build();
|
||||
|
@ -186,6 +206,18 @@ public class OauthService {
|
|||
}
|
||||
}
|
||||
|
||||
private CredentialsBean getCredentialFromBasicAuthorization(HttpServletRequest request) {
|
||||
String basicAuthorization = request.getHeader(AUTHORIZATION_HEADER);
|
||||
String base64Credentials = basicAuthorization.substring("Basic".length()).trim();
|
||||
String credentials = new String(DatatypeConverter.parseBase64Binary(base64Credentials));
|
||||
// credentials = username:password
|
||||
String[] splitCreds = credentials.split(":");
|
||||
String clientId = URLDecoder.decode(splitCreds[0]);
|
||||
String clientSecret = URLDecoder.decode(splitCreds[1]);
|
||||
return new CredentialsBean(clientId, clientSecret);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check request parameters
|
||||
* @param clientId
|
||||
|
@ -195,19 +227,19 @@ public class OauthService {
|
|||
* @param grantType
|
||||
* @return see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
private String checkRequest(String clientId, String clientSecret,
|
||||
String redirectUri, String code, String grantType) {
|
||||
private String checkRequest(CredentialsBean credentials,
|
||||
String redirectUri, String code, String grantType, HttpServletRequest request) {
|
||||
try{
|
||||
if(clientId == null || clientSecret == null || redirectUri == null || code == null || grantType == null)
|
||||
if(credentials.getClientId() == null || credentials.getClientSecret() == null || redirectUri == null || code == null || grantType == null )
|
||||
return "invalid_request";
|
||||
if(clientId.isEmpty() || clientSecret.isEmpty() || redirectUri.isEmpty() || code.isEmpty() || grantType.isEmpty())
|
||||
if(credentials.getClientId().isEmpty() || credentials.getClientSecret().isEmpty() || redirectUri.isEmpty() || code.isEmpty() || grantType.isEmpty())
|
||||
return "invalid_request";
|
||||
if(!checkIsapplicationTokenType(authorizationService().get(clientSecret).getClientInfo().getType())) // it is not an app token or it is not a token
|
||||
if(!checkIsapplicationTokenType(authorizationService().get(credentials.getClientSecret()).getClientInfo().getType())) // it is not an app token or it is not a token
|
||||
return "invalid_client";
|
||||
if(!entries.containsKey(code) || CacheBean.isExpired(entries.get(code)))
|
||||
return "invalid_grant";
|
||||
CacheBean entry = entries.get(code);
|
||||
if(!entry.getRedirectUri().equals(redirectUri) || !entry.getClientId().equals(clientId))
|
||||
if(!entry.getRedirectUri().equals(redirectUri) || !entry.getClientId().equals(credentials.getClientId()))
|
||||
return "invalid_grant";
|
||||
if(!grantType.equals(GRANT_TYPE_VALUE))
|
||||
return "unsupported_grant_type";
|
||||
|
|
Loading…
Reference in New Issue