Spring MVC application architecture

15 02 2015

Relatively short article explaining fairly complex idea of spring app architecture was published on codebeach:

http://www.codebeach.com/2008/06/spring-mvc-application-architecture.html

View, Controller, Service and Model layer explained in few sentences each. That helped me a lot when beginning Spring development





Spring Boot Security: Custom AuditEvent listener configuration

17 01 2015

Security best practices requires all Authentication related events to be logged in defined format and sometimes event should be handled in special way.

Spring security has its own Security Event log implementation and default repository (in memory repository) If you need to provide your own implementation you need to add custom configuration class.

The class should implement the generic ApplicationListener interface for specified event type. In my example I listen for all events (AbstractAuthenticationEvent type). If you need less, you can specify one of its subclasses only.

Here I only log the event, but you can implement your business logic as required. Event object has a timestamp, remote IP address, user login and event type:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.event.AbstractAuthenticationEvent;
import org.springframework.security.core.Authentication;

@Configuration
public class AuditEventLogConfiguration implements ApplicationListener<AbstractAuthenticationEvent> {

  private final Logger log = LoggerFactory.getLogger(this.getClass());
  
  @Override
  public void onApplicationEvent(AbstractAuthenticationEvent event) {
    //do whatever you need with your event
    log.info(event.toString());
  }
}

Did I help you?
I manage this blog and share my knowledge for free, sacrificing my time. If you appreciate it and find this information helpful, please consider making a donation in order to keep this page alive and improve quality

Donate Button with Credit Cards

Thank You!





HTML 5 Offline Web Application with Spring Boot

30 11 2014

Think of users using your web application from mobile phones when their internet connection breaks down. Native mobile app would still work and cache all user actions, synchronizing them afterwards. HTML5 web apps can also work offline.

Basically it is done by listing the resource files (html, js, images) that browser should cache immadietly and use the cached version when user redirects to it. If internet connection is working, the browser will return the online server version, else, if user is offline the cached version will be used.

Resources to cache can be defined in html headers or in .manifest file. These two locations are interpreted by all modern browsers.

1. Download the code base

This tutorial is based on the source code from SpringBoot MVC Hello World tutorial. All instructions are performed on this code.

2. Create offline.manifest file

In this file you can select the files and resources that will be cached by the browser and used if user requests to connect with server while being disconnected from the Internet. I will create new html file: offline.html and redirect to it if user is offline. My offline.manifest looks as follows:

CACHE MANIFEST
#v1

CACHE:
offline.html

NETWORK:
*

FALLBACK:
/ /offline.html

And is located under the /src/main/resources/static/offline.manifest.

3. Manifest file explained

The manifest file must begin with CACHE MANIFEST. The CACHE: section lists the files that we need for offline use. The NETWORK: section lists any resources that should not be cached. The FALLBACK: section uses the / character to define a URL pattern. It basically asks “is this page in the cache?” If it finds the page there, it displays it. If not, it shows the user the file specified – offline.html.

4. Create the offline.html page

This page will be displayed when user requests any page while being offline. This is static page – not the Spring template, so i simply put it in the /src/main/resources/static folder, next to the offfline.manifest file. The offline.html page content is basic one:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" 
  xmlns:th="http://www.thymeleaf.org" >
    <head>
        <title>Offline Web Application</title>
    </head>
    <body>
        <h1>You are offline</h1>
    </body>
</html>

5. Request to cache resources

To make use of offline.manifest file I point it in my hello.html and greeting.html page head:

<html xmlns="http://www.w3.org/1999/xhtml" 
  xmlns:th="http://www.thymeleaf.org" 
  manifest="offline.manifest">

This way the browser will download the manifest and cache specified resources. Moreover it will add the hello.html and greeting.html to the cache as well

6. Test it

Run spring boot app, and open the url in the browser. When you are on hello page, the browser will cache files for offline use. In Chrome console this is indicated as:

hello:1 Creating Application Cache with manifest http://localhost:8080/offline.manifest
hello:1 Application Cache Checking event
hello:1 Application Cache Downloading event
hello:1 Application Cache Progress event (0 of 1) http://localhost:8080/offline.html
hello:1 Application Cache Progress event (1 of 1) 
hello:1 Application Cache Cached event

Now stop the Spring Boot app and click the url on th page. Since the server is offline, you will be redirected to cached offline.html page (or the greeting.html if it was previously cached). If you try tu go to any other url, for example: http://localhost:8080/someInvalidUrl – then the offline html page will be displayed.

Note: best to be tested in private / incognito browser mode to prevent unwanted cache.

Get the source Code

Full source code for this tutorial you can get at my GitHub under the SpringBootOfflineWebApp tag: https://github.com/yacekmm/looksok/tree/SpringBootOfflineWebApp.

Did I help you?
I manage this blog and share my knowledge for free, sacrificing my time. If you appreciate it and find this information helpful, please consider making a donation in order to keep this page alive and improve quality

Donate Button with Credit Cards

Thank You!





