Gradle: Replace Tokens by finding the tokens from property file - ant

Currently I understand that we can use org.apache.tools.ant.filters.ReplaceTokens to replace the contents of a file during build in the following way.
myBeans.xml:
<bean id="mybean1" class="com.test.MyClass1" >
<property name="myprop1" value="#myproperty#" />
</bean>
my.properties:
myprop=testme
gradle file:
from file("myBeans.xml"), {
filter(ReplaceTokens, tokens: ["myproperty": project.properties["myprop"]])
}
However I would want gradle to find the property names from my.properties file and replace it in the xml file (without mentioning myprop in the filter). If not, I would have to add all the PlaceHolders manually.

you can pass properties as a map to the ReplaceTokens configuration. The key must match the token you want to see replaced. Example:
beans.xml:
<bean id="mybean1" class="com.test.MyClass1" >
<property name="myprop1" value="#myproperty#" />
</bean>
my.properties:
myproperty=testme
build.gradle:
task myCopy(type:Copy){
from "bean.xml"
into ("$buildDir/beans")
def myProps = new Properties()
file("my.properties").withInputStream{
myProps.load(it);
}
filter(org.apache.tools.ant.filters.ReplaceTokens, tokens: myProps)
}
hope that helped.
cheers,
René

Related

jasper server 5.6 active directory authentication not working

I'm authentication jasper server 5.6 to ldap active directory.ldapAuthenticationProvider bean configurations are ok.(userDnPatterns working).but server couldn't search in usersearch bean.this is my userSearch configuration.Am I correctly put values to constructor-arg ?
<bean id="userSearch"
class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg index="0"><value>(sAMAccountName={0})</value></constructor-arg>
<constructor-arg index="1"><value>sAMAccountName={0},ou=IT Service Accounts</value></constructor-arg>
<constructor-arg index="2"><ref local="ldapContextSource"/></constructor-arg>
<property name="searchSubtree"><value>true</value></property>
</bean>
Thanks !
You should not use "sAMAccountName" as first parameter (index=0), as that parameter is the Directory search base.
If you want to use the default search base, leave the value blank.
Now, the second parameter, tells jasper (or any app that uses the FilterBasedLdapUserSearch method) how to search for the user, and what user should the app use to finally bind to the directory.
The fiter you specified on "index=1" would only work if AD has users DN's in the form:
DN: sAMAccountName=user,ou=IT Service Accounts, .....
Now, AD's default user DN's are more like: "CN=Full Name,CN=Users,....", so, in your case, you should be using only (sAMAccountName={0}) in the "FilterBasedLdapUserSearch" method, and then modify "LdapAuthenticationProvider" method to specify "userDnPatterns", like this:
<bean id="ldapAuthenticationProvider"
class="org.springframework.security.providers.ldap.LdapAuthenticationProvider">
<constructor-arg><bean class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator">
<constructor-arg><ref local="ldapContextSource"/></constructor-arg>
<property name="userDnPatterns"/>
<list> <value>CN={0},ou=IT Service Accounts</value> </list> </bean> </bean>
Of course, you should match this more closely to your setup, this is only an example.

Setting the ExtendedMetadata 'signingAlgorithm' field

I'm having an issue getting the Spring SAML integration to generate the correct metadata file for my IdP. I was issued new SHA256 SSL certs. I've gone through all of the steps to create the appropriate keyStore and have my Spring security configuration file all set. I am literally like 98% of the way there but there is one thing missing in the generated metadata file that I can't for the life of me figure out why it's not getting set.
Here is my ExtendedMetadata config for MetadataGeneratorFilter:
<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
<constructor-arg>
<bean class="org.springframework.security.saml.metadata.MetadataGenerator">
<property name="entityId" value="urn:myentityidhere"/>
<property name="entityBaseURL" value="https://${saml.url}"/>
<property name="extendedMetadata">
<bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
<property name="signMetadata" value="true"/>
<property name="signingAlgorithm" value="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<property name="alias" value="ceo"/>
<property name="signingKey" value="${saml.sp.alias}"/>
<property name="encryptionKey" value="${saml.sp.alias}"/>
</bean>
</property>
</bean>
</constructor-arg>
When I run my app and go to the /saml/metadata URI to get Spring to generate the metadata file I need to send to my IdP, the SHA256 algo gets correctly set on the SignatureMethod, but the child DigestMethod tag's algorithm value is still set to SHA1, when I need that ALSO set to SHA256 along with the DigestValue to be a SHA256 value and not a SHA1 value.
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#urn_myentityidhere">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>xxxxxxx</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
Can someone guide me in how/what I need to set to get the DigestMethod algorithm value set to 256 also? I figured since it is a child of the SignedInfo tag, it would inherit the signingAlgorithm value from the Extendedmetadata config, but alas it is not.
Any help would be GREATLY appreciated. Thanks so much.
SOLUTION - In case anyone cares
So, after a day's worth of digging, I decided to just implement this myself. I extended the ExtendedMetadata class by adding the field, digestMethodAlgorithm and added the appropriate getter/setters:
/**
* Algorithm used for creation of digest method of this entity. At the moment only used for metadata signatures.
* Only valid for local entities.
*/
private String digestMethodAlgorithm;
/**
* Returns digest method algorithm value
* #return String
*/
public String getDigestMethodAlgorithm()
{
return digestMethodAlgorithm;
}
/**
* Sets the digest method algorithm to use when signing the SAML messages.
* This can be used, for example, when a strong algorithm is required (e.g. SHA 256 instead of SHA 128).
* If this property is null, then the {#link org.opensaml.xml.Configuration} default algorithm will be used instead.
*
* Value only applies to local entities.
*
* At the moment the value is only used for signatures on metadata.
*
* Typical values are:
* http://www.w3.org/2001/04/xmlenc#sha1
* http://www.w3.org/2001/04/xmlenc#sha256
* http://www.w3.org/2001/04/xmlenc#sha384
* http://www.w3.org/2001/04/xmlenc#sha512
* http://www.w3.org/2001/04/xmlenc#ripemd160
*
* #param digestMethodAlgorithm The new digest method algorithm to use
* #see org.opensaml.xml.signature.SignatureConstants
*/
public void setDigestMethodAlgorithm(String digestMethodAlgorithm)
{
this.digestMethodAlgorithm = digestMethodAlgorithm;
}
Then I modified my spring security configuration from above to include this new bean property to be set in my MetadataGenerator config:
<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
<constructor-arg>
<bean class="org.springframework.security.saml.metadata.MetadataGenerator">
<property name="entityId" value="urn:myentityidhere"/>
<property name="entityBaseURL" value="https://${saml.url}"/>
<property name="extendedMetadata">
<bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
<property name="signMetadata" value="true"/>
<property name="signingAlgorithm" value="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<property name="digestMethodAlgorithm" value="http://www.w3.org/2001/04/xmlenc#sha256"/>
<property name="alias" value="ceo"/>
<property name="signingKey" value="${saml.sp.alias}"/>
<property name="encryptionKey" value="${saml.sp.alias}"/>
</bean>
</property>
</bean>
</constructor-arg>
Then I also had to make two changes to the SAMLUtil class. In getmetadataAsString, in the isSignMetadata() if-clause, I pulled out the injected value for the digestMethodAlgorithm set by the config above and then further modified the marshallAndSignMessage method to accept a new input parameter which I further use to get the DigestMethod algo set properly.
Inside of SAMLUtil.getMetaDataAsString, line 572
...
String digestMethodAlgorithm = extendedMetadata.getDigestMethodAlgorithm();
element = SAMLUtil.marshallAndSignMessage(descriptor, credential, signingAlgorithm, digestMethodAlgorithm, keyGenerator);
...
Inside of SAMLUtil.marshallAndSignMessage, right after line 437, I add/changed the following:
...
BasicSecurityConfiguration secConfig = null;
if (digestMethodAlgorithm != null)
{
secConfig = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration();
secConfig.setSignatureReferenceDigestMethod(digestMethodAlgorithm);
}
try {
SecurityHelper.prepareSignatureParams(signature, signingCredential, secConfig, keyInfoGenerator);
} catch (org.opensaml.xml.security.SecurityException e) {
throw new MessageEncodingException("Error preparing signature for signing", e);
}
...
I recompiled the entire Spring SAML core package via Gradle, spring-security-saml-1.0.0.RELEASE, copied the new jar from the build/libs directory to my project, deployed the webapp, pointed my browser to /saml/metadata and successfully got the metadata file with the correct SHA256 signed portion of the metadata file.
I'm going to see what I can do about getting this committed to the git repo for this project because I don't want to lose this ability as the project does future releases. Never contributed to an open-source project like this before.
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#urn_myentityidhere">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>xxxxxx</ds:DigestValue>
</ds:Reference>
Things seem to have changed since the #VladimírSchäfer answer; it did not work for us with AD FS 2.0 and SHA-256. We had to add an extra setting to get it to work (see code, below).
The problem appears to be in OpenSAML's xmltooling library, specifically the org.opensaml.xml.security.BasicSecurityConfiguration.getSignatureAlgorithmURI(Credential) method - instead of just using the signature algorithm of the certificate (in our case, SHA256withRSA), it gets the key of the certificate, then looks at the algorithm of that key and uses a map of registered URIs to look up a signature URI. If they'd just have a map of JCA signature algorithms to URIs, instead of key algorithms to URIs, it would all be fine.
The workaround is to register the correct signature algorithm URI with BasicSecurityConfiguration during Spring wiring, overwriting the (undesirable) URI http://www.w3.org/2000/09/xmldsig#rsa-sha1 that's already present with http://www.w3.org/2001/04/xmldsig-more#rsa-sha256.
We also had to remove the setSignatureReferenceDigestMethod() call, or importing metadata into AD FS would fail.
import org.opensaml.Configuration;import org.opensaml.xml.security.BasicSecurityConfiguration;
import org.springframework.beans.BeansException;import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;import org.springframework.security.saml.SAMLBootstrap;public class CustomSamlBootstrap extends SAMLBootstrap { #Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { super.postProcessBeanFactory(beanFactory);
BasicSecurityConfiguration config = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration();
config.registerSignatureAlgorithmURI("RSA", "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
}
}
You can configure digest method for computation of digital signatures by making the following call during Spring SAML initialization:
// Use SHA-256 signatures for RSA keys
BasicSecurityConfiguration config = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration();
config.setSignatureReferenceDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256);
For example extend the default org.springframework.security.saml.SAMLBootstrap and add the code to the overriden postProcessBeanFactory method after call to super:
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
super.postProcessBeanFactory(beanFactory);
BasicSecurityConfiguration config = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration();
config.setSignatureReferenceDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256);
}
This change affects both signatures in generated metadata and signatures in generated SAML messages.
After making the changes in SAMLBootstrap for global security config , I ran into below exception :
org.apache.xml.security.signature.XMLSignatureException: The requested
algorithm SHA256withRSA does not exist. Original Message was:
SHA256withRSA MessageDigest not available at
org.apache.xml.security.algorithms.MessageDigestAlgorithm.getDigestInstance(Unknown
Source) at
org.apache.xml.security.algorithms.MessageDigestAlgorithm.getInstance(Unknown
Source) at org.apache.xml.security.signature.Reference.(Unknown
Source) at
org.apache.xml.security.signature.Manifest.addDocument(Unknown Source)
at org.apache.xml.security.signature.XMLSignature.addDocument(Unknown
Source)
After further investigation found that the Apache XML Security xmlsec-1.4.3.jar does not support the underlying SHA256withRSA algorithm.
Resolution : Use xmlsec-2.0.2.jar from https://mvnrepository.com/artifact/org.apache.santuario/xmlsec/2.0.2
This new jar resolved the issue .

Error registering camel's ftp jpa Idempotent repository

I'm trying to implement jpa idempotent repository just as described here http://camel.apache.org/file2.html, but i'm getting a Mbean export error.
On my application-context.xml i've the following section.
<bean id="mvStore" class="org.apache.camel.processor.idempotent.jpa.JpaMessageIdRepository" lazy-init="false">
<!-- Here we refer to the spring jpaTemplate -->
<constructor-arg index="0" ref="jpaTemplate" />
<!-- This 2nd parameter is the name (= a cateogry name). You can have different repositories with different names -->
<constructor-arg index="1" value="FileConsumer" />
</bean>
<context:mbean-server id="mbeanServer" />
<context:mbean-export server="mbeanServer" registration="replaceExisting" default-domain="br.com.touchtec"/>
If I remove the above section than the server (tomcat) starts just fine. Can anybody help me on this?
Here's the stack:
Caused by: org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.apache.camel.processor.idempotent.jpa.JpaMessageIdRepository#6df960c4] with key 'mvStore'; nested exception is javax.management.MalformedObjectNameException: Key properties cannot be empty
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:602)
at org.springframework.jmx.export.MBeanExporter.registerBeans(MBeanExporter.java:527)
at org.springframework.jmx.export.MBeanExporter.afterPropertiesSet(MBeanExporter.java:413)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
... 50 more
Caused by: javax.management.MalformedObjectNameException: Key properties cannot be empty
at javax.management.ObjectName.construct(ObjectName.java:467)
at javax.management.ObjectName.<init>(ObjectName.java:1403)
at javax.management.ObjectName.getInstance(ObjectName.java:1285)
at org.springframework.jmx.support.ObjectNameManager.getInstance(ObjectNameManager.java:62)
at org.springframework.jmx.export.naming.MetadataNamingStrategy.getObjectName(MetadataNamingStrategy.java:114)
at org.springframework.jmx.export.MBeanExporter.getObjectName(MBeanExporter.java:728)
at org.springframework.jmx.export.MBeanExporter.registerBeanInstance(MBeanExporter.java:631)
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:592)
... 54 more
First of all, I hope you're clear on the fact the jmx part is not necessary to make the Idempotent Repository work. Your error is a pure JMX/Spring error, not linked to Camel.
If you want to use an MBeanExporter, you should read the official documentation on Spring JMX to have a better understaking of this matter.
Your MBeanExporter definition might look like
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="bean:name=mvStore" value-ref="mvStore"/>
</map>
</property>
<property name="server" ref="mbeanServer"/>
</bean>

Spring ws XSD validation

Currently i am implementing web services using Spring-ws . Here i am struck with xsd validation . For xsd validation i am using the following configruation
<bean id="validatingInterceptor" class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
<property name="xsdSchema" ref="schema" />
<property name="validateRequest" value="true" />
<property name="validateResponse" value="true" />
</bean>
<bean id="schema" class="org.springframework.xml.xsd.SimpleXsdSchema">
<property name="xsd" value="/WEB-INF/ProductSchema.xsd" />
</bean>
Here i am passing the xsd file during bean initialization . Is there any way for me to send this(ProductSchema.xsd) xsd file dynamically. Because I will comes to know which xsd file needs to send based on the input payload.
Please help me. Thanks in advance
I don't know how many XSD's you have, but perhaps you can define imports in ProductSchema.xsd to include the others. That's at least how I've got it set up.
For example:
<import namespace="http://namespace" schemaLocation="data.xsd" />
I'm not quite sure of what you are trying to do.
But you can make different endpoints/methods that matches different payloads by annotating the handler method with a localPart that matches the name of an element i the payload:
#Endpoint
public class MyEndpoint {
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "NameOfMyXmlRequestElement")
#ResponsePayload
public MyResponse handleMyRequest(#RequestPayload MyRequest MyRequest) throws Exception {
...
A recived request can then be unmarshalled/validated using a specific schema:
<bean id="myJaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>mydomain.model.oxm.MyRequest</value>
<value>mydomain.model.oxm.MyResponse</value>
</list>
</property>
<property name="schema" ref="MyServiceSchema" />
</bean>
<bean id="MyServiceSchema" class="org.springframework.core.io.ClassPathResource">
<constructor-arg value="WEB-INF/schemas/MyService.xsd" />
</bean>
The MyRequest class must be annotated to work with the Jaxb2marshaller, #XmlRootElement(name="MyRequest") etc...

How can I allow an Ant property file to override the value set in another?

I have an ant file that does the following:
<property file="project.properties" description="Project configuration properties"/>
<property file="build-defaults.properties" description="default build configuration."/>
<property file="build.properties" description="local build configuration overrides"/>
I want to have defaults set in build-defaults.properties (which is checked in to SCM) but allow developers to override values in a local build.properties so that they can work with local paths.
The problem is, it doesn't seem to be working; I've set this up, created an override in build.properties, but the value of my path remains the one set in build-defaults.properties. How do I accomplish this?
The initial problem with your set up is that you've got build.properties and build-defaults.properties reversed.
Ant Properties are set once and then can never be overridden. That's why setting any property on the command line via a -Dproperty=value will always override anything you've set in the file; the property is set and then nothing can override it.
So the way you want this set up is:
<property file="build.properties" description="local build configuration overrides"/>
<property file="project.properties" description="Project configuration properties"/>
<property file="build-defaults.properties" description="default build configuration."/>
This way:
Anything set at the command line takes precedence over build.properties
Anything set in build.properties overrides other values
etc. on down the line.
Actually ant properties may be overriden. See the documentation of the property task:
Normally property values can not be changed, once a property is set,
most tasks will not allow its value to be modified.
One of the tasks that are able to override the property value is script. Also any custom task may use this backdoor. Other proposals are in question Ant loadfile override property. This is against the spirit of ant and usually unnecessary. But it's good to know that, because I just had an opposite problem: why the property value changed although it is immutable.
Here is a sample target that uses script task to change the value of a property. It shows the basic methods to work with properties. All methods are described in Ant Api which is not available online. You need to download the Ant Manual. In its api directory there is the api documentation.
<target name="t1">
<property name="a" value="one" />
<script language="javascript">
sProp = project.getProperty("a");
sProp = sProp.replace("e", "ly");
project.setProperty("a", sProp);
project.setNewProperty("a", "new value");
</script>
<property name="a" value="two" />
<echo>a=${a}</echo>
</target>
How to easily setup the script task? Making the script task running with beanshell language is a bit tricky and non-trivial, but it's explained in this answer. However as Rebse noted, using javascript language is supported out of the box in jdk 6.
Ant property can't be overwritten unless using macro and javascript plug-in to do:
Step 1: define a macro function to overwrite property
<!--overwrite property's value-->
<macrodef name="set" >
<attribute name="name"/>
<attribute name="value"/>
<sequential>
<script language="javascript">
<![CDATA[
project.setProperty("#{name}", "#{value}");
]]>
</script>
</sequential>
</macrodef>
Step 2: use the macro in the ant xml
<set
name="your_target_property"
value="your_value" or "${another_property}"
</set>

Resources