Merge pull request #58 from amarkevich/FEDIZ-248

FEDIZ-248: OIDC UI: shared stylesheet
diff --git a/plugins/core/src/main/java/org/apache/cxf/fediz/core/TokenValidatorRequest.java b/plugins/core/src/main/java/org/apache/cxf/fediz/core/TokenValidatorRequest.java
index 05178bb..ec6c2c3 100644
--- a/plugins/core/src/main/java/org/apache/cxf/fediz/core/TokenValidatorRequest.java
+++ b/plugins/core/src/main/java/org/apache/cxf/fediz/core/TokenValidatorRequest.java
@@ -28,6 +28,7 @@
 
     private final Element token;
     private final Certificate[] certs;
+    private boolean enforceTokenSigned = true;
 
     public TokenValidatorRequest(Element token, Certificate[] certs) {
         this.token = token;
@@ -48,7 +49,12 @@
         }
         return null;
     }
-
-
-
+    
+    public void setEnforceTokenSigned(boolean enforceTokenSigned) {
+        this.enforceTokenSigned = enforceTokenSigned;
+    }
+    
+    public boolean isEnforceTokenSigned() {
+        return this.enforceTokenSigned;
+    }
 }
diff --git a/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/SAMLProtocol.java b/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/SAMLProtocol.java
index c552ef5..41be398 100644
--- a/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/SAMLProtocol.java
+++ b/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/SAMLProtocol.java
@@ -53,11 +53,23 @@
     }
 
     public boolean isSignRequest() {
-        return getSAMLProtocol().isSignRequest();
+        if (getSAMLProtocol().getSignRequest() != null) {
+            return getSAMLProtocol().getSignRequest().isValue();
+        } else {
+            return false;
+        }
+    }
+    
+    public SignatureDigestAlgorithm getSignRequestAlgorithm() {
+        if (getSAMLProtocol().getSignRequest() != null && getSAMLProtocol().getSignRequest().getAlgorithm() != null) {
+            return SignatureDigestAlgorithm.fromValue(getSAMLProtocol().getSignRequest().getAlgorithm().value());
+        }
+        
+        return SignatureDigestAlgorithm.RSA_SHA1;
     }
 
     public void setSignRequest(boolean signRequest) {
-        getSAMLProtocol().setSignRequest(signRequest);
+        getSAMLProtocol().getSignRequest().setValue(signRequest);
     }
 
     public SAMLPRequestBuilder getSAMLPRequestBuilder() {
@@ -103,6 +115,10 @@
     public boolean isDoNotEnforceKnownIssuer() {
         return getSAMLProtocol().isDoNotEnforceKnownIssuer();
     }
+    
+    public boolean isDoNotEnforceEncryptedAssertionsSigned() {
+        return getSAMLProtocol().isDoNotEnforceEncryptedAssertionsSigned();
+    }
 
     public void setDoNotEnforceKnownIssuer(boolean doNotEnforceKnownIssuer) {
         getSAMLProtocol().setDoNotEnforceKnownIssuer(doNotEnforceKnownIssuer);
diff --git a/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/SignatureDigestAlgorithm.java b/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/SignatureDigestAlgorithm.java
new file mode 100644
index 0000000..c6a936f
--- /dev/null
+++ b/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/SignatureDigestAlgorithm.java
@@ -0,0 +1,53 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.fediz.core.config;
+
+import org.apache.cxf.fediz.core.config.jaxb.SignatureDigestAlgorithmType;
+
+public enum SignatureDigestAlgorithm {
+
+    RSA_SHA1("RSA_SHA1"),
+    RSA_SHA256("RSA_SHA256");
+
+    private final String value;
+
+    SignatureDigestAlgorithm(String v) {
+        value = v;
+    }
+    SignatureDigestAlgorithm(SignatureDigestAlgorithmType type) {
+        value = type.value();
+    }
+
+    public String value() {
+        return value;
+    }
+
+    public static SignatureDigestAlgorithm fromValue(String v) {
+        for (SignatureDigestAlgorithm c: SignatureDigestAlgorithm.values()) {
+            if (c.value.equals(v)) {
+                return c;
+            }
+        }
+        throw new IllegalArgumentException(v);
+    }
+
+
+
+}
diff --git a/plugins/core/src/main/java/org/apache/cxf/fediz/core/processor/SAMLProcessorImpl.java b/plugins/core/src/main/java/org/apache/cxf/fediz/core/processor/SAMLProcessorImpl.java
index 08af3d7..3b40248 100644
--- a/plugins/core/src/main/java/org/apache/cxf/fediz/core/processor/SAMLProcessorImpl.java
+++ b/plugins/core/src/main/java/org/apache/cxf/fediz/core/processor/SAMLProcessorImpl.java
@@ -213,6 +213,11 @@
                 try {
                     TokenValidatorRequest validatorRequest =
                         new TokenValidatorRequest(token, request.getCerts());
+                    boolean doNotEnforceAssertionsSigned =
+                            ((SAMLProtocol)config.getProtocol()).isDoNotEnforceEncryptedAssertionsSigned()
+                            && !((org.opensaml.saml.saml2.core.Response)responseObject).getEncryptedAssertions()
+                            .isEmpty();
+                    validatorRequest.setEnforceTokenSigned(!doNotEnforceAssertionsSigned);
                     validatorResponse = validator.validateAndProcessToken(validatorRequest, config);
                 } catch (ProcessingException ex) {
                     throw ex;
@@ -440,7 +445,12 @@
             ssoResponseValidator.setIssuerIDP(requestState != null ? requestState.getIdpServiceAddress() : null);
             ssoResponseValidator.setRequestId(requestState != null ? requestState.getRequestId() : null);
             ssoResponseValidator.setSpIdentifier(requestState != null ? requestState.getIssuerId() : null);
-            ssoResponseValidator.setEnforceAssertionsSigned(true);
+            
+            boolean doNotEnforceAssertionsSigned =
+                    ((SAMLProtocol)config.getProtocol()).isDoNotEnforceEncryptedAssertionsSigned()
+                    && !samlResponse.getEncryptedAssertions().isEmpty();
+            ssoResponseValidator.setEnforceAssertionsSigned(!doNotEnforceAssertionsSigned);
+            
             ssoResponseValidator.setReplayCache(config.getTokenReplayCache());
 
             return ssoResponseValidator.validateSamlResponse(samlResponse, false);
@@ -572,6 +582,19 @@
         if (privateKey.getAlgorithm().equalsIgnoreCase("DSA")) {
             sigAlgo = WSConstants.DSA;
             jceSigAlgo = "SHA1withDSA";
+        } else {
+            switch(((SAMLProtocol)config.getProtocol()).getSignRequestAlgorithm()) {
+            case RSA_SHA1:
+                sigAlgo = WSConstants.RSA_SHA1;
+                jceSigAlgo = "SHA1withRSA";
+                break;
+            case RSA_SHA256:
+                sigAlgo = WSConstants.RSA_SHA256;
+                jceSigAlgo = "SHA256withRSA";
+                break;
+            default:
+                throw new ProcessingException("Unknown sign algorithm");
+            }
         }
         LOG.debug("Using Signature algorithm " + sigAlgo);
 
diff --git a/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SAMLTokenValidator.java b/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SAMLTokenValidator.java
index 3f493b0..b7f5b22 100644
--- a/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SAMLTokenValidator.java
+++ b/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SAMLTokenValidator.java
@@ -99,75 +99,80 @@
             // PasswordCallbackHandler(password));
 
             SamlAssertionWrapper assertion = new SamlAssertionWrapper(token);
-            if (!assertion.isSigned()) {
-                LOG.warn("Assertion is not signed");
-                throw new ProcessingException(TYPE.TOKEN_NO_SIGNATURE);
-            }
-            // Verify the signature
-            Signature sig = assertion.getSignature();
-            KeyInfo keyInfo = sig.getKeyInfo();
-            SAMLKeyInfo samlKeyInfo =
-                org.apache.wss4j.common.saml.SAMLUtil.getCredentialFromKeyInfo(
-                    keyInfo.getDOM(), new WSSSAMLKeyInfoProcessor(requestData),
-                    requestData.getSigVerCrypto()
-                );
-            assertion.verifySignature(samlKeyInfo);
-
-            // Parse the subject if it exists
-            assertion.parseSubject(
-                new WSSSAMLKeyInfoProcessor(requestData), requestData.getSigVerCrypto(),
-                requestData.getCallbackHandler()
-            );
-
-            // Now verify trust on the signature
-            Credential trustCredential = new Credential();
-            trustCredential.setPublicKey(samlKeyInfo.getPublicKey());
-            trustCredential.setCertificates(samlKeyInfo.getCerts());
-            trustCredential.setSamlAssertion(assertion);
-
-            SamlAssertionValidator trustValidator = new SamlAssertionValidator();
-            trustValidator.setFutureTTL(config.getMaximumClockSkew().intValue());
-
-            boolean trusted = false;
+            
+            boolean doNotEnforceAssertionsSigned = !request.isEnforceTokenSigned();
+            
+            boolean trusted = doNotEnforceAssertionsSigned;
             String assertionIssuer = assertion.getIssuerString();
-
-            List<TrustedIssuer> trustedIssuers = config.getTrustedIssuers();
-            for (TrustedIssuer ti : trustedIssuers) {
-                Pattern subjectConstraint = ti.getCompiledSubject();
-                List<Pattern> subjectConstraints = new ArrayList<>(1);
-                if (subjectConstraint != null) {
-                    subjectConstraints.add(subjectConstraint);
+            
+            if (!doNotEnforceAssertionsSigned) {
+                if (!assertion.isSigned()) {
+                    LOG.warn("Assertion is not signed");
+                    throw new ProcessingException(TYPE.TOKEN_NO_SIGNATURE);
                 }
+                // Verify the signature
+                Signature sig = assertion.getSignature();
+                KeyInfo keyInfo = sig.getKeyInfo();
+                SAMLKeyInfo samlKeyInfo =
+                    org.apache.wss4j.common.saml.SAMLUtil.getCredentialFromKeyInfo(
+                        keyInfo.getDOM(), new WSSSAMLKeyInfoProcessor(requestData),
+                        requestData.getSigVerCrypto()
+                    );
+                assertion.verifySignature(samlKeyInfo);
 
-                if (ti.getCertificateValidationMethod().equals(CertificateValidationMethod.CHAIN_TRUST)) {
-                    trustValidator.setSubjectConstraints(subjectConstraints);
-                    trustValidator.setSignatureTrustType(TrustType.CHAIN_TRUST_CONSTRAINTS);
-                } else if (ti.getCertificateValidationMethod().equals(CertificateValidationMethod.PEER_TRUST)) {
-                    trustValidator.setSignatureTrustType(TrustType.PEER_TRUST);
-                } else {
-                    throw new IllegalStateException("Unsupported certificate validation method: "
-                                                    + ti.getCertificateValidationMethod());
-                }
-                try {
-                    for (TrustManager tm: config.getCertificateStores()) {
-                        try {
-                            requestData.setSigVerCrypto(tm.getCrypto());
-                            trustValidator.validate(trustCredential, requestData);
-                            trusted = true;
-                            break;
-                        } catch (Exception ex) {
-                            LOG.debug("Issuer '{}' not validated in keystore '{}'",
-                                      ti.getName(), tm.getName());
+                // Parse the subject if it exists
+                assertion.parseSubject(
+                    new WSSSAMLKeyInfoProcessor(requestData), requestData.getSigVerCrypto(),
+                    requestData.getCallbackHandler()
+                );
+
+                // Now verify trust on the signature
+                Credential trustCredential = new Credential();
+                trustCredential.setPublicKey(samlKeyInfo.getPublicKey());
+                trustCredential.setCertificates(samlKeyInfo.getCerts());
+                trustCredential.setSamlAssertion(assertion);
+
+                SamlAssertionValidator trustValidator = new SamlAssertionValidator();
+                trustValidator.setFutureTTL(config.getMaximumClockSkew().intValue());
+           
+                List<TrustedIssuer> trustedIssuers = config.getTrustedIssuers();
+                for (TrustedIssuer ti : trustedIssuers) {
+                    Pattern subjectConstraint = ti.getCompiledSubject();
+                    List<Pattern> subjectConstraints = new ArrayList<>(1);
+                    if (subjectConstraint != null) {
+                        subjectConstraints.add(subjectConstraint);
+                    }
+                
+                    if (ti.getCertificateValidationMethod().equals(CertificateValidationMethod.CHAIN_TRUST)) {
+                        trustValidator.setSubjectConstraints(subjectConstraints);
+                        trustValidator.setSignatureTrustType(TrustType.CHAIN_TRUST_CONSTRAINTS);
+                    } else if (ti.getCertificateValidationMethod().equals(CertificateValidationMethod.PEER_TRUST)) {
+                        trustValidator.setSignatureTrustType(TrustType.PEER_TRUST);
+                    } else {
+                        throw new IllegalStateException("Unsupported certificate validation method: "
+                                                        + ti.getCertificateValidationMethod());
+                    }
+                    try {
+                        for (TrustManager tm: config.getCertificateStores()) {
+                            try {
+                                requestData.setSigVerCrypto(tm.getCrypto());
+                                trustValidator.validate(trustCredential, requestData);
+                                trusted = true;
+                                break;
+                            } catch (Exception ex) {
+                                LOG.debug("Issuer '{}' not validated in keystore '{}'",
+                                          ti.getName(), tm.getName());
+                            }
                         }
-                    }
-                    if (trusted) {
-                        break;
-                    }
-
-                } catch (Exception ex) {
-                    if (LOG.isInfoEnabled()) {
-                        LOG.info("Issuer '" + assertionIssuer + "' doesn't match trusted issuer '" + ti.getName()
-                                 + "': " + ex.getMessage());
+                        if (trusted) {
+                            break;
+                        }
+                
+                    } catch (Exception ex) {
+                        if (LOG.isInfoEnabled()) {
+                            LOG.info("Issuer '" + assertionIssuer + "' doesn't match trusted issuer '" + ti.getName()
+                                     + "': " + ex.getMessage());
+                        }
                     }
                 }
             }
diff --git a/plugins/core/src/main/resources/schemas/FedizConfig.xsd b/plugins/core/src/main/resources/schemas/FedizConfig.xsd
index 15f82cf..4441594 100644
--- a/plugins/core/src/main/resources/schemas/FedizConfig.xsd
+++ b/plugins/core/src/main/resources/schemas/FedizConfig.xsd
@@ -172,6 +172,7 @@
                     <xs:element ref="disableDeflateEncoding" />
                     <xs:element ref="disableClientAddressCheck" />
                     <xs:element ref="doNotEnforceKnownIssuer" />
+                    <xs:element ref="doNotEnforceEncryptedAssertionsSigned" />
                     <xs:element ref="issuerLogoutURL" />
                 </xs:sequence>
                 <xs:attribute name="version" use="required" type="xs:string" />
@@ -185,10 +186,11 @@
     <xs:element name="applicationServiceURL" type="xs:string" />
     <xs:element name="metadataURI" type="xs:string" />
 
-    <xs:element name="signRequest" type="xs:boolean" />
+    <xs:element name="signRequest" type="SignRequestType" />
     <xs:element name="authnRequestBuilder" type="xs:string" />
     <xs:element name="disableDeflateEncoding" type="xs:boolean" />
     <xs:element name="doNotEnforceKnownIssuer" type="xs:boolean" />
+    <xs:element name="doNotEnforceEncryptedAssertionsSigned" type="xs:boolean" />
     <xs:element name="issuerLogoutURL" type="xs:string" />
     <xs:element name="disableClientAddressCheck" type="xs:boolean"/>
 
@@ -205,6 +207,21 @@
             <xs:element ref="reply" />
         </xs:sequence>
     </xs:complexType>
+    
+     <xs:complexType name="SignRequestType">
+        <xs:simpleContent>
+            <xs:extension base="xs:boolean">
+                <xs:attribute name="algorithm" type="signatureDigestAlgorithmType" />
+            </xs:extension>
+        </xs:simpleContent>
+    </xs:complexType>
+    
+    <xs:simpleType name="signatureDigestAlgorithmType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="RSA_SHA1" />
+            <xs:enumeration value="RSA_SHA256" />
+        </xs:restriction>
+    </xs:simpleType>
 
     <xs:complexType name="CallbackType">
         <xs:simpleContent>
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLEncryptedResponseTest.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLEncryptedResponseTest.java
index b801796..882df46 100644
--- a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLEncryptedResponseTest.java
+++ b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLEncryptedResponseTest.java
@@ -52,6 +52,7 @@
 import org.apache.cxf.fediz.core.SAML2CallbackHandler;
 import org.apache.cxf.fediz.core.config.FedizConfigurator;
 import org.apache.cxf.fediz.core.config.FedizContext;
+import org.apache.cxf.fediz.core.exception.ProcessingException;
 import org.apache.cxf.fediz.core.processor.FedizProcessor;
 import org.apache.cxf.fediz.core.processor.FedizRequest;
 import org.apache.cxf.fediz.core.processor.FedizResponse;
@@ -86,6 +87,7 @@
 
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 /**
  * Some tests for processing SAMLResponses containing EncryptedAssertions using the SAMLProcessorImpl
@@ -150,7 +152,6 @@
     @org.junit.Test
     public void validateSignedEncryptedSAMLResponse() throws Exception {
         // Mock up a Request
-        //FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
         FedizContext config =
                 getFederationConfigurator().getFedizContext("ROOT_DECRYPTION");
 
@@ -199,12 +200,10 @@
     }
 
     @org.junit.Test
-    @org.junit.Ignore // TODO re-enable once we support unsigned encrypted assertions
     public void validateUnsignedEncryptedSAMLResponse() throws Exception {
         // Mock up a Request
-        //FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
         FedizContext config =
-                getFederationConfigurator().getFedizContext("ROOT_DECRYPTION");
+                getFederationConfigurator().getFedizContext("ROOT_DECRYPTION_ALLOW_UNSIGNED");
 
         String requestId = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
 
@@ -250,6 +249,53 @@
         assertClaims(wfRes.getClaims(), ClaimTypes.COUNTRY);
     }
 
+    @org.junit.Test
+    public void rejectUnsignedEncryptedAssertionByDefault() throws Exception {
+        // Mock up a Request
+        FedizContext config =
+                getFederationConfigurator().getFedizContext("ROOT_DECRYPTION");
+
+        String requestId = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+
+        String relayState = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+        RequestState requestState = new RequestState(TEST_REQUEST_URL,
+                TEST_IDP_ISSUER,
+                requestId,
+                TEST_REQUEST_URL,
+                (String)config.getProtocol().getIssuer(),
+                null,
+                relayState,
+                System.currentTimeMillis());
+
+        // Create SAML Response
+        SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+        callbackHandler.setAlsoAddAuthnStatement(true);
+        callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+        callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+        callbackHandler.setIssuer(TEST_IDP_ISSUER);
+        callbackHandler.setSubjectName(TEST_USER);
+        String responseStr = createSamlResponseStr(callbackHandler, requestId, false);
+
+        HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+        EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL));
+        EasyMock.expect(req.getRemoteAddr()).andReturn(TEST_CLIENT_ADDRESS);
+        EasyMock.replay(req);
+
+        FedizRequest wfReq = new FedizRequest();
+        wfReq.setResponseToken(responseStr);
+        wfReq.setState(relayState);
+        wfReq.setRequest(req);
+        wfReq.setRequestState(requestState);
+
+        FedizProcessor wfProc = new SAMLProcessorImpl();
+        try {
+            wfProc.processRequest(wfReq, config);
+            fail("Failure expected on an unsigned token");
+        } catch (ProcessingException ex) {
+            // expected
+        }
+    }
+
     private String createSamlResponseStr(AbstractSAMLCallbackHandler saml2CallbackHandler,
                                          String requestId,
                                          boolean signAssertion) throws Exception {
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLRequestTest.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLRequestTest.java
index 34a3ddb..8910070 100644
--- a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLRequestTest.java
+++ b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLRequestTest.java
@@ -42,6 +42,7 @@
 import org.apache.cxf.fediz.core.processor.SAMLProcessorImpl;
 import org.apache.cxf.fediz.core.util.DOMUtils;
 import org.apache.wss4j.common.saml.OpenSAMLUtil;
+import org.apache.wss4j.dom.WSConstants;
 import org.opensaml.saml.saml2.core.AuthnRequest;
 import org.opensaml.saml.saml2.core.LogoutRequest;
 
@@ -201,6 +202,34 @@
         String signature =
             redirectionURL.substring(redirectionURL.indexOf("Signature=") + "Signature=".length());
         Assert.assertTrue(signature != null && signature.length() > 0);
+        String signatureAlg =
+                redirectionURL.substring(redirectionURL.indexOf("SigAlg=") + "SigAlg=".length(),
+                        redirectionURL.indexOf('&', redirectionURL.indexOf("SigAlg=")));
+        Assert.assertEquals(WSConstants.RSA_SHA1, URLDecoder.decode(signatureAlg, "UTF-8"));
+    }
+
+    @org.junit.Test
+    public void testSignedSAMLAuthnRequestSHA256() throws Exception {
+        // Mock up a Request
+        FedizContext config = getFederationConfigurator().getFedizContext("SIGNED_ROOT_SHA256");
+
+        HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+        EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL)).times(1, 2);
+        EasyMock.expect(req.getContextPath()).andReturn(TEST_REQUEST_URI);
+        EasyMock.expect(req.getRequestURI()).andReturn(TEST_REQUEST_URI).times(1, 2);
+        EasyMock.replay(req);
+
+        FedizProcessor wfProc = new SAMLProcessorImpl();
+        RedirectionResponse response = wfProc.createSignInRequest(req, config);
+
+        String redirectionURL = response.getRedirectionURL();
+        String signature =
+                redirectionURL.substring(redirectionURL.indexOf("Signature=") + "Signature=".length());
+        Assert.assertTrue(signature != null && signature.length() > 0);
+        String signatureAlg =
+                redirectionURL.substring(redirectionURL.indexOf("SigAlg=") + "SigAlg=".length(),
+                        redirectionURL.indexOf('&', redirectionURL.indexOf("SigAlg=")));
+        Assert.assertEquals(WSConstants.RSA_SHA256, URLDecoder.decode(signatureAlg, "UTF-8"));
     }
 
     @org.junit.Test
diff --git a/plugins/core/src/test/resources/fediz_test_config_saml.xml b/plugins/core/src/test/resources/fediz_test_config_saml.xml
index ff84520..37166c5 100644
--- a/plugins/core/src/test/resources/fediz_test_config_saml.xml
+++ b/plugins/core/src/test/resources/fediz_test_config_saml.xml
@@ -213,8 +213,38 @@
 				<claimType type="a particular claim type" optional="true" />
 			</claimTypesRequested>
 		</protocol>
-	</contextConfig>	
-	
+	</contextConfig>
+
+	<contextConfig name="SIGNED_ROOT_SHA256">
+		<audienceUris>
+			<audienceItem>http://host_one:port/url</audienceItem>
+		</audienceUris>
+		<certificateStores>
+			<trustManager>
+				<keyStore file="ststrust.jks" password="storepass"
+						  type="JKS" />
+			</trustManager>
+		</certificateStores>
+		<signingKey keyPassword="stskpass" keyAlias="mystskey">
+			<keyStore file="stsstore.jks" password="stsspass" type="JKS" />
+		</signingKey>
+		<trustedIssuers>
+			<issuer certificateValidation="PeerTrust" />
+		</trustedIssuers>
+
+		<maximumClockSkew>1000</maximumClockSkew>
+		<protocol xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+				  xsi:type="samlProtocolType" version="1.2">
+			<signRequest algorithm="RSA_SHA256">true</signRequest>
+			<issuer>http://url_to_the_issuer</issuer>
+			<roleDelimiter>;</roleDelimiter>
+			<roleURI>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role</roleURI>
+			<claimTypesRequested>
+				<claimType type="a particular claim type" optional="true" />
+			</claimTypesRequested>
+		</protocol>
+	</contextConfig>
+
 	<contextConfig name="CLIENT_TRUST">
 		<audienceUris>
 			<audienceItem>http://host_one:port/url</audienceItem>
@@ -364,4 +394,37 @@
 		<logoutURL>secure/logout</logoutURL>
 		<logoutRedirectTo>/redir.html</logoutRedirectTo>
 	</contextConfig>
+
+	<contextConfig name="ROOT_DECRYPTION_ALLOW_UNSIGNED">
+		<audienceUris>
+			<audienceItem>http://host_one:port/url</audienceItem>
+		</audienceUris>
+		<certificateStores>
+			<trustManager>
+				<keyStore file="ststrust.jks" password="storepass"
+						  type="JKS" />
+			</trustManager>
+		</certificateStores>
+		<trustedIssuers>
+			<issuer certificateValidation="PeerTrust" />
+		</trustedIssuers>
+		<tokenDecryptionKey keyPassword="stskpass" keyAlias="mystskey">
+			<keyStore file="stsstore.jks" password="stsspass" type="JKS" />
+		</tokenDecryptionKey>
+
+		<maximumClockSkew>1000</maximumClockSkew>
+		<protocol xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+				  xsi:type="samlProtocolType" version="1.2">
+			<issuer>http://url_to_the_issuer</issuer>
+			<roleDelimiter>;</roleDelimiter>
+			<roleURI>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role</roleURI>
+			<claimTypesRequested>
+				<claimType type="a particular claim type" optional="true" />
+			</claimTypesRequested>
+			<doNotEnforceEncryptedAssertionsSigned>true</doNotEnforceEncryptedAssertionsSigned>
+		</protocol>
+
+		<logoutURL>secure/logout</logoutURL>
+		<logoutRedirectTo>/redir.html</logoutRedirectTo>
+	</contextConfig>
 </FedizConfig>