Spring Boot: SSL/HTTPS for embedded Tomcat

22 11 2014

If your Spring Boot app is running on embedded Tomcat, you need to use the TomcatConnectionCustomizer class to set up the HTTPS in Tomcat.

Get the source code

Source Code for this tutorial is available on my github under the SpringBootHttps tag: https://github.com/yacekmm/looksok/tree/SpringBootHttps

1. Prepare keystore and certificate

First you need to have your certificate. If you already have it, go to point 2., else, follow the step 1 and 2 from this tutorial: https://looksok.wordpress.com/2014/11/16/configure-sslhttps-on-tomcat-with-self-signed-certificate/

2. Put your keystore in defined location

You need to locate your keystore file in path on your machine. On my machine this is:

D:\keystore\server.p12

This path I will use in my app configuration.

3. Customize Tomcat Connection

Create class implementing the TomcatConnectorCustomizer, and override its customize(Connection) method. As you can see, in customize() I set exactly the same properties as in stantalone Tomcat xml configuration (see this post). Note that in class constructor I convert the alias string to lowercase – in keystore only these are allowed.

public class MyTomcatConnectionCustomizer implements TomcatConnectorCustomizer {

  private String absoluteKeystoreFile;
  private String keystorePassword;
  private String keystoreType;
  private String keystoreAlias;

  public MyTomcatConnectionCustomizer(String absoluteKeystoreFile,
      String keystorePassword, String keystoreType, String keystoreAlias) {
    this.absoluteKeystoreFile = absoluteKeystoreFile;
    this.keystorePassword = keystorePassword;
    this.keystoreType = keystoreType;
    this.keystoreAlias = keystoreAlias.toLowerCase();

  }

  @Override
  public void customize(Connector connector) {
    connector.setPort(443);
    connector.setSecure(true);
    connector.setScheme("https");
    
    connector.setAttribute("SSLEnabled", true);
        connector.setAttribute("sslProtocol", "TLS");
        connector.setAttribute("protocol", "org.apache.coyote.http11.Http11Protocol");
        connector.setAttribute("clientAuth", false);
        connector.setAttribute("keystoreFile", absoluteKeystoreFile);
        connector.setAttribute("keystoreType", keystoreType);
        connector.setAttribute("keystorePass", keystorePassword);
        connector.setAttribute("keystoreAlias", keystoreAlias);
        connector.setAttribute("keyPass", keystorePassword);
  }
}

4. Create containerCustomizer Bean

Now to use the TomcatConnectionCustomizer, create the bean as follows:

@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() throws FileNotFoundException {

  final String absoluteKeystoreFile = ResourceUtils.getFile("D:\\keystore\\server.p12").getAbsolutePath();

  final TomcatConnectorCustomizer customizer = new MyTomcatConnectionCustomizer(
      absoluteKeystoreFile, "keyPwd", "PKCS12", "keyalias"); 

  return new EmbeddedServletContainerCustomizer() {

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
      if(container instanceof TomcatEmbeddedServletContainerFactory) {
        TomcatEmbeddedServletContainerFactory containerFactory = (TomcatEmbeddedServletContainerFactory) container;
        containerFactory.addConnectorCustomizers(customizer);
      }
    };
  };
}

5. Test it

Start Spring Boot App and go to the:

https:\\127.0.0.1

Your browser will propably warn you about the untrusted certificate:

Przechwytywanie

Note: Don’t use Self_signed certificates in production! Use it only in test / dev environment

Get the source code

Source Code for this tutorial is available on my github under the SpringBootHttps tag: https://github.com/yacekmm/looksok/tree/SpringBootHttps

Did I help you?
I manage this blog and share my knowledge for free, sacrificing my time. If you appreciate it and find this information helpful, please consider making a donation in order to keep this page alive and improve quality

Donate Button with Credit Cards

Thank You!





Spring Security Tutorial: Authorization and user roles

11 11 2014

User authenticated with username and password can access web pages. The second step is to authorize him – decide whether or not he is authorized to access certain resources or not. Spring supports role based authorization. In this tutorial I will show how to assign users a role and how to authorize them.

Use case scenarios

In simpliest case, you can have one role and allow it to access all of your views, or few roles, each authorized to only a subset of resources. For example you can have users with role ‘USER’ that are app users, and ‘ADMIN’ which have more rights and access to admin resources in your webapp.

Download the source code

Full source code for this tutorial is available for download on my git: https://github.com/yacekmm/looksok/tree/RoleBasedAccessTutorial/Spring/SpringSecurity

1. Get the code base

This tutorial is based on the code developed in my previous tutorial. Download the code or follow the tutorial in: Spring Security: Securing your MVC app with basic login and password authentication.

2. What we have now

In the code base you have a method to authenticate user. There is an Autowired configureGlobal() method in a WebSecurityConfigurerAdapter. In it I use the simplest, default in memory authentication, verifying user’s login, password and assigning him a roleUSER‘:

@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
    auth
      .inMemoryAuthentication()
        .withUser("user").password("userPwd").roles("USER");
  }
}

If you are loking for custom authentication method, take a look at the Spring Security Tutorial: Custom authentication engine.

2. Add user with Admin role

Now we want to add the new user with ADMIN role. This is as simple as duplicating the line in previous snippet. My configureGlobal method now is as follows:

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
  auth
    .inMemoryAuthentication()
      .withUser("user").password("userPwd").roles("USER")
      .and()
      .withUser("admin").password("adminPwd").roles("ADMIN");
}

3. Implement role based access

Now when you have two user roles, you can specify wich role will have access to certain resource. In my app I have the hello page and greeting page. I will permit ADMIN role to both of these resources, and USER role only to hello page. Moreover I will require any request to be authenticated, so user must log in. This is how these rules look like in implementation:

protected void configure(HttpSecurity http) throws Exception{

  http
    .formLogin().permitAll()
  .and()
    .authorizeRequests()
    .antMatchers("/hello").hasRole("USER")
    .antMatchers("/hello", "/greeting").hasRole("ADMIN")
    .anyRequest().authenticated();
}

4. Run App and verify

Start the spring boot app and go to the url:

http://localhost:8080/

You will be automatically redirected to the login page. Login as admin:

admin :  adminPwd

after login you will be redirected to Welcome page (hello), and when you click a link, you will be redirected to the greeting page.

Now logout by going to the login page in your app with logout param:

http://localhost:8080/login?logout

And login as user:

user :  userPwd

After logging in, you will also be redirected to the Welcome page, but when you click th link on that page, you will get the Error Page 403, which means that you are not authorized to access it.

5. Provide custom unauthorized page

The spring’s Whitelabel error page is not the best you can have in your app, so let’s configure new template to have nice, custom unauthorized message for your users. To do it, you just create new html template and controller, let’s name it ‘unauthorized’ and add the exception configuration for HttpSecurity in configure method:

.and()
  .exceptionHandling().accessDeniedPage("/unauthorized");

Download the source code

Full source code for this tutorial is available for download on my git: https://github.com/yacekmm/looksok/tree/RoleBasedAccessTutorial/Spring/SpringSecurity

Did I help you?
I manage this blog and share my knowledge for free, sacrificing my time. If you appreciate it and find this information helpful, please consider making a donation in order to keep this page alive and improve quality

Donate Button with Credit Cards

Thank You!






SOAP request in Spring 4: Add Header to SOAP message

27 09 2014

Spring ‘Convention over configuration‘ routine makes it easy to implement basic use cases. But when it comes to advanced configuration, sometimes it can be difficult (see post about authenticating SOAP requests).

Another case is when you need to add SOAP Header to the SOAP message. This time it is however much easier than authenticating requests.

Sending the basic request

Developer has access to the request after it is marshalled, but before it is send. This is the moment when you can modify message by adding header. Following the spring.io site tutorial, you probably know that sending request is done via:

getWebServiceTemplate().marshalSendAndReceive(
	request,
	someSoapActionCallback);

Create class that will modify the request

The someSoapActionCallback will be called after the request is marshalled, and before it is send, allowing you to modify it before sending. So this is a hook where you can modify step of an sending algorythm. This is an instance of a class implementing the WebServiceMessageCallback and overriding its method: doWithMessage(WebServiceMessage message). This is how my class looks like:

public class SoapRequestHeaderModifier implements WebServiceMessageCallback{
	
	@Override
	public void doWithMessage(WebServiceMessage message) throws IOException,
			TransformerException {
		
		SoapHeader header = ((SoapMessage)message).getSoapHeader();
		
		StringSource headerSource = new StringSource(prepareSecurityHeader());
        
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.transform(headerSource, header.getResult());
	}
	
	private String prepareSecurityHeader() {
		String result = "";
		StringWriter sw = new StringWriter();
        try {
            JAXBContext carContext = JAXBContext.newInstance(Security.class);
            Marshaller carMarshaller = carContext.createMarshaller();
            carMarshaller.marshal(SECURITY_HEADER, sw);
            result = sw.toString();
        } catch (JAXBException e) {
            throw new RuntimeException(e);
        }
		return result;
	}
}

Where SECURITY_HEADER is an authentication string required by SOAP server. The Security.class is a data class generated from JAX2B (marshalled from WSDL). And Security class is in fact being added to the SOAP header.

Use the Header Modifier while sending request

I annotated the Header Modifier as a Component and Atowired its instance in a constructor. Thanks to that I can add its instance to the marshall request as folows:

getWebServiceTemplate().marshalSendAndReceive(
       request, 
       soapRequestHeaderModifier);

Now you can ensure that your request header is modified using your favorite SOAP mock client (SoapUI for instance).

Did I help you?
I manage this blog and share my knowledge for free, sacrificing my time. If you appreciate it and find this information helpful, please consider making a donation in order to keep this page alive and improve quality

Donate Button with Credit Cards

Thank You!








%d bloggers like this: