Friday, January 29, 2016

Spring Security: Redirecting to original URL after login

Its simple, monkey friends.

Your springContext.xml file:
Note: always-use-default-target="false" and authentication-success-handler-ref="authenticationSuccessHandler"
...
       <s:http auto-config='true'>
  <s:intercept-url pattern="/secure/**" access="ROLE_WEBUSER" />
  <s:form-login always-use-default-target="false" 
                login-processing-url="/j_spring_security_check"
             login-page="/index.html" 
             authentication-failure-handler-ref="authenticationFailureHandler" 
             authentication-success-handler-ref="authenticationSuccessHandler"
             default-target-url="/secure/alert.html" />
  <s:logout logout-url="/j_spring_security_logout" logout-success-url="/index.jsp" />
  <s:access-denied-handler error-page="/index.html" />
 </s:http>

        <bean id="authenticationSuccessHandler" class="monkey.web.springsecurity.AuthSuccessHandler" />
...


Your class:
package monkey.web.springsecurity;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;

import works.deepdata.deepalert.util.DeepAlertConstants;
import works.deepdata.deepalert.util.StringUtils;

public class AuthSuccessHandler implements AuthenticationSuccessHandler {
    
    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    private static Logger logger = Logger.getLogger(AuthSuccessHandler.class);
    
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            org.springframework.security.core.Authentication authentication) throws IOException, ServletException {
        logger.debug("After successful auth...");        
        String targetUrl = determineTargetUrl(request, response);        
        if (response.isCommitted()) {
            logger.error("Response has already been committed. Unable to redirect to " + targetUrl);
            return;
        }
        redirectStrategy.sendRedirect(request, response, targetUrl);
    }
    
    protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) {
        SavedRequest savedRequest = new HttpSessionRequestCache().getRequest(request, response);
        if (savedRequest != null) {
            String targetUrl = savedRequest.getRedirectUrl();
            if (StringUtils.isNotNullOrBlank(targetUrl)) {
                logger.debug("Redirecting to: "+targetUrl);
                return targetUrl;
            }
        }
        return DeepAlertConstants.DEFAULT_AUTH_URL;
    }
}

Thursday, September 5, 2013

Android - Displaying Formatted Text

Bugging me for a while but all you do is:

Step 1: Format the Java String as html
   String formattedMessage = document.replaceAll("(\\r|\\n)", "<br/>");
   formattedMessage = formattedMessage.replaceAll("\\s", "&nbsp;");

Step 2: Display the text in a pre tags
    StringBuilder sb = new StringBuilder();
    sb.append("<html><body><pre>");
    sb.append(formattedMessage);
    sb.append("</pre></body></html>");
    return sb.toString();

Step 3: Display in an AlertDialog using a WebView
   public void showHtml(String html) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setIcon(R.drawable.dialog_information);    
    WebView webView = new WebView(this);
    webView.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
    webView.loadData(html, "text/html", "utf-8");
    builder.setView(webView);
    builder.show();
  }   

   

Thursday, May 2, 2013

Regular Expressions (Again! Yes, I have forgotten the basics... meh)

So to match a couple of sub-strings, use this: .*(One|Two|Three|Example).*

Monday, October 1, 2012

Now Novel, an online book writing course

For my latest project, please check out the Now Novel website -  it's an online novel writing course designed to get you started quickly.

I had to learn how to program in ruby using ruby on rails (RoR) - I am a Java developer usually, so it was quite a steep learning curve, but very enjoyable. 

I am a new convert to to RoR and was amazed about how quick it was to get a website up and running. For front-end heavy websites, I'd definitely use RoR again. I am really glad that the initial plan of hacking together a WordPress site was abandoned. That would have been php hell!

For more information: I am using Devise for my user registration framework - awesome! Wicked wizard for all the wizards (basically the whole site) and Radar's Forem for the forum. All great libraries that I would recommend to anyone.

Monday, September 27, 2010

GWT: Developer Mode and Spring Contex Listener

I could not get the usual Spring web context listener to work with GWT 2.0.4 in developer mode, running within Eclipse.

Usually the context listener will load the bootstrap Spring files and then parse the classpath to do auowiring, etc. Running the GWT application in Developer mode failed to parse the classpath so any @Autowired annotations threw exceptions with no bean found error message.

The same Spring files loaded fine when loaded "old school way" - IE remove the web context loader listener and use a manual creation of the Spring application context using the same XML files.

Code Change:

In order to get the Developer mode working within Eclipse, I followed what other monkeys had done and nastily copy & paste the GWT class used to start up Developer mode (which is essentially a Jetty-specific class) and made one small change to get it working for Spring classpath parsing.

The class is called com.google.gwt.dev.shell.jetty.JettyLoader
located here: gwt-src-2010-09-02/trunk/dev/core/src (where gwt-src-2010-09-02 is the root of where the GWT code was checked out to from Subversion).

I copy the whole class as a new class called SpringJettyLoader and changed it as follows:
private final ClassLoader bootStrapOnlyClassLoader = new ClassLoader(null) {};
to
private final ClassLoader bootStrapOnlyClassLoader = Thread.currentThread().getContextClassLoader();

I also had to copy the additional class called JettyNullLogger and include it with my new loader class to reduce hassles.

Running GWT Web Application:

A change is required to the Eclipse Run Configuration used to run your GWT web application. Open up the Run Configuration.
On the Server (2nd) tab, uncheck the "Run built-in server" option.
On the Arguments tab, change the current arguments to include your new class as the -server option.
-noserver 
-remoteUI "${gwt_remote_ui_server_port}:${unique_id}" 
-startupUrl PropertyWeb.html 
-server com.tradecraft.property.web.server.jetty.SpringJettyLauncher 
-logLevel INFO 
-war /home/aisling/development/workspaces/workspace2/property-web/war com.tradecraft.property.web.PropertyWeb

Eclipse Classpath:

I was using m2eclipse to do my dependency resolution for me within Eclipse. This ended up being more trouble than it was worth as I kept getting other dependencies includes that I didn't expect. This especially caused issues with Hibernate 3.3.5.FINAL and JPA 1.0 and 2.0.

I ended up putting all my libs in the usual WEB-INF/lib directory and all the other Eclipse projects specifically pointed to those jars.

Eclipse Source Folders Additional Note:

Removing m2eclipse from the projects, left the classes output pointing to /target/classes which is fine but then I attempted to change all the output directories to /bin. The previously added source folders contain to point to the old location and you wonder why nothing works.

It is cleaner to remove all the source folders within each Eclipse project and then re-add them as they then point to where you expect them to.

Thursday, September 16, 2010

GWT: Custom context menu on a Tree

Monkeys, in order to add a custom pop up menu to a tree (or any similar widget I suppose) which is displayed instead of the usual browser's context menu when you right-click on the tree, you can do the following:

Create a Tree class that implements the correct interface for adding a context menu handler:
package com.tradecraft.property.web.client.view.type;

import com.google.gwt.event.dom.client.ContextMenuEvent;
import com.google.gwt.event.dom.client.ContextMenuHandler;
import com.google.gwt.event.dom.client.HasContextMenuHandlers;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Tree;

public class MenuContextTree extends Tree implements HasContextMenuHandlers {

  @Override
  public HandlerRegistration addContextMenuHandler(ContextMenuHandler handler) {
    return addDomHandler(handler, ContextMenuEvent.getType());
  }

}

Then add a handler instance to your tree:
public class PropertyTypesAdminScreen extends BaseClientContentScreen {
  ...
  @Override
  public void initScreenUi() {
    tree = new MenuContextTree();
    tree.addContextMenuHandler(new ContextMenuHandler() {      
      @Override
      public void onContextMenu(ContextMenuEvent event) {
        showContextMenu();
        //Don't let the browser display its default context menu
        event.preventDefault();
      }
    });
    mainPanel.add(tree);
  }

  private void showContextMenu() {
    TreeItem selectedTreeItem = tree.getSelectedItem();
    if (selectedTreeItem != null && selectedTreeItem.getUserObject() != null) {
      //do your thing like display a pop up menu
      MenuDialog menuDialog = new MenuDialog(menuBar);
      menuDialog.showRelativeTo(selectedTreeItem);
    }
  }
}


Wednesday, September 15, 2010

Hibernate SQLQuery

In the last week I have seen this error twice when running native SQL queries to a MySQL database using Hibernate. (I am forced to use SQL - not my first choice.)
No Dialect mapping for JDBC type: -1

It took me a while to find the answer, so I thought I would share.

The problem this time is that the data I was retrieving was a longtext column (not a regular varchar) and this is not automatically mapped by the MySQL dialect (I believe this is fixed in Hibernate 3.5).

I solved the problem by using "addScalar" to define the mapping to use. It worked!


Query query = getSession()
.createSQLQuery("select data from form_data where form_data_id = ?")
.addScalar("data", Hibernate.TEXT)
.setInteger(0, formData.getId());
String oldData = ((String)query.uniqueResult());