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!

Advertisements





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!






String externalization in Spring 3.1+ with MessageSource [no web.xml]

5 07 2014

spring-logoWhen dealing with translations or keeping text messages in one file you can use embedded Spring engine supporting String externalization with MessageSource Bean. There is a plenty of tutorials how to do it with web.xml based configuration, but not so many of them regarding the new Spring version and Spring boot completely in Java code.

Here I will show how to set up the MessageSource bean, create messages file, use messages both in Java and thymeleaf and a clue how to easily make a translation.

Source code
Get the source code for this tutorial from my GitHub here.

1. Start with the SpringMVC tutorial Code
This tutorial is based on the Spring MVC tutorial, so may want either follow it first, download its source code or if you are advanced enough, the following description should be enough.

2.Create messages text file
Start with defining your messages. Put the definitions in messages.properties file. My messages are as follows:

hello.header=Welcome!
hello.content=Click here to advance to the next page
greeting.header=Hello on a second page!
greeting.content=Click here to go back

The messages.properties file should be placed under the src/main/resources folder. My location is src/main/resources/locale/messages.properties.

3. Configure MessageSource bean to see messages file
In your MVC Spring app configuration (the class marked with @Configuration annotation and extending WebMvcConfigurerAdapter class) configure the MessageSource Bean. Remember to annotate it with @Bean. Here is my config, pointing to locale/ directory in src/main/java/resources/, and setting encoding to UTF-8:

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {

	@Bean
	public MessageSource messageSource() {
		ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
		messageSource.setBasename("locale/messages");
		messageSource.setDefaultEncoding("UTF-8");
		return messageSource;
	}
}

Now when you have bean and messages.properties up and ready, you can use it in Java code and thymeleaf templates.

4. Use messages in a thymeleaf template
To access the message in thymeleaf template you simply query for the desired message key with syntax: #{} in th:text tag. For header element it looks as follows:

<h1 th:text="#{greeting.header}"></h1>

5. Use messages in Java code
I am not sure whether accessing the externalized messages in your Java methods indicates a good MVC design, however if you need to use them – here is how you can do it.

First get access to MessageSource bean by Autowiring it to the constructor or setter and store it in class private field:

private MessageSource messageSource;

@Autowired
public void setMessageSource(MessageSource messageSource) {
	this.messageSource = messageSource;
}

Then you can get the desired message as simple as that:

messageSource.getMessage("hello.content", null, Locale.US);

This will return a string with message text for en_US locale or the default string if implicit message for en_US is not found.

Locale and translations
To provide translation simply prepare the messages.properties for each language you want to support. The locale indicator is in the file name. Here is sample config for english (en), polish (pl) and default locale message files:

messages.properties
messages_en_US.properties
messages_pl_PL.properties

In each file, under the same key, provide the translations for the specific language. Spring will interpret file name and use the file proper for requested locale:
– in Java code you indicate the locale implicit, by passing it to messageSource method
– in thymeleaf the locale is taken from users’ browser setting

Note: Always provide the default messages.properties file with default language so that if implicit locale is not found, the default message will be displayed.

Source code
Get the source code for this tutorial from my GitHub here.

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 website layouts SSI with thymeleaf templates

28 06 2014

Based on application from this post, I will show how to make the MVC app containing two pages, both with the same header and footer, but different contents. I will reuse the header and footer HTML code, to avoid code duplication and follow DRY principle.

What I am going to build

The goal is to have two pages differecing only in body, the header and footer are the same, reused by SSI (Server Side Include)

layout

Get the source code

The source code for this tutorial you can find here. on the GitHub

Build basic MVC Spring app

You can base it, or copy the code from the tutorial in this post

Create Header and Footer contents

Create two HTML files with header and footer content. Mine will be basic ones:

header.html:

<div th:fragment="head" style="background-color: red">
	<h3><i>Spring tutorial header</i></h3>
</div>

footer.html:

<footer th:fragment="foot" style="background-color: yellow;">
  &copy; 2014 Jacek Milewski from <a href="http://www.looksok.wordpress.com">Looks OK!</a>
