REST TO REST using WSO2 ESB
Asked Answered
I

3

10

I have a REST service deployed on a server and would like to expose it (proxy it) through WSO2 ESB and use the ESB security to secure the access to the service (probably HTTP BASIC authentication that looks by username and password in the ESB user database). I cannot find a good documentation describing how to do it. Could this be done using WSO2 ESB and how?

Ingulf answered 12/9, 2012 at 14:51 Comment(0)
S
4

You can refer this blog post for creating proxy for REST service.To secure the service there are articles on how to secure services. this is one such.

I am adding a new link for securing REST services.

Sporophyll answered 12/9, 2012 at 15:12 Comment(3)
Thank you for the answer. The blog post about security is describing UsernameToken security profile which is for WS but not for REST services.Ingulf
I hope the new link for "Fine-Grained Authorization to RESTful Services with XACML" would give you some helpful hints.Sporophyll
Will the example from the new link work with usernameToken security or I have to use XACML?Mercator
O
1

You can use REST API for this purpose, with wso2 ESB 4.0.2 onward it ships with REST API where you can easily invoke them, you can get a comprehensive understanding on how the REST API involoves in WSO2 ESB ref REST API Article

Orectic answered 20/9, 2012 at 8:22 Comment(0)
C
1

For http basic Authenticathion with users form wso2-esb I use these sequence.

<sequence xmlns="http://ws.apache.org/ns/synapse" name="ValidacionHttpBasica">
<property name="isAuthorized" value="0" scope="default" type="STRING"/>
<class name="org.wso2.security.HttpBasicAuthOpMediator"/>
<switch source="get-property('isAuthorized')">
    <case regex="0">
        <property name="HTTP_SC" value="401" scope="axis2" type="STRING"/>
        <makefault version="soap11">
            <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Server"/>
            <reason value="Not Authorized"/>
            <role/>
        </makefault>
        <respond/>
    </case>
    <default/>
</switch>
</sequence>

The code for org.wso2.security.HttpBasicAuthOpMediator (wso2-esb 4.9.0)

package org.wso2.security;

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

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import org.apache.synapse.MessageContext;
import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.apache.synapse.mediators.AbstractMediator;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.user.api.UserStoreException;

public class HttpBasicAuthOpMediator extends AbstractMediator {

private static final Logger LOGGER = Logger.getLogger(HttpBasicAuthOpMediator.class);


/* (non-Javadoc)
 * @see org.apache.synapse.Mediator#mediate(org.apache.synapse.MessageContext)
 */
public boolean mediate(MessageContext msgctx) {

    boolean isOK = true;

    try {

        //trazearDatos(msgctx);
        org.apache.axis2.context.MessageContext axis2MessageContext = ((Axis2MessageContext) msgctx)
                .getAxis2MessageContext();
        Map<String,String> mHeaders = (Map<String,String>)axis2MessageContext.getProperty("TRANSPORT_HEADERS");


        // 1 - Validacion de cabeceras de seguridad
        String securityHeader = mHeaders.get("Authorization");
        if ( securityHeader==null || securityHeader.trim().length()<7 ) {
            throw new RuntimeException ("Request sin cabecera de Autorizacion");
        }

        // 2 - Validacion de usuario-contrasenya
        String user = validarUsuario(securityHeader);

        // 3 - validacion de operacion asociada a un rol
        if (msgctx.getProperty("SECURITY_OPERATION")!=null && msgctx.getProperty("SECURITY_OPERATION").toString().equalsIgnoreCase("1")) {
            validarOperacion(user,  mHeaders.get("SOAPAction"), msgctx);
        }

        // todo ha ido bien, esta autorizado
        msgctx.setProperty("isAuthorized", "1");

    } catch (Exception e) {
        LOGGER.info("ERROR VALIDACION USUARIO ..." + e.getMessage() );
        //isOK = false;
    }

    return isOK;
}



/**
 * Comprueba que el usuario tiene los roles asociados a la operacion.
 * Si el usuario no tiene los roles, lanza un runtimeExcpetion
 * @param operacion, que se obtiene del soapAction de la cabecera http
 * @param messageContext 
 */
private void validarOperacion(String user, String operacion, MessageContext messageContext) {

    operacion = operacion.replaceAll("\"", "");
    operacion = operacion.replaceAll("'", "");
    //obtener los roles asociados a la operacion
    if ( messageContext.getProperty("SECURITY_OPERATION_" + operacion)!= null ) {
        boolean existeRol = false;
        try {
            String[] rolesOperation =  messageContext.getProperty("SECURITY_OPERATION_" + operacion).toString().split(",");
            Map<String,String> mRolesUser = toMap( CarbonContext.getThreadLocalCarbonContext().getUserRealm().getUserStoreManager().getRoleListOfUser(user) );

            for (String rol : rolesOperation) {
                if (mRolesUser.containsKey(rol)) {
                    existeRol = true;
                    break;
                }
            }
            if (!existeRol) {
                throw new RuntimeException("Usuario sin role para ejecutar operacion");
            }
        } catch (Exception e) {
            throw new RuntimeException("ValidaRoleOperacion:" + e.getMessage() );
        }
    }


}



/**
 * Valida si la cabecera contiene un usuario-contrsenya valido en wso2.
 * Si no lo encuentra lanza un RuntimeExpception.
 * @param cabecera http-header que contiene el usuario-contrsenya en base64.
 */
private String validarUsuario(String cabecera) {

    String credentials = cabecera.substring(6).trim();
    String decodedCredentials = new String(new Base64().decode(credentials.getBytes()));
    String userName = decodedCredentials.split(":")[0];
    String password = decodedCredentials.split(":")[1];

    //CarbonContext ctx = CarbonContext.getCurrentContext();
    CarbonContext ctx = CarbonContext.getThreadLocalCarbonContext();

    try {
        if ( !ctx.getUserRealm().getUserStoreManager().authenticate(userName, password) )  {
            throw new RuntimeException("Usuario-contrasenya incorrecto");
        }
    } catch (UserStoreException e) {
        throw new RuntimeException("UserStoreException:" + e.getMessage() );
    }
    return userName;
}



public void trazearDatos(MessageContext msgctx ) {

    try {

    System.out.println("....INICIO_TRAZEO DATOS...............");
    // CABECERAS HTTP para pbtener operacion, user-password. Es un Map<String, String>
    if ( msgctx.getProperty("TRANSPORT_HEADERS") != null ) {
        Map<String,String> mHeaders = (Map<String,String>)msgctx.getProperty("TRANSPORT_HEADERS");
        for (String key:mHeaders.keySet() ) {
            System.out.println("HEADER_HTTP..." + key + "==" + mHeaders.get(key) );
        }
    } else {
        System.out.println("Es nulo TRANSJPPORT_HEADER, casteamos");
        org.apache.axis2.context.MessageContext axis2MessageContext = ((Axis2MessageContext) msgctx)
                .getAxis2MessageContext();
        Map<String,String> mHeaders = (Map<String,String>)axis2MessageContext.getProperty("TRANSPORT_HEADERS");
        for (String key:mHeaders.keySet() ) {
            System.out.println("(cast) HEADER_HTTP..." + key + "==" + mHeaders.get(key) );
        }
    }

    // PROPERTIES DEL MESSAGE_CONTEXT
    String keyMC;
    for (Object keyObject : msgctx.getPropertyKeySet() ) {
        keyMC = (String)keyObject;
        System.out.println("PROPERTIES_CONTEXT..." + keyMC + "==" + msgctx.getProperty(keyMC));
    }


    // pintamos los roles que tiene asignado el usuario
    CarbonContext carbonctx = CarbonContext.getThreadLocalCarbonContext();

    String[] roles = carbonctx.getUserRealm().getUserStoreManager().getRoleNames();
    for(String role:roles) {
        System.out.println("ROLE_WSO2..." + role);
    }
    System.out.println("....FIN_TRAZEO DATOS...............");

    } catch (Exception e) {
        LOGGER.debug("ERROR TRAZEANDO DATOS VALIDACION USER:" + e.getMessage() );
    }

}

private Map<String,String> toMap(String[] array) {
    Map<String,String> mapa = new HashMap<String,String>();
    if ( array!=null) {
        for (String val : array) {
            mapa.put(val, val);
        }
    }
    return mapa;
} 

}

Crossopterygian answered 14/1, 2016 at 15:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.