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);
authorizationHeader
:Authorization
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
-
创建名为
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"); } }
-
创建名为
JTVFilter
的javax.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); } } }
-
在 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。
样本用法
- 确保更新保密客户机和 MobileFirst Operations Console 中的密钥值。
- 部署安全性检查:UserLogin 或 PinCodeAttempts。
- 注册匹配应用程序。
- 将
accessRestricted
作用域映射到安全性检查。 - 更新客户机应用程序以针对 servlet URL 生成
WLResourceRequest
。