Validador de elementos Java

improve this page | report issue

Visión general

IBM Mobile Foundation proporciona una biblioteca Java para imponer funciones de seguridad en recursos externos.
La biblioteca Java se proporciona como un archivo JAR (mfp-java-token-validator-8.0.0.jar).

Esta guía de aprendizaje muestra cómo proteger un Servlet Java simple, GetBalance, utilizando un ámbito (accessRestricted).

Requisitos previos:

Flujo

Añadir la dependencia de archivo de .jar

El archivo mfp-java-token-validator-8.0.0.jar está disponible como dependencia maven:

<dependency>
  <groupId>com.ibm.mfp</groupId>
  <artifactId>mfp-java-token-validator</artifactId>
  <version>8.0.0</version>
</dependency>

Creación de una instancia de TokenValidationManager

Para poder validar señales, cree la instancia TokenValidationManager.

TokenValidationManager(java.net.URI authorizationURI, java.lang.String clientId, java.lang.String clientSecret);
  • authorizationURI: el identificador universal de recursos (URI) del servidor de autorización, normalmente MobileFirst Server. Por ejemplo http://localhost:9080/mfp/api.
  • clientId: El ID de cliente confidencial que ha configurado en MobileFirst Operations Console.
  • clientSecret: El secreto de cliente confidencial que ha configurado en MobileFirst Operations Console.

La biblioteca expone una API que encapsula y simplifica la interacción con el punto final de introspección del servidor de autorización. Para obtener una referencia de API detallada, consulte la MobileFirst referencia de API del validador de señal Java.

Validación de credenciales

El método API validate ofrece al servidor de autorización la validación de la cabecera de autorización:

public TokenValidationResult validate(java.lang.String authorizationHeader, java.lang.String expectedScope);
  • authorizationHeader: El contenido de la cabecera HTTP Authorization, que es la señal de acceso. Por ejemplo, puede obtenerse a partir de HttpServletRequest (httpServletRequest.getHeader("Authorization")).
  • expectedScope: El ámbito para validar la señal, por ejemplo accessRestricted.

Puede consultar el objeto TokenValidationResult resultante para un error o para los datos de introspección válidos:

TokenValidationResult tokenValidationRes = validator.validate(authCredentials, expectedScope);
if (tokenValidationRes.getAuthenticationError() != null) {
    // Error
    AuthenticationError error = tokenValidationRes.getAuthenticationError();
    httpServletResponse.setStatus(error.getStatus());
    httpServletResponse.setHeader("WWW-Authenticate", error.getAuthenticateHeader());
} else if (tokenValidationRes.getIntrospectionData() != null) {
    // Success logic here
}

Datos de introspección

El objeto TokenIntrospectionData devuelto por getIntrospectionData() le proporciona información acerca del cliente como, por ejemplo, el nombre de usuario del usuario activo actual:

httpServletRequest.setAttribute("introspection-data", tokenValidationRes.getIntrospectionData());
TokenIntrospectionData introspectionData = (TokenIntrospectionData) request.getAttribute("introspection-data");
String username = introspectionData.getUsername();

Memoria caché

La clase TokenValidationManager tiene una memoria caché interna que copia en caché las señales y los datos de introspección. El propósito de la memoria caché es reducir la cantidad de introspecciones de señal realizadas en relación con el servidor de autorización, si se realiza una solicitud con la misma cabecera.

El tamaño de la memoria caché predeterminada es 50000 elementos. Después de alcanzar la capacidad, se elimina la señal más antigua.

El constructor de TokenValidationManager también acepta cacheSize (número de elementos de datos de introspección) para almacenar:

public TokenValidationManager(java.net.URI authorizationURI, java.lang.String clientId, java.lang.String clientSecret, long cacheSize);

Protección de un servlet Java simple

  1. Cree un servlet Java simple llamado GetBalance, que devuelve un valor no modificable:

    @WebServlet("/GetBalance")
    public class GetBalance extends HttpServlet {
     	private static final long serialVersionUID = 1L;
    
     	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     		//Return hardcoded value
     		response.getWriter().append("17364.9");
     	}
    
    }
    
  2. Cree una implementación javax.servlet.Filter, llamada JTVFilter, que validará la cabecera de autorización para un ámbito proporcionado:

    public class JTVFilter implements Filter {
    
     	public static final String AUTH_HEADER = "Authorization";
     	private static final String AUTHSERVER_URI = "http://localhost:9080/mfp/api"; //Set here your authorization server URI
     	private static final String CLIENT_ID = "jtv"; //Set here your confidential client ID
     	private static final String CLIENT_SECRET = "jtv"; //Set here your confidential client SECRET
    
     	private TokenValidationManager validator;
     	private FilterConfig filterConfig = null;
    
     	@Override
     	public void init(FilterConfig filterConfig) throws ServletException {
     		URI uri = null;
     		try {
     			uri = new URI(AUTHSERVER_URI);
     			validator = new TokenValidationManager(uri, CLIENT_ID, CLIENT_SECRET);
     			this.filterConfig = filterConfig;
     		} catch (Exception e1) {
     			System.out.println("Error reading introspection URI");
     		}
     	}
    
     	@Override
     	public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException {
     		String expectedScope = filterConfig.getInitParameter("scope");
     		HttpServletRequest httpServletRequest = (HttpServletRequest) req;
     		HttpServletResponse httpServletResponse = (HttpServletResponse) res;
    
     		String authCredentials = httpServletRequest.getHeader(AUTH_HEADER);
    
     		try {
     			TokenValidationResult tokenValidationRes = validator.validate(authCredentials, expectedScope);
     			if (tokenValidationRes.getAuthenticationError() != null) {
     				// Error
     				AuthenticationError error = tokenValidationRes.getAuthenticationError();
     				httpServletResponse.setStatus(error.getStatus());
     				httpServletResponse.setHeader("WWW-Authenticate", error.getAuthenticateHeader());
     			} else if (tokenValidationRes.getIntrospectionData() != null) {
     				// Success
     				httpServletRequest.setAttribute("introspection-data", tokenValidationRes.getIntrospectionData());
     				filterChain.doFilter(req, res);
     			}
     		} catch (TokenValidationException e) {
     			httpServletResponse.setStatus(500);
     		}
     	}
    
    }
    
  3. En el archivo web.xml del servlet, declare una instancia de JTVFilter y pase el ámbito accessRestricted como un parámetro:

    <filter>
       <filter-name>accessRestricted</filter-name>
       <filter-class>com.sample.JTVFilter</filter-class>
       <init-param>
         <param-name>scope</param-name>
         <param-value>accessRestricted</param-value>
       </init-param>
    </filter>
    

    Proteja el servlet con el filtro:

    <filter-mapping>
       <filter-name>accessRestricted</filter-name>
       <url-pattern>/GetBalance</url-pattern>
    </filter-mapping>
    

Aplicación de ejemplo

Puede desplegar el proyecto en los servidores de aplicaciones soportados (Tomcat, el perfil completo de WebSphere Application Server y el perfil de WebSphere Application Server Liberty).
Descargue el servlet Java simple.

Uso de ejemplo

  1. Asegúrese de actualizar el cliente confidencial y los valores secretos en MobileFirst Operations Console.
  2. Despliegue alguna de las comprobaciones de seguridad: UserLogin o PinCodeAttempts.
  3. Registre la aplicación coincidente.
  4. Correlacione el ámbito accessRestricted en la comprobación de seguridad.
  5. Actualice la aplicación de cliente para crear WLResourceRequest en su URL de servlet.
Inclusive terminology note: The Mobile First Platform team is making changes to support the IBM® initiative to replace racially biased and other discriminatory language in our code and content with more inclusive language. While IBM values the use of inclusive language, terms that are outside of IBM's direct influence are sometimes required for the sake of maintaining user understanding. As other industry leaders join IBM in embracing the use of inclusive language, IBM will continue to update the documentation to reflect those changes.
Last modified on February 27, 2020