</footer>

Include fragments in your main pages
Add header and footer divs in your page, and include head and foot fragment from header.html and footer.html:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" 
	xmlns:th="http://www.thymeleaf.org" >
    <head>
        <title>Spring MVC Example</title>
    </head>
    <body>
       	<div th:include="header::head"></div>
    
        <h1>Welcome!</h1>
        <p>Click <a th:href="@{/greeting}">here</a> to advance to the next page.</p>

        <div th:include="footer::foot"></div>

    </body>
</html>

You can do it at any other page you need.

Include or replace?

Here I used th:include, so the header.html was inserted into div element. The other option is to replace that div entirely with fragment content. You can do it with th:replace instead of th:include.

Get the source code

The source code for this tutorial you can find here. on the GitHub

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 MVC application tutorial

21 06 2014

spring-logoI will tutor you to create simple Spring MVC application based on Spring boot. App will have two linked web pages with thymeleaf. The project itself will be made in Eclipse as an Gradle project. Let’s start!

Download Source Code

Source for this tutorial is available here, on GitHub

Create project with Gradle build file

Create build.gradle file. First of all depict repositories and dependencies that you will use for gradle plugins:

buildscript {
    repositories {
        maven { url "http://repo.spring.io/libs-release" }
        mavenLocal()
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.1.RELEASE")
    }
}

Then apply plugins for java, spring-boot and eclipse to have default targets of these plugins:

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'spring-boot'

Now show which java version compliance you want to have, and how your jar file will be named:

sourceCompatibility = 1.6

jar {
    baseName = 'looksok-mvc-demo'
    version =  '0.1.0'
}

And add repositories with dependencies used in your code:

repositories {
    mavenLocal()
    mavenCentral()
    maven { url "http://repo.spring.io/libs-release" }
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-thymeleaf")
    testCompile("junit:junit")
}

Note: Use gradle version 1.1 or higher

Create web page templates in thymeleaf

Start with welcome page in src/main/resources/templates/hello.html with link to greeting page. If gradle did not automatically create directory structure, then create necessary folders on your own.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" 
	xmlns:th="http://www.thymeleaf.org" >
    <head>
        <title>Spring MVC Example</title>
    </head>
    <body>
        <h1>Welcome!</h1>

        <p>Click <a th:href="@{/greeting}">here</a> to advance to the next page.</p>
    </body>
</html>

and second template named greeting.html with link to previous page:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" 
	xmlns:th="http://www.thymeleaf.org" >
    <head>
        <title>Spring MVC Example</title>
    </head>
    <body>
        <h1>Hello on a second page!</h1>

        <p>Click <a th:href="@{/hello}">here</a> to go back.</p>
    </body>
</html>

Configure MVC application components

Now with template pages you need to register controllers that will expose views (templates). Create java class with MVC Configuration (extending WebMvcConfigurerAdapter and market with @Configuration annotation). There override the addViewControllers method and add your views to the registry:

@Configuration
public class MvcConfig extends WebMvcAutoConfigurationAdapter {

	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
		registry.addViewController("/hello").setViewName("hello");
		registry.addViewController("/greeting").setViewName("greeting");
	}
}

Make the Spring boot application executable
Spring boot will compile to Uber jar file with servlet engine embedded. To make it possible, the jar needs to have main class. This is how it should look like:

@EnableAutoConfiguration
@Configuration
@ComponentScan("pl.looksok.spring")
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}
}

Remember about annotations. The configuration annotation to indicate this is Spring config class, EnableAutoConfiguration of servlet engine and ComponentScan with package to scan (package is not mandatory when all @Configuration classes are in the same package).

Compile and run
Execute the command to build spring boot app:

gradle build compile

and to start the application:

java -jar [path_to_your_otput_jar]/looksok-mvc-demo-0.1.0.jar

To launch webpage, access the url:
localhost:8080\hello

Download Source Code

Source for this tutorial is available here, on GitHub

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: