org.wso2.carbon.identity.oauth.ui.endpoints.token.OAuth2TokenEndpoint.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.carbon.identity.oauth.ui.endpoints.token.OAuth2TokenEndpoint.java

Source

/*
*Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
*WSO2 Inc. licenses this file to you under the Apache License,
*Version 2.0 (the "License"); you may not use this file except
*in compliance with the License.
*You may obtain a copy of the License at
*
*http://www.apache.org/licenses/LICENSE-2.0
*
*Unless required by applicable law or agreed to in writing,
*software distributed under the License is distributed on an
*"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
*KIND, either express or implied.  See the License for the
*specific language governing permissions and limitations
*under the License.
*/

package org.wso2.carbon.identity.oauth.ui.endpoints.token;

import org.apache.amber.oauth2.as.request.OAuthTokenRequest;
import org.apache.amber.oauth2.as.response.OAuthASResponse;
import org.apache.amber.oauth2.common.OAuth;
import org.apache.amber.oauth2.common.exception.OAuthProblemException;
import org.apache.amber.oauth2.common.exception.OAuthSystemException;
import org.apache.amber.oauth2.common.message.OAuthResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.identity.oauth.common.OAuth2ErrorCodes;
import org.wso2.carbon.identity.oauth.ui.OAuthClientException;
import org.wso2.carbon.identity.oauth.ui.OAuthConstants;
import org.wso2.carbon.identity.oauth.ui.util.OAuthUIUtil;
import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2AccessTokenRespDTO;
import org.wso2.carbon.identity.oauth2.stub.types.ResponseHeader;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
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.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;

import java.util.Enumeration;

@Path("/")
public class OAuth2TokenEndpoint {

    private static Log log = LogFactory.getLog(OAuth2TokenEndpoint.class);

