Author: owulff
Date: Mon Oct 1 18:44:14 2012
New Revision: 1392512
URL: http://svn.apache.org/viewvc?rev=1392512&view=rev
Log:
[FEDIZ-20] IDP should maintain authentication state
Modified:
cxf/fediz/trunk/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/IdpServlet.java
cxf/fediz/trunk/services/idp/src/main/webapp/WEB-INF/RPClaims.xml
cxf/fediz/trunk/services/idp/src/main/webapp/WEB-INF/web.xml
cxf/fediz/trunk/services/sts/src/main/webapp/WEB-INF/cxf-transport.xml
Modified:
cxf/fediz/trunk/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/IdpServlet.java
URL:
http://svn.apache.org/viewvc/cxf/fediz/trunk/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/IdpServlet.java?rev=1392512&r1=1392511&r2=1392512&view=diff
==============================================================================
---
cxf/fediz/trunk/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/IdpServlet.java
(original)
+++
cxf/fediz/trunk/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/IdpServlet.java
Mon Oct 1 18:44:14 2012
@@ -27,6 +27,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
import javax.xml.namespace.QName;
import org.w3c.dom.Element;
@@ -38,6 +39,7 @@ import org.apache.cxf.common.util.Base64
import org.apache.cxf.staxutils.W3CDOMStreamWriter;
import org.apache.cxf.ws.security.SecurityConstants;
import org.apache.cxf.ws.security.sts.provider.STSException;
+import org.apache.cxf.ws.security.tokenstore.SecurityToken;
import org.apache.cxf.ws.security.trust.STSUtils;
import org.apache.ws.security.WSConstants;
import org.slf4j.Logger;
@@ -45,7 +47,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
public class IdpServlet extends HttpServlet {
-
+
public static final String PARAM_ACTION = "wa";
public static final String ACTION_SIGNIN = "wsignin1.0";
@@ -64,6 +66,10 @@ public class IdpServlet extends HttpServ
public static final String SERVLET_PARAM_TOKENTYPE = "ws-trust-tokentype";
+ public static final String IDP_TOKEN = "idp-token";
+
+ public static final String IDP_USER = "idp-user";
+
private static final Logger LOG =
LoggerFactory.getLogger(IdpServlet.class);
@@ -84,15 +90,30 @@ public class IdpServlet extends HttpServ
throw new ServletException(
"Parameter 'sts.wsdl.service' not configured");
}
- if (getInitParameter("sts.wsdl.endpoint") == null) {
+ if (getInitParameter("sts.UT.wsdl.endpoint") == null) {
throw new ServletException(
- "Parameter 'sts.wsdl.endpoint' not configured");
+ "Parameter 'sts.UT.wsdl.endpoint' not configured");
}
+ if (getInitParameter("sts.RP.wsdl.endpoint") == null) {
+ throw new ServletException(
+ "Parameter 'sts.RP.wsdl.endpoint' not configured");
+ }
+ if (getInitParameter("sts.UT.uri") == null) {
+ throw new ServletException(
+ "Parameter 'sts.UT.uri' not configured");
+ }
+ if (getInitParameter("sts.RP.uri") == null) {
+ throw new ServletException(
+ "Parameter 'sts.RP.uri' not configured");
+ }
tokenType = getInitParameter(SERVLET_PARAM_TOKENTYPE);
if (tokenType != null && tokenType.length() > 0) {
LOG.info("Configured Tokentype: " + tokenType);
}
+ if (getInitParameter("token.internal.lifetime") != null) {
+ LOG.info("Configured token lifetime: " +
getInitParameter("token.internal.lifetime"));
+ }
}
@@ -100,10 +121,6 @@ public class IdpServlet extends HttpServ
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
- /*
- * if (request.getPathInfo().contains("jsp")) { return; }
- */
-
String action = request.getParameter(PARAM_ACTION);
String wtrealm = request.getParameter(PARAM_WTREALM);
String wctx = request.getParameter(PARAM_WCONTEXT);
@@ -127,24 +144,60 @@ public class IdpServlet extends HttpServ
"Parameter " + ACTION_SIGNIN + " missing");
return;
}
-
- String wresult = null;
- String auth = request.getHeader("Authorization");
- LOG.debug("Authorization header: " + auth);
- if (auth != null) {
- String username = null;
- String password = null;
-
- try {
- StringTokenizer st = new StringTokenizer(auth, " ");
- String authType = st.nextToken();
- String encoded = st.nextToken();
-
- if (authType.equalsIgnoreCase("basic")) {
-
+ boolean authenticationRequired = false;
+ SecurityToken idpToken = null;
+ HttpSession session = request.getSession(false);
+ if (session != null) {
+ idpToken = (SecurityToken)session.getAttribute(IDP_TOKEN);
+ String user = (String)session.getAttribute(IDP_USER);
+ if (idpToken == null) {
+ LOG.error("IDP token not found");
+
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ "IDP token not found");
+ return;
+ } else {
+ if (idpToken.isExpired()) {
+ LOG.info("IDP token of '" + user + "' expired. Require
authentication.");
+ authenticationRequired = idpToken.isExpired();
+ } else {
+ LOG.debug("Session found for '" + user + "'.");
+ }
+ }
+ } else {
+ authenticationRequired = true;
+ }
+
+ if (authenticationRequired) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Authentication required ...");
+ }
+ String auth = request.getHeader("Authorization");
+ LOG.debug("Authorization header: " + auth);
+
+ if (auth == null) {
+ // request authentication from browser
+ StringBuilder value = new StringBuilder(16);
+ value.append("Basic realm=\"IDP\"");
+ response.setHeader(AUTH_HEADER_NAME, value.toString());
+ response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+ return;
+ } else {
+ String username = null;
+ String password = null;
+
+ try {
+ StringTokenizer st = new StringTokenizer(auth, " ");
+ String authType = st.nextToken();
+ String encoded = st.nextToken();
+
+ if (!authType.equalsIgnoreCase("basic")) {
+
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid Authorization
header");
+ return;
+ }
+
String decoded = new String(
Base64Utility.decode(encoded));
-
+
int colon = decoded.indexOf(':');
if (colon < 0) {
username = decoded;
@@ -153,56 +206,63 @@ public class IdpServlet extends HttpServ
password = decoded.substring(colon + 1,
decoded.length());
}
- LOG.debug("Validating user [" + username
- + "] and password [" + password + "]");
-
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Validating user '" + username + "'...");
+ }
+
try {
- wresult = requestSecurityToken(username, password,
- wtrealm);
- request.setAttribute("fed." + PARAM_WRESULT,
-
StringEscapeUtils.escapeXml(wresult));
- if (wctx != null) {
- request.setAttribute("fed." + PARAM_WCONTEXT,
-
StringEscapeUtils.escapeXml(wctx));
- }
- if (wreply == null) {
- request.setAttribute("fed.action", wtrealm);
- } else {
- request.setAttribute("fed.action", wreply);
- }
+ idpToken = requestSecurityTokenForIDP(username,
password, "urn:fediz:idp");
+ session = request.getSession(true);
+ session.setAttribute(IDP_TOKEN, idpToken);
+ session.setAttribute(IDP_USER, username);
} catch (Exception ex) {
- LOG.info("Requesting security token failed", ex);
+ LOG.info("Requesting IDP security token failed",
ex);
response.sendError(HttpServletResponse.SC_FORBIDDEN,
- "Requesting security token failed");
+ "Requesting IDP security token failed");
return;
}
-
- LOG.debug("Forward to jsp...");
- //
request.getRequestDispatcher("WEB-INF/signinresponse.jsp").forward(request,
- // response);
- //
this.getServletContext().getRequestDispatcher("/WEB-INF/signinresponse.jsp").forward(request,
- // response);
-
this.getServletContext().getRequestDispatcher("/WEB-INF/signinresponse.jsp")
- .forward(request, response);
-
- } else {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST,
"Invalid Authorization header");
+ } catch (Exception ex) {
+ LOG.error("Invalid Authorization header", ex);
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST,
+ "Invalid Authorization header");
return;
}
- } catch (Exception ex) {
- LOG.error("Invalid Authorization header", ex);
- response.sendError(HttpServletResponse.SC_BAD_REQUEST,
- "Invalid Authorization header");
- return;
+
}
+ }
- } else {
- StringBuilder value = new StringBuilder(16);
- value.append("Basic realm=\"IDP\"");
- response.setHeader(AUTH_HEADER_NAME, value.toString());
- response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+
+ // Get token on-behalf-of the IDP token
+ String wresult = null;
+ String user = (String)session.getAttribute(IDP_USER);
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Requesting token on-behalf-of '" + user + "' for
relying party '" + wtrealm);
+ }
+
+ try {
+ wresult = requestSecurityTokenForRP(idpToken, wtrealm);
+ request.setAttribute("fed." + PARAM_WRESULT,
+ StringEscapeUtils.escapeXml(wresult));
+ if (wctx != null) {
+ request.setAttribute("fed." + PARAM_WCONTEXT,
+ StringEscapeUtils.escapeXml(wctx));
+ }
+ if (wreply == null) {
+ request.setAttribute("fed.action", wtrealm);
+ } else {
+ request.setAttribute("fed.action", wreply);
+ }
+ } catch (Exception ex) {
+ LOG.info("Requesting security token failed", ex);
+ response.sendError(HttpServletResponse.SC_FORBIDDEN,
+ "Requesting security token failed");
return;
}
+
+ LOG.debug("Forward to jsp...");
+
this.getServletContext().getRequestDispatcher("/WEB-INF/signinresponse.jsp")
+ .forward(request, response);
+
} else {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Parameter "
+ PARAM_ACTION + " with value " + action
@@ -210,9 +270,40 @@ public class IdpServlet extends HttpServ
return;
}
}
+
+ private SecurityToken requestSecurityTokenForIDP(String username, String
password, String appliesTo) throws Exception {
+ Bus bus = BusFactory.getDefaultBus();
+
+ IdpSTSClient sts = new IdpSTSClient(bus);
+ sts.setAddressingNamespace("http://www.w3.org/2005/08/addressing");
+ if (tokenType != null && tokenType.length() > 0) {
+ sts.setTokenType(tokenType);
+ } else {
+ sts.setTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
+ }
+
sts.setKeyType("http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer");
+
+ sts.setWsdlLocation(getInitParameter("sts.wsdl.url") +
getInitParameter("sts.UT.uri") + "?wsdl");
+ sts.setServiceQName(new QName(
+
"http://docs.oasis-open.org/ws-sx/ws-trust/200512/",
+ getInitParameter("sts.wsdl.service")));
+ sts.setEndpointQName(new QName(
+
"http://docs.oasis-open.org/ws-sx/ws-trust/200512/",
+
getInitParameter("sts.UT.wsdl.endpoint")));
+ sts.getProperties().put(SecurityConstants.USERNAME, username);
+ sts.getProperties().put(SecurityConstants.PASSWORD, password);
+
+ if (getInitParameter("token.internal.lifetime") != null) {
+ sts.setEnableLifetime(true);
+ int ttl =
Integer.parseInt(getInitParameter("token.internal.lifetime"));
+ sts.setTtl(ttl);
+ }
+
+ return sts.requestSecurityToken(appliesTo);
+ }
- private String requestSecurityToken(String username, String password,
- String wtrealm) throws Exception {
+ private String requestSecurityTokenForRP(SecurityToken onbehalfof,
+ String appliesTo) throws Exception {
try {
Bus bus = BusFactory.getDefaultBus();
List<String> realmClaims = null;
@@ -222,9 +313,9 @@ public class IdpServlet extends HttpServ
@SuppressWarnings("unchecked")
Map<String, List<String>> realmClaimsMap = (Map<String,
List<String>>) ctx
.getBean("realm2ClaimsMap");
- realmClaims = realmClaimsMap.get(wtrealm);
+ realmClaims = realmClaimsMap.get(appliesTo);
if (realmClaims != null && realmClaims.size() > 0 &&
LOG.isDebugEnabled()) {
- LOG.debug("claims for realm " + wtrealm);
+ LOG.debug("claims for realm " + appliesTo);
for (String item : realmClaims) {
LOG.debug(" " + item);
}
@@ -242,25 +333,25 @@ public class IdpServlet extends HttpServ
}
sts.setKeyType("http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer");
- sts.setWsdlLocation(getInitParameter("sts.wsdl.url"));
+ sts.setWsdlLocation(getInitParameter("sts.wsdl.url") +
getInitParameter("sts.RP.uri") + "?wsdl");
sts.setServiceQName(new QName(
"http://docs.oasis-open.org/ws-sx/ws-trust/200512/",
getInitParameter("sts.wsdl.service")));
sts.setEndpointQName(new QName(
"http://docs.oasis-open.org/ws-sx/ws-trust/200512/",
-
getInitParameter("sts.wsdl.endpoint")));
- sts.getProperties().put(SecurityConstants.USERNAME, username);
- sts.getProperties().put(SecurityConstants.PASSWORD, password);
+
getInitParameter("sts.RP.wsdl.endpoint")));
+
+ sts.setOnBehalfOf(onbehalfof.getToken());
Element claims = createClaimsElement(realmClaims);
if (claims != null) {
sts.setClaims(claims);
}
- return sts.requestSecurityTokenResponse(wtrealm);
+ return sts.requestSecurityTokenResponse(appliesTo);
} catch (org.apache.cxf.binding.soap.SoapFault ex) {
QName faultCode = ex.getFaultCode();
if (faultCode.equals(STSException.FAILED_AUTH)) {
- LOG.warn("Failed authentication for '" + username + "'");
+ LOG.warn("Failed authentication for '" +
onbehalfof.getPrincipal().getName() + "'");
}
throw ex;
} catch (Exception ex) {
Modified: cxf/fediz/trunk/services/idp/src/main/webapp/WEB-INF/RPClaims.xml
URL:
http://svn.apache.org/viewvc/cxf/fediz/trunk/services/idp/src/main/webapp/WEB-INF/RPClaims.xml?rev=1392512&r1=1392511&r2=1392512&view=diff
==============================================================================
--- cxf/fediz/trunk/services/idp/src/main/webapp/WEB-INF/RPClaims.xml (original)
+++ cxf/fediz/trunk/services/idp/src/main/webapp/WEB-INF/RPClaims.xml Mon Oct
1 18:44:14 2012
@@ -15,6 +15,10 @@
value-ref="claimsWsfedhelloworld2" />
<entry key="https://localhost:8443/fedizhelloworld/"
value-ref="claimsWsfedhelloworld2" />
+ <entry key="urn:fediz:fedizhelloworld"
+ value-ref="claimsWsfedhelloworld2" />
+ <entry key="urn:fediz:fedizhelloworld2"
+ value-ref="claimsWsfedhelloworld" />
</util:map>
Modified: cxf/fediz/trunk/services/idp/src/main/webapp/WEB-INF/web.xml
URL:
http://svn.apache.org/viewvc/cxf/fediz/trunk/services/idp/src/main/webapp/WEB-INF/web.xml?rev=1392512&r1=1392511&r2=1392512&view=diff
==============================================================================
--- cxf/fediz/trunk/services/idp/src/main/webapp/WEB-INF/web.xml (original)
+++ cxf/fediz/trunk/services/idp/src/main/webapp/WEB-INF/web.xml Mon Oct 1
18:44:14 2012
@@ -8,27 +8,46 @@
</description>
<display-name>WS Federation Tomcat Example</display-name>
+
+
<servlet>
<servlet-name>FederationServlet</servlet-name>
<servlet-class>org.apache.cxf.fediz.service.idp.IdpServlet</servlet-class>
<init-param>
<param-name>sts.wsdl.url</param-name>
-
<param-value>https://localhost:9443/fedizidpsts/STSService?wsdl</param-value>
+
<param-value>https://localhost:9443/fedizidpsts/</param-value>
</init-param>
<init-param>
<param-name>sts.wsdl.service</param-name>
<param-value>SecurityTokenService</param-value>
</init-param>
<init-param>
- <param-name>sts.wsdl.endpoint</param-name>
+ <param-name>sts.UT.wsdl.endpoint</param-name>
<param-value>TransportUT_Port</param-value>
</init-param>
+ <init-param>
+ <param-name>sts.UT.uri</param-name>
+ <param-value>STSService</param-value>
+ </init-param>
+ <init-param>
+ <param-name>sts.RP.wsdl.endpoint</param-name>
+ <param-value>Transport_Port</param-value>
+ </init-param>
+ <init-param>
+ <param-name>sts.RP.uri</param-name>
+ <param-value>STSServiceTransport</param-value>
+ </init-param>
+ <init-param>
+ <param-name>token.internal.lifetime</param-name>
+ <param-value>7200</param-value>
+ </init-param>
+
<!--
<init-param>
<param-name>ws-trust-tokentype</param-name>
<param-value>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1</param-value>
</init-param>
--->
+-->
</servlet>
<servlet-mapping>
Modified: cxf/fediz/trunk/services/sts/src/main/webapp/WEB-INF/cxf-transport.xml
URL:
http://svn.apache.org/viewvc/cxf/fediz/trunk/services/sts/src/main/webapp/WEB-INF/cxf-transport.xml?rev=1392512&r1=1392511&r2=1392512&view=diff
==============================================================================
--- cxf/fediz/trunk/services/sts/src/main/webapp/WEB-INF/cxf-transport.xml
(original)
+++ cxf/fediz/trunk/services/sts/src/main/webapp/WEB-INF/cxf-transport.xml Mon
Oct 1 18:44:14 2012
@@ -59,6 +59,7 @@
<bean id="conditionsProvider"
class="org.apache.cxf.sts.token.provider.DefaultConditionsProvider">
<property name="lifetime" value="1200" />
+ <property name="acceptClientLifetime" value="true" />
</bean>
<bean id="transportSamlTokenValidator"
class="org.apache.cxf.sts.token.validator.SAMLTokenValidator" />