Java 令牌验证器

improve this page | report issue

概述

IBM Mobile Foundation 提供 Java 库以对外部资源实施安全功能。
Java 库是作为 JAR 文件 (mfp-java-token-validator-8.0.0.jar) 提供的。

本教程显示如何使用作用域 (accessRestricted) 来保护简单 Java Servlet GetBalance

先决条件:

流程

添加 .jar 文件依赖关系

mfp-java-token-validator-8.0.0.jar 文件可用作 maven 依赖关系

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

实例化 TokenValidationManager

为了能够验证令牌,请实例化 TokenValidationManager

TokenValidationManager(java.net.URI authorizationURI, java.lang.String clientId, java.lang.String clientSecret);
  • authorizationURI:授权服务器的 URI,通常为 MobileFirst Server。 例如,http://localhost:9080/mfp/api
  • clientId:在 MobileFirst Operations Console 中配置的保密客户机标识。
  • clientSecret:在 MobileFirst Operations Console 中配置的保密客户机密钥。

该库会公开一个 API,用于封装并简化与授权服务器的自省端点的交互。 有关详细 API 参考,请参阅 MobileFirst Java 令牌验证程序 API 参考

验证凭证

validate API 方法会要求授权服务器验证授权头:

public TokenValidationResult validate(java.lang.String authorizationHeader, java.lang.String expectedScope);
  • authorizationHeaderAuthorization HTTP 头的内容,这是访问令牌。 例如,可以从 HttpServletRequest (httpServletRequest.getHeader("Authorization")) 中获取。
  • expectedScope:用于验证令牌的作用域,例如,accessRestricted

您可以查询生成的 TokenValidationResult 对象以查找错误或有效的自省数据:

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
}

自省数据

getIntrospectionData() 返回的 TokenIntrospectionData 对象为您提供有关客户机的一些信息,例如,当前活动用户的用户名:

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

高速缓存

TokenValidationManager 类随附一个内部高速缓存,用于高速缓存令牌和自省数据。 高速缓存的目的是减少针对授权服务器完成的令牌自省总量(如果使用相同的头发出请求)。

缺省高速缓存大小为 50000 个项。 在到达此容量后,将除去最旧的令牌。

TokenValidationManager 的构造方法也可接受要存储的 cacheSize(自省数据项的数量):

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

保护简单 Java Servlet

  1. 创建名为 GetBalance 的简单 Java Servlet,这将返回硬编码值:

    @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. 创建名为 JTVFilterjavax.servlet.Filter 实现,这将针对指定作用域验证授权头:

    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. 在 servlet 的 web.xml 文件中,声明 JTVFilter 的实例,并传递 scopeaccessRestricted 作为参数:

    <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>
    

    然后,使用过滤器保护 servlet:

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

样本应用程序

您可以在受支持的应用程序服务器(Tomcat、WebSphere Application Server Full Profile 和 WebSphere Application Server Liberty Profile)上部署项目。
下载简单 Java servlet

样本用法

  1. 确保更新保密客户机和 MobileFirst Operations Console 中的密钥值。
  2. 部署安全性检查:UserLoginPinCodeAttempts
  3. 注册匹配应用程序。
  4. accessRestricted 作用域映射到安全性检查。
  5. 更新客户机应用程序以针对 servlet URL 生成 WLResourceRequest
Last modified on October 05, 2017