java - Opensaml- HTTPPostEncoder encoder.encode() - 发送响应和重定向
问题描述
我已经编写了一种将 SAML 响应发送到 ACS url 并将用户重定向到 SP 的方法。方法是:
public static void sendPostMessage(HttpServletResponse response, SAMLObject message, String url, String relayState) throws OpenSAMLException {
logger.info("Starting to post SAML Response...");
MessageContext<SAMLObject> context = new MessageContext();
context.setMessage(message);
Endpoint endpoint = OpenSAMLUtils.createSAMLObject(AssertionConsumerService.class);
endpoint.setLocation(url);
SAMLPeerEntityContext peerEntityContext = context.getSubcontext(SAMLPeerEntityContext.class, true);
SAMLEndpointContext endpointContext = peerEntityContext.getSubcontext(SAMLEndpointContext.class, true);
endpointContext.setEndpoint(endpoint);
SAMLBindingContext bindingContext = context.getSubcontext(SAMLBindingContext.class, true);
bindingContext.setRelayState(relayState);
HTTPPostEncoder encoder = new HTTPPostEncoder();
encoder.setVelocityEngine(getVelocityEngine());
encoder.setMessageContext(context);
encoder.setHttpServletResponse(response);
try {
encoder.initialize();
} catch (ComponentInitializationException e) {
throw new RuntimeException(e);
}
try {
encoder.encode(); //POST the message and redirect
} catch (MessageEncodingException e) {
throw new RuntimeException(e);
}
logger.info("SAML response posted successfully...");
}
我在两个实例中调用此方法
1)
@POST
@Consumes("application/x-www-form-urlencoded")
public javax.ws.rs.core.Response doSSO(@FormParam("SAMLRequest") String encodedSAMLRequest,
@FormParam("RelayState") String relayState,
@Context HttpServletResponse httpServletResponse,
@CookieParam(USERNAME_COOKIE) String username) throws OpenSAMLException, SAMLTokenGenerationException, URISyntaxException, UnsupportedEncodingException, ServletException {
if (username != null) {
logger.info("User {} is already logged in.", username);
//build the SAML response
Object requestXmlObj = SAMLMessageHandler.getAuthnRequestSamlObject(encodedSAMLRequest);
AuthnRequest authnRequest = (AuthnRequest) requestXmlObj;
Response response = SAMLMessageHandler.buildSamlResponse(authnRequest, username);
SAMLMessageHandler.sendPostMessage
(httpServletResponse, response, authnRequest.getAssertionConsumerServiceURL(), relayState); //**sendPostMessage**
return javax.ws.rs.core.Response.ok().build();
} else {
NewCookie samlReqCookie = new NewCookie(SAMLREQ_COOKIE, encodedSAMLRequest, "/", null, null, MAX_AGE, false, true);
NewCookie relayStateCookie = new NewCookie(RELAYSTATE_COOKIE, relayState, "/", null, null, MAX_AGE, false, true);
return javax.ws.rs.core.Response.seeOther(URI.create("/portal/login"))
.cookie(samlReqCookie, relayStateCookie)
.build();
}
}
@Path("/login")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response login(String login,
@CookieParam(SAMLREQ_COOKIE) Cookie encodedAuthnReq,
@CookieParam(RELAYSTATE_COOKIE) Cookie relayState,
@Context HttpServletResponse httpServletResponse)
throws IOException, OpenSAMLException, SAMLTokenGenerationException, URISyntaxException {
Map<String, String> loginMap = objectMapper.readValue(login, new TypeReference<HashMap<String, String>>() {
});
if (encodedAuthnReq != null) {
//build the SAML response
Object requestXmlObj = SAMLMessageHandler.getAuthnRequestSamlObject(encodedAuthnReq.getValue());
AuthnRequest authnRequest = (AuthnRequest) requestXmlObj;
org.opensaml.saml.saml2.core.Response response =
SAMLMessageHandler.buildSamlResponse(authnRequest, loginMap.get("username"));
SAMLMessageHandler.sendPostMessage
(httpServletResponse, response, authnRequest.getAssertionConsumerServiceURL(), relayState.getValue()); //**sendPostMessage**
return javax.ws.rs.core.Response.ok().build();
} else {
return Response.seeOther(URI.create("/portal/login-success"))
.cookie(new NewCookie(USERNAME_COOKIE, loginMap.get("username"), "/", null, null, MAX_AGE, false, true))
.build();
}
}
虽然它在第一种情况下按预期工作(能够发布消息并将用户重定向到 SP 页面),但在第二种情况下,不会发生 POST 和重定向。我尝试调试代码,但找不到任何东西。
注意-我在最后一次调用时使用 OpenSAML3 库和 encoder.encode() (opensaml-saml-impl-3.4.6.jar):
Writer out = new OutputStreamWriter(response.getOutputStream(), "UTF-8");
this.velocityEngine.mergeTemplate(this.velocityTemplateId, "UTF-8", context, out);
out.flush();
解决方案
推荐阅读
- php - 尝试一次向 Steam 商店发出大约 1500 个请求
- python-3.x - Python:使用登录的 Windows 用户登录网站
- java - 处理缓慢的构建时间(Gradle)
- python - 从每行具有多个 macthe 的条件创建列
- jupyter-notebook - jupyter notebook seaborn load_dataset https错误:找不到404
- java - 对 Java 集执行 get 操作
- python - 包含单引号和双引号的 Python 子进程参数
- javascript - 对象作为 React 子级无效(找到:[object Promise])。如果您打算渲染一组子项,请改用数组。(NEXT JS)
- python - 创建字符串中单词的字典,按出现次数排序,仅显示包含 4 个或更多字母的单词
- java - 如何在 JavaFX Swingnode 中调用 HSQLDB DatabaseManager Swing 应用程序?