    @POST
    @Path("/")
    @Consumes("application/x-www-form-urlencoded")
    @Produces("application/json")
    public Response issueAccessToken(@Context HttpServletRequest request, MultivaluedMap<String, String> paramMap)
            throws OAuthSystemException {

        HttpServletRequestWrapper httpRequest = new OAuthRequestWrapper(request, paramMap);

        if (log.isDebugEnabled()) {
            logAccessTokenRequest(httpRequest);
        }

        // extract the basic auth credentials if present in the request and use for authentication.
        boolean basicAuthUsed = false;
        if (request.getHeader(OAuthConstants.HTTP_REQ_HEADER_AUTHZ) != null) {
            try {
                String[] clientCredentials = OAuthUIUtil
                        .extractCredentialsFromAuthzHeader(request.getHeader(OAuthConstants.HTTP_REQ_HEADER_AUTHZ));

                // If the client has included client credentials as request parameters, then it is
                // not permitted as per the specification. sending invalid_client error back.
                if (paramMap.containsKey(OAuth.OAUTH_CLIENT_ID)
                        && paramMap.containsKey(OAuth.OAUTH_CLIENT_SECRET)) {
                    return handleBasicAuthFailure();
                }

                // add the credentials available in Authorization to the parameter map
                paramMap.add(OAuth.OAUTH_CLIENT_ID, clientCredentials[0]);
                paramMap.add(OAuth.OAUTH_CLIENT_SECRET, clientCredentials[1]);

                // keep track of the authentication mode : required for sending back auth. failure errors
                basicAuthUsed = true;

                log.debug("HTTP Authorization Header is available which will take precedence "
                        + "over the client credentials available as request parameters.");

            } catch (OAuthClientException e) {
                // malformed credential string is considered as an auth failure.
                return handleBasicAuthFailure();
            }
        }

        try {
            OAuthTokenRequest oauthRequest = new OAuthTokenRequest(httpRequest);
            OAuth2TokenClient tokenClient = new OAuth2TokenClient();
            // exchange the access token for the authorization grant.
            OAuth2AccessTokenRespDTO oauth2AccessTokenResp = tokenClient.getAccessToken(oauthRequest);
            // if there BE has returned an error
            if (oauth2AccessTokenResp.getError()) {
                // if the client has used Basic Auth and if there is an auth failure, HTTP 401 Status
                // Code should be sent back to the client.
                if (basicAuthUsed && OAuth2ErrorCodes.INVALID_CLIENT.equals(oauth2AccessTokenResp.getErrorCode())) {
                    return handleBasicAuthFailure();
                }
                // Otherwise send back HTTP 400 Status Code
                OAuthResponse response = OAuthASResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
                        .setError(oauth2AccessTokenResp.getErrorCode())
                        .setErrorDescription(oauth2AccessTokenResp.getErrorMsg()).buildJSONMessage();
                return Response.status(response.getResponseStatus()).entity(response.getBody()).build();
            }

            else {
                OAuthResponse response = OAuthASResponse.tokenResponse(HttpServletResponse.SC_OK)
                        .setAccessToken(oauth2AccessTokenResp.getAccessToken())
                        .setRefreshToken(oauth2AccessTokenResp.getRefreshToken())
                        .setExpiresIn(Long.toString(oauth2AccessTokenResp.getExpiresIn())).setTokenType("bearer")
                        .buildJSONMessage();
                ResponseHeader[] headers = oauth2AccessTokenResp.getRespHeaders();

                ResponseBuilder respBuilder = Response.status(response.getResponseStatus())
                        .header(OAuthConstants.HTTP_RESP_HEADER_CACHE_CONTROL,
                                OAuthConstants.HTTP_RESP_HEADER_VAL_CACHE_CONTROL_NO_STORE)
                        .header(OAuthConstants.HTTP_RESP_HEADER_PRAGMA,
                                OAuthConstants.HTTP_RESP_HEADER_VAL_PRAGMA_NO_CACHE);

                if (headers != null && headers.length > 0) {
                    for (int i = 0; i < headers.length; i++) {
                        if (headers[i] != null) {
                            respBuilder.header(headers[i].getKey(), headers[i].getValue());
                        }
                    }
                }

                return respBuilder.entity(response.getBody()).build();
            }

        } catch (OAuthProblemException e) {
            log.debug(e.getError());
            OAuthResponse res = OAuthASResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST).error(e)
                    .buildJSONMessage();
            return Response.status(res.getResponseStatus()).entity(res.getBody()).build();
        } catch (OAuthClientException e) {
            OAuthResponse response = OAuthASResponse.errorResponse(HttpServletResponse.SC_INTERNAL_SERVER_ERROR)
                    .setError(OAuth2ErrorCodes.SERVER_ERROR).setErrorDescription(e.getMessage()).buildJSONMessage();
            return Response.status(response.getResponseStatus()).entity(response.getBody()).build();
        }

    }

    private Response handleBasicAuthFailure() throws OAuthSystemException {
        OAuthResponse response = OAuthASResponse.errorResponse(HttpServletResponse.SC_UNAUTHORIZED)
                .setError(OAuth2ErrorCodes.INVALID_CLIENT).setErrorDescription("Client Authentication was failed.")
                .buildJSONMessage();
        return Response.status(response.getResponseStatus())
                .header(OAuthConstants.HTTP_RESP_HEADER_AUTHENTICATE, OAuthUIUtil.getRealmInfo())
                .entity(response.getBody()).build();
    }

    private void logAccessTokenRequest(HttpServletRequest request) {
        log.debug("Received a request : " + request.getRequestURI());
        // log the headers.
        log.debug("----------logging request headers.----------");
        Enumeration headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String headerName = (String) headerNames.nextElement();
            Enumeration headers = request.getHeaders(headerName);
            while (headers.hasMoreElements()) {
                log.debug(headerName + " : " + headers.nextElement());
            }
        }
        // log the parameters.
        log.debug("----------logging request parameters.----------");
        log.debug(OAuth.OAUTH_GRANT_TYPE + " - " + request.getParameter(OAuth.OAUTH_GRANT_TYPE));
        log.debug(OAuth.OAUTH_CLIENT_ID + " - " + request.getParameter(OAuth.OAUTH_CLIENT_ID));
        log.debug(OAuth.OAUTH_CODE + " - " + request.getParameter(OAuth.OAUTH_CODE));
        log.debug(OAuth.OAUTH_REDIRECT_URI + " - " + request.getParameter(OAuth.OAUTH_REDIRECT_URI));
    }

}