Pages

March 2, 2011

Integrating Spring Security 3 with Wicket

In an older post I spoke about integrating Spring Security 3 with Extjs (here), now I will speak about integrating Spring Security 3 with Wicket.
Tools:
- Wicket 1.4.15
- Maven 3.0.2
- Spring Security 3.0.5
- IDE: Netbeans 6.9.1
- Server: Tomcat VI
How to start?
Just create a simple wicket application with maven and add the following dependencies for the Spring framework:


        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>3.0.5.RELEASE</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>3.0.5.RELEASE</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>3.0.5.RELEASE</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
            <version>3.0.5.RELEASE</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>3.0.5.RELEASE</version>
            <type>jar</type>
        </dependency>

The wicket application class should extends AuthenticatedWebApplication.
After that you should add the following code in web.xml:


    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/applicationContext-security.xml
        </param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

The Spring XML configuration file:



        
    <http create-session="never" auto-config="true" >
        <remember-me/>
        <intercept-url pattern="/**"/>
    </http>


    <!--
    Usernames/Passwords are
        moez/moez
        test/test
    -->
    <authentication-manager alias="authenticationManager" >
        <authentication-provider>
            <password-encoder hash="md5"/>
            <user-service>
                <user name="moez" password="f69471ca2c42621b8b8e731b2b4446e4" authorities="ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER" />
                <user name="test" password="098f6bcd4621d373cade4e832627b4f6" authorities="ROLE_USER" />
            </user-service>
        </authentication-provider>
    </authentication-manager>
    <global-method-security secured-annotations="enabled" />
</beans:beans>

The authenticated websession:

public class SpringWicketWebSession extends AuthenticatedWebSession {


    private static final Logger logger = Logger.getLogger(SpringWicketWebSession.class);

    @SpringBean(name = "authenticationManager")
    private AuthenticationManager authenticationManager;

    public SpringWicketWebSession(Request request) {
        super(request);
        injectDependencies();
        ensureDependenciesNotNull();
    }

    public static SpringWicketWebSession getSpringWicketWebSession() {
        return (SpringWicketWebSession) Session.get();
    }

    private void ensureDependenciesNotNull() {
        if (authenticationManager == null) {
            throw new IllegalStateException("Requires an authentication");
        }
    }

    private void injectDependencies() {
        InjectorHolder.getInjector().inject(this);
    }

    @Override
    public boolean authenticate(String username, String password) {
        boolean authenticated = false;
        try {
            Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
            SecurityContextHolder.getContext().setAuthentication(authentication);
            authenticated = authentication.isAuthenticated();
        } catch (AuthenticationException e) {
            logger.warn("User "+username+" failed to login. Reason: ", e);
            authenticated = false;
        }
        return authenticated;
    }

    @Override
    public Roles getRoles() {
        Roles roles = new Roles();
        getRolesIfSignedIn(roles);
        return roles;
    }

    private void getRolesIfSignedIn(Roles roles) {
        if (isSignedIn()) {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            addRolesFromAuthentication(roles, authentication);
        }
    }

    private void addRolesFromAuthentication(Roles roles, Authentication authentication) {
        for (GrantedAuthority authority : authentication.getAuthorities()) {
            roles.add(authority.getAuthority());
        }
    }

    

}

source code here

February 24, 2011

What's new in GlassFish 3.1

Developer Productivity:
* Rapidly deploy and redeploy enterprise applications
* Major OSGi improvements and updates
* Enhanced JEE 6 functionality such as EJB support in embedded API and JMX/JAX-RS management API

Enterprise Readiness:
* Management of clusters containing many instances from a centralized web based console
* Dynamic configuration of live clusters
* High availability for JAX-WS, JMS, EJB. ActiveRedeploy that retains EJB/HTTP session state on redeploy
* Oracle Portfolio Integration: Oracle Coherence, Oracle Web Services Manager, Oracle Access Manager, Oracle WebLogic Server compatibility and interoperation

References: http://glassfish.java.net/

February 17, 2011

New features for Spring 3.0

This is a list of some new features for Spring 3.0:
  • Support for Java EE 6: JPA2, JSF2, EJB3.1...
  • Core APIs updated for Java 5: typed bean instances returned
    T getBean(Class<T> requiredType)
  • Support embedded database:  Support for embedded Java database engines provides by the org.springframework.jdbc.datasource.embedded package (hsql, h2...).
  • New features from JavaConfig: Some core features from the JavaConfig project have been added to the Spring Framework.
  • 
    @Configuration
    public class AppConfig {
    
        private
        @Value("#{jdbcProperties.url}")
        String url;
        private
        @Value("#{jdbcProperties.username}")
        String username;
        private
        @Value("#{jdbcProperties.password}")
        String password;
    
        /**
         * ........
         * some code here
         * ........
         */
        @Bean
        public DataSource dataSource() {
            return new DriverManagerDataSource(url, username, password);
        }
    }
    
    
    The properties file is declared into application context xml file
    
    <util:properties id="jdbcProperties" location="/WEB-INF/jdbc.properties"/>
    
    
  • Object to XML mapping: Moved from Spring web services to Spring core (package org.springframework.oxm).
You can see how integrating Spring Security 3 with Extjs here
References: http://www.springsource.org/documentation

February 9, 2011

Integrating Spring Security 3 with Extjs

It has a lot of differences and developments in Spring Security 3 versus 2, for this I thought to add this article..

The following tutorial will talk about how integrating Spring security 3 with extjs login page.

Tools:
   - Netbeans 6.9.1
   - Spring framework 3.0.2
   - Spring security 3.0.4
   - Extjs 3.2.1
   - Tomcat 6.0.24

Step1: 
   Create a java web application with netbeans, and add the spring web MVC framework dependency.

Step2: 
   In the webcontent create a js file named login.js

Ext.onReady(function(){
    Ext.QuickTips.init();
    var login = new Ext.FormPanel({
        labelWidth:80,
        url:'j_spring_security_check',
        frame:true,
        title:'Please Login',
        defaultType:'textfield',
        width:300,
        height:150,
        monitorValid:true,
        items:[{
            fieldLabel:'Username',
            name:'j_username',
            allowBlank:false
        },{
            fieldLabel:'Password',

            name:'j_password',
            inputType:'password',
            allowBlank:false
        }],

        buttons:[{

            text:'Login',
            formBind: true,
            handler:function(){
            login.getForm().submit({

                method:'POST',
                success:function(){
                Ext.Msg.alert('Status', 'Login Successful!', function(btn, text){

                    if (btn == 'ok'){
                        window.location = 'main.htm';
                    }
                });

            },

            failure:function(form, action){
                if(action.failureType == 'server'){
                    obj = Ext.util.JSON.decode(action.response.responseText);

                    Ext.Msg.alert('Login Failed!', obj.errors.reason);
                }else{
                    Ext.Msg.alert('Warning!', 'Authentication server is unreachable : ' + action.response.responseText);

                }
                login.getForm().reset();
            }
            });
        }
        }]
    });
    login.render('login');
});

Step3:
  If you try to execute the application now with a basic applicationContext-security.xml file, the user will be successfully authenticated, but is not going to be redirected. So, we will need to create a filter.

public class RecrutementAuthProcessingFilter extends UsernamePasswordAuthenticationFilter {

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) throws IOException, ServletException {
        SavedRequestAwareAuthenticationSuccessHandler srh = new SavedRequestAwareAuthenticationSuccessHandler();
        this.setAuthenticationSuccessHandler(srh);
        srh.setRedirectStrategy(new RedirectStrategy() {
            @Override
            public void sendRedirect(HttpServletRequest httpServletRequest,
                    HttpServletResponse httpServletResponse, String s) throws IOException {
                    //do nothing, no redirect
            }
        });
        super.successfulAuthentication(request, response, authResult);
        HttpServletResponseWrapper responseWrapper = new HttpServletResponseWrapper(response);
        Writer out = responseWrapper.getWriter();
        out.write("{success:true}");
        out.close();
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        super.unsuccessfulAuthentication(request, response, failed);
        HttpServletResponseWrapper responseWrapper = new HttpServletResponseWrapper(response);
        Writer out = responseWrapper.getWriter();
        out.write("{success:false}");
        out.close();
    }
}

UsernamePasswordAuthenticationFilter(AuthenticationProcessingFilter prior to Spring Security 3.0) processes an authentication form submission. Called login forms must present two parameters to this filter: a username (j_username) and password (j_password).
The applicationContext-security will be:

<?xml version="1.0" encoding="UTF-8"?>

<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">


    <global-method-security pre-post-annotations="enabled"/>

    <http auto-config='false' entry-point-ref="authenticationEntryPoint">
        <intercept-url pattern="/index*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
        <intercept-url pattern="/js/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
        <intercept-url pattern="/main*" access="ROLE_USER" />
        <custom-filter position="FORM_LOGIN_FILTER" ref="authenticationFilter" />
    </http>

    <beans:bean id="authenticationFilter" class="com.blog.dev.security.RecrutementAuthProcessingFilter">                
        <beans:property name="authenticationManager" ref="authenticationManager" />
    </beans:bean>

    <beans:bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
        <beans:property name="loginFormUrl" value="/index.jsp" />
    </beans:bean>

    <!--
    Usernames/Passwords are
        moez/moez
        test/test        
    -->
    <authentication-manager alias="authenticationManager" >
        <authentication-provider>
            <password-encoder hash="md5"/>
            <user-service>
                <user name="moez" password="f69471ca2c42621b8b8e731b2b4446e4" authorities="ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER" />
                <user name="test" password="098f6bcd4621d373cade4e832627b4f6" authorities="ROLE_USER" />                
            </user-service>
        </authentication-provider>
    </authentication-manager>

</beans:beans>



Step4: 
  Now you need to create a jsp page 'main.jsp' in order to call it when you are successfully authenticated.
  Since we use Spring MVC, we will need to create a controller.

public class MainController extends MultiActionController{
 public ModelAndView main(HttpServletRequest request,
   HttpServletResponse response) throws Exception {
  return new ModelAndView("main.jsp");
 }
}


Step5: 
   In the dispatcher-servlet.xml add the following line:

<bean name="/*.htm" class="com.blog.dev.controller.MainController"/>


Step6: 
   In the web.xml add the following code:


    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>



Step7: 
   Deploy your application under tomcat, you can test it with test/test.



Of course, you can add a link disconnect in the main page. So you need:
1- add in the configuration spring file and under the tag http the following tag:

<logout/>

2- add in main.jsp the link disconnect:

<a href="j_spring_security_logout">Logout</a>

Source code (Netbeans project) until http://spring-extjs.googlecode.com/svn/trunk/
  

New features for spring 3.0 here

January 29, 2011

How to add a SOAP header using jax-ws

In this article I will add a security header to the soap request. So I will create a class implementing the interface SOAPHandler and I will override the method handleMessage:



@Override
    public boolean handleMessage(SOAPMessageContext context) {
        String prefixUri = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-";
        String uri = prefixUri + "wssecurity-secext-1.0.xsd";
        String uta = prefixUri + "wssecurity-utility-1.0.xsd";
        String ta = prefixUri + "username-token-profile-1.0#PasswordText";
        Boolean outboundProperty =
            (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (outboundProperty.booleanValue()) {
            try {
                SOAPEnvelope envelope = context.getMessage()
                        .getSOAPPart().getEnvelope();
                SOAPFactory factory = SOAPFactory.newInstance();
                String prefix = "wsse";
                SOAPElement securityElem =
                        factory.createElement("Security",prefix,uri);
                SOAPElement tokenElem =
                        factory.createElement("UsernameToken",prefix,uri);
                tokenElem.addAttribute(QName.valueOf("wsu:Id"),"UsernameToken-2");
                tokenElem.addAttribute(QName.valueOf("xmlns:wsu"), uta);
                SOAPElement userElem =
                        factory.createElement("Username",prefix,uri);
                userElem.addTextNode("myUser");
                SOAPElement pwdElem =
                        factory.createElement("Password",prefix,uri);
                pwdElem.addTextNode("myPwd");
                pwdElem.addAttribute(QName.valueOf("Type"), ta);
                tokenElem.addChildElement(userElem);
                tokenElem.addChildElement(pwdElem);
                securityElem.addChildElement(tokenElem);
                SOAPHeader header = envelope.addHeader();
                header.addChildElement(securityElem);

            } catch (Exception e) {
                System.out.println("Exception in handler: " + e);
            }
        }
        
        return true;
    }


Now, I will add a simple call to this class in my implementation client:


service.setHandlerResolver(new HandlerResolver() {
            @Override
    public List<Handler> getHandlerChain(PortInfo portInfo) {
        List<Handler> handlerList = new ArrayList<Handler>();
        handlerList.add(new MySoapHandler());
        return handlerList;
    }
});