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