1717package org .apache .cloudstack .api .command ;
1818
1919import com .cloud .api .response .ApiResponseSerializer ;
20+ import com .cloud .configuration .Config ;
2021import com .cloud .user .Account ;
2122import org .apache .cloudstack .api .APICommand ;
2223import org .apache .cloudstack .api .ApiErrorCode ;
2728import org .apache .cloudstack .api .auth .APIAuthenticator ;
2829import org .apache .cloudstack .api .auth .PluggableAPIAuthenticator ;
2930import org .apache .cloudstack .api .response .LogoutCmdResponse ;
31+ import org .apache .cloudstack .framework .config .dao .ConfigurationDao ;
3032import org .apache .cloudstack .saml .SAML2AuthManager ;
3133import org .apache .cloudstack .utils .auth .SAMLUtils ;
3234import org .apache .log4j .Logger ;
3335import org .opensaml .DefaultBootstrap ;
3436import org .opensaml .saml2 .core .LogoutRequest ;
3537import org .opensaml .saml2 .core .NameID ;
38+ import org .opensaml .saml2 .core .Response ;
39+ import org .opensaml .saml2 .core .StatusCode ;
3640import org .opensaml .xml .ConfigurationException ;
3741import org .opensaml .xml .io .MarshallingException ;
42+ import org .opensaml .xml .io .UnmarshallingException ;
43+ import org .xml .sax .SAXException ;
3844
3945import javax .inject .Inject ;
4046import javax .servlet .http .HttpServletResponse ;
4147import javax .servlet .http .HttpSession ;
48+ import javax .xml .parsers .ParserConfigurationException ;
4249import javax .xml .stream .FactoryConfigurationError ;
4350import java .io .IOException ;
4451import java .util .List ;
@@ -51,6 +58,8 @@ public class SAML2LogoutAPIAuthenticatorCmd extends BaseCmd implements APIAuthen
5158
5259 @ Inject
5360 ApiServerService _apiServer ;
61+ @ Inject
62+ ConfigurationDao _configDao ;
5463 SAML2AuthManager _samlAuthManager ;
5564
5665 /////////////////////////////////////////////////////
@@ -79,6 +88,7 @@ public String authenticate(String command, Map<String, Object[]> params, HttpSes
7988 LogoutCmdResponse response = new LogoutCmdResponse ();
8089 response .setDescription ("success" );
8190 response .setResponseName (getCommandName ());
91+ String responseString = ApiResponseSerializer .toSerializedString (response , responseType );
8292
8393 try {
8494 DefaultBootstrap .bootstrap ();
@@ -89,8 +99,35 @@ public String authenticate(String command, Map<String, Object[]> params, HttpSes
8999 params , responseType ));
90100 }
91101
102+ if (params .containsKey ("SAMLResponse" )) {
103+ try {
104+ final String samlResponse = ((String [])params .get (SAMLUtils .SAML_RESPONSE ))[0 ];
105+ Response processedSAMLResponse = SAMLUtils .decodeSAMLResponse (samlResponse );
106+ String statusCode = processedSAMLResponse .getStatus ().getStatusCode ().getValue ();
107+ if (!statusCode .equals (StatusCode .SUCCESS_URI )) {
108+ throw new ServerApiException (ApiErrorCode .INTERNAL_ERROR , _apiServer .getSerializedApiError (ApiErrorCode .INTERNAL_ERROR .getHttpCode (),
109+ "SAML SLO LogoutResponse status is not Success" ,
110+ params , responseType ));
111+ }
112+ } catch (ConfigurationException | FactoryConfigurationError | ParserConfigurationException | SAXException | IOException | UnmarshallingException e ) {
113+ s_logger .error ("SAMLResponse processing error: " + e .getMessage ());
114+ }
115+ try {
116+ resp .sendRedirect (_configDao .getValue (Config .SAMLCloudStackRedirectionUrl .key ()));
117+ } catch (IOException ignored ) {
118+ }
119+ return responseString ;
120+ }
121+
92122 NameID nameId = (NameID ) session .getAttribute (SAMLUtils .SAML_NAMEID );
93123 String sessionIndex = (String ) session .getAttribute (SAMLUtils .SAML_SESSION );
124+ if (nameId == null || sessionIndex == null ) {
125+ try {
126+ resp .sendRedirect (_configDao .getValue (Config .SAMLCloudStackRedirectionUrl .key ()));
127+ } catch (IOException ignored ) {
128+ }
129+ return responseString ;
130+ }
94131 LogoutRequest logoutRequest = SAMLUtils .buildLogoutRequest (_samlAuthManager .getIdpSingleLogOutUrl (), _samlAuthManager .getServiceProviderId (), nameId , sessionIndex );
95132
96133 try {
@@ -102,8 +139,7 @@ public String authenticate(String command, Map<String, Object[]> params, HttpSes
102139 "SAML Single Logout Error" ,
103140 params , responseType ));
104141 }
105-
106- return ApiResponseSerializer .toSerializedString (response , responseType );
142+ return responseString ;
107143 }
108144
109145 @ Override
0 commit comments