2 items | |
Frictionless data preloading in AngularJS http://t.co/QDwlEiQoDS | |
June 08, 2014 at 11:51PM | |
| |
KendoNg–Part 2–Data http://t.co/gSgoFVJeuZ | |
June 08, 2014 at 11:51PM | |
|
niko's mini factory in english
Tips about Node.js, AngularJS & MongoDB development.
Monday, June 09, 2014
Daily Digest about Node.js AngularJS and MongoDB links
Monday, February 17, 2014
MEAN Flipboard Magazine
Obviously I have not updated this blog for a long time, but if you are interested in the MEAN stack (MongoDB, Express, AngularJS y Node.js) please do not forget to visit this Flipboard magazine.
Thursday, February 24, 2011
Helpful Spring Links
The SpringSource Team Blog continues posting articles about Spring 3.1 and Grean Beans Series (Spring in general). Here is the list:
Green Beans
Putting the Spring in Your Step (and Application)
Getting Started with Spring MVC
Getting Started with Spring in your Service Tier
Getting Started with Maven and Spring
Getting Started with Enterprise Messaging and Spring
Getting Started with Spring Integration
Spring 3.1
Spring 3.1 M1: Introducing @Profile
Unified Property Management
Introducing FeatureSpecification support
MVC Namespace Enhancements and @Configuration
Cache Abstraction
Monday, April 26, 2010
Presenting on Semana Informática 2010
On April 27, my colleague Pedro Molina
and me will give a talk on frameworks and MDD. The talk will be during the Computer Week 2010: Development productivity and flexibility through frameworks and code generation event.
Having helped on many occasions with the development of frameworks for the most diverse institutions, the challenge is knowing how to convey the need for such frameworks, the complexity associated with their development and the productivity gains achieved.
But do not forget a fundamental part of what is intended to achieve with a framework: development flexibility. Is useless for us to standardize how to build applications, and provide very robust infrastructure services (That's a development framework, right?), if after every technology change we have to change the framework.
If after each technology change our framework becomes obsolete, the ability to adapt to the business needs are diminished, up to the point of becoming an obstacle to it. And our goal as software developers is to always be 100% aligned to business, not to act as an obstacle of change.
This is where the benefits of code generation are obvious. From Spring Roo, to model driven development, the way is "meta-programming".
How is it that after more than 30 years of computers, we're still devoting whole days to develop a simple table maintenance screen? How come we have not yet managed to say "HAL: build me a Customer table maintenance"?
I don't have the answer, but I know that 80% of the applications code is repeatable and can be modelled and generated, and we should put more effort into meta-programming and less into maintenances.
And I also know that I would like to spend my time developing the other 20%.
Thursday, April 08, 2010
OpenSAML signature verification
Assuming that a webservice call containing a signed SAML Assertion, how do we verify that signature? CXF provides "interceptors" to add code before and after a call to a webservice.
First we must configure the call (with Spring in this case):
<jaxws:client id="clientWS" serviceClass="es.mycompany.MyService" address="http://localhost:8080/app/services/myservice"> <jaxws:dataBinding> <ref bean="aegisBean" /> </jaxws:dataBinding> <jaxws:inInterceptors> <ref bean="clientWS.InInterceptor" /> </jaxws:inInterceptors></jaxws:client><bean id="clientWS.InInterceptor" class="es.mycompany.MyInterceptor"> <constructor-arg> <map> <entry key="action" value="Timestamp Signature"/> <entry key="passwordCallbackClass" value="es.mycompany.MyPasswordCallback"/> <entry key="signaturePropFile" value="keystore.properties"/> </map> </constructor-arg></bean>
After that, we need to create a "keystore.properties" file:
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlinorg.apache.ws.security.crypto.merlin.keystore.type=jksorg.apache.ws.security.crypto.merlin.keystore.alias=MyAliasorg.apache.ws.security.crypto.merlin.keystore.password=MyPasswordorg.apache.ws.security.crypto.merlin.file=keystore.jks
And finally the class for managing the certificate passwords. This class needs improvements, but it's good as an example:
public class MyPasswordCallback implements CallbackHandler { private MapWith everything in place, we only have to code the interceptor, which in turn uses a utilities class:passwords = new HashMap (); public STSPasswordCallback() { passwords.put("MyAlias", "MyPassword"); } public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < pc =" (WSPasswordCallback)" pass =" passwords.get(pc.getIdentifier());">
public class MyInterceptor extends WSS4JInInterceptor { private String issuer = "http://www.mycompany.com"; public MyInterceptor() { super(); } public MyInterceptor(MapAs you can see, all the work is done in the trustEngine.validate(assertion.getSignature(), criteriaSet); line, we only need to reach there with the right data.properties) { super(properties); } protected void doReceiverAction(int doAction, RequestData reqData) throws WSSecurityException { // Get SOAP Header SOAPMessage message = ((org.apache.cxf.binding.soap.SoapMessage) reqData.getMsgContext()).getContent(javax.xml.soap.SOAPMessage.class); SOAPHeader soapHeader = message.getSOAPHeader(); // Get Assertion XML XPathUtils xu = new XPathUtils(); Element xmlAssertion = (Element) xu.getValueNode("//saml2:Assertion", soapHeader); // Unmarshall Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(xmlAssertion); Assertion assertion = (Assertion) unmarshaller.unmarshall(xmlAssertion); // Get Handler properties String sigPropFile = getString(WSHandlerConstants.SIG_PROP_FILE, reqData.getMsgContext()); String callback = getString(WSHandlerConstants.PW_CALLBACK_CLASS, reqData.getMsgContext()); // Verify SAMLUtils.verifySignature(assertion, issuer, sigPropFile, callback); super.doReceiverAction(doAction, reqData); } public void handleMessage(SoapMessage message) throws Fault { super.handleMessage(message); }}public class SAMLUtils { public static void verifySignature(Assertion assertion, String issuer, String sigPropFile, String callback) throws WSSecurityException { X509Credential cred = getX509Credential(sigPropFile, callback); StaticCredentialResolver credResolver = new StaticCredentialResolver(cred); KeyInfoCredentialResolver kiResolver = SecurityHelper.buildBasicInlineKeyInfoResolver(); ExplicitKeySignatureTrustEngine trustEngine = new ExplicitKeySignatureTrustEngine(credResolver, kiResolver); CriteriaSet criteriaSet = new CriteriaSet(); criteriaSet.add(new EntityIDCriteria(issuer)); criteriaSet.add(new UsageCriteria(UsageType.SIGNING)); criteriaSet.add(new MetadataCriteria(IDPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS)); try { trustEngine.validate(assertion.getSignature(), criteriaSet); } catch (SecurityException e) { throw new WSSecurityException(e.getMessage()); } } public static X509Credential getX509Credential(String sigPropFile, String callback) throws WSSecurityException { PrivateKey privateKey = null; X509Certificate[] certs = null; Crypto crypto = crypto = CryptoFactory.getInstance(sigPropFile); try { CallbackHandler cbhandler = getPasswordCallBack(callback); WSPasswordCallback cb = new WSPasswordCallback(crypto.getDefaultX509Alias(), WSPasswordCallback.SIGNATURE); cbhandler.handle(new Callback[] { cb }); privateKey = crypto.getPrivateKey(crypto.getDefaultX509Alias(), cb.getPassword()); certs = crypto.getCertificates(crypto.getDefaultX509Alias()); } catch (Exception e) { throw new WSSecurityException(e.getMessage()); } if (certs.length != 1) { throw new WSSecurityException("Couldn't get the (" + crypto.getDefaultX509Alias() + ") signature certificate."); } X509Credential cred = SecurityHelper.getSimpleCredential(certs[0], privateKey); return cred; } public static CallbackHandler getPasswordCallBack(String callback) throws WSSecurityException { CallbackHandler cbHandler = null; try { Class cbClass = Loader.loadClass(callback); cbHandler = (CallbackHandler) cbClass.newInstance(); } catch (Exception e) { throw new WSSecurityException("WSHandler: cannot create instance of password callback: " + callback, e); } return cbHandler; }}
Monday, October 26, 2009
CXF, WSS4J & Spring Security Recipe
How to use Spring Security to authenticate a user/password web service implemented with CXF using WSS4J (Apache Java WS-Security):
In the Spring Application context, we define the namespaces, import CXF's xml and define the "Interceptor" to deal with security:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:cxf="http://cxf.apache.org/core" xmlns:util="http://www.springframework.org/schema/util" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd" > <!-- Load CXF modules from cxf.jar --> <import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <bean id="WSS4JInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"> <property name="properties"> <map> <entry key="action" value="UsernameToken Timestamp"/> <entry key="passwordType" value="PasswordDigest"/> <entry key="passwordCallbackRef"> <bean class="my.company.SecurityInPasswordHandler"/> </entry> </map> </property> </bean> </beans>
And then we add the interceptor to the webservice:
<jaxws:endpoint id="salaWebService" implementor="#salaService" address="/salas"> <jaxws:inInterceptors> <ref bean="WSS4JInInterceptor"/> </jaxws:inInterceptors> </jaxws:endpoint>
Assuming we have the following service:
@WebService @SOAPBinding public interface SalaService { @WebResult(name = "sala") public abstract Sala get(@WebParam(name = "id") Long id); } @Service("salaService") @WebService(serviceName = "SalaService", portName = "SalaPort", endpointInterface = "my.company.service.SalaService") public class SalaServiceImpl implements SalaService { public Sala get(Long id) { return (Sala) executor.execute(SalaBusinessOperations.GET, new Long(id)); } }
And CXF configured in web.xml as follows:
<servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping>
The spring security should be configured with something like this:
<http > <intercept-url pattern="/services/**" access="ROLE_ANONYMOUS" /> <intercept-url pattern="/**" access="ROLE_USER" /> <logout/> <anonymous/> </http>
Finally we could write the interceptor class:
public class SecurityInPasswordHandler implements CallbackHandler { @Autowired private AuthenticationManager authenticationManager; @Autowired private UserDetailsService userService; public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException, AuthenticationException { WSPasswordCallback pwdCallback = (WSPasswordCallback) callbacks[0]; int usage = pwdCallback.getUsage(); if ((usage == WSPasswordCallback.USERNAME_TOKEN) || (usage == WSPasswordCallback.USERNAME_TOKEN_UNKNOWN)) { String password = pwdCallback.getPassword(); if (usage == WSPasswordCallback.USERNAME_TOKEN) { UserDetails userDetails = userService.loadUserByUsername(pwdCallback.getIdentifier()); password = userDetails.getPassword(); } Authentication authentication = new UsernamePasswordAuthenticationToken(pwdCallback.getIdentifier(), password); authentication = authenticationManager.authenticate(authentication); //throws AuthenticationException SecurityContextHolder.getContext().setAuthentication(authentication); // Return the password to the caller pwdCallback.setPassword(password); } } }
Now we could handle plain (PasswordText) or encrypted (PasswordDigest) passwords. In both cases creating a SecurityContext for the request to have the user roles and use them in our Spring Security "@Secured" annotations.
Friday, June 27, 2008
Subscribe to:
Posts (Atom)