diff --git a/pom.xml b/pom.xml
index d53bf80d88b7cc97a493ee90c09ee624438f4f50..0fc0b3f978b42663ab71b3fd65892b665df6c170 100644
--- a/pom.xml
+++ b/pom.xml
@@ -64,6 +64,10 @@
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter-web</artifactId>
 		</dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
 		<dependency>
 			<groupId>org.hsqldb</groupId>
 			<artifactId>hsqldb</artifactId>
@@ -102,6 +106,11 @@
 			<artifactId>spring-boot-starter-test</artifactId>
 			<scope>test</scope>
 		</dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-test</artifactId>
+            <scope>test</scope>
+        </dependency>
 
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
diff --git a/readme.md b/readme.md
index 0a645e7fcd52cd5dd4e49b3d86a1141201e8db8f..98e7babf1d28f0aae65cdb1bfb90b4a27ff61df3 100644
--- a/readme.md
+++ b/readme.md
@@ -80,6 +80,35 @@ You may also start a Postgres database with docker:
 docker run --name postgres-petclinic -e POSTGRES_PASSWORD=petclinic -e POSTGRES_DB=petclinic -p 5432:5432 -d postgres:9.6.0
 ```
 
+## Security configuration
+In its default configuration, Petclinic doesn't have authentication and authorization enabled.
+
+### Basic Authentication
+In order to use the basic authentication functionality, turn in on from the application.properties file
+```
+basic.authentication.enabled=true
+```
+This will secure all APIs and in order to access them, basic authentication is required.
+Apart from authentication, APIs also require authorization. This is done via roles that a user can have.
+The existing roles are listed below with the corresponding permissions 
+* OWNER_ADMIN -> OwnerController, PetController, PetTypeController (getAllPetTypes and getPetType), VisitController
+* VET_ADMIN   -> PetTypeController, SpecialityController, VetController
+* ADMIN       -> UserController
+
+There is an existing user with the username admin and password admin that has access to all APIs.
+ In order to add a new user, please use the following API:
+```
+POST /api/users
+{
+    "username": "secondAdmin",
+    "password": "password",
+    "enabled": true,
+    "roles": [
+    	{ "name" : "OWNER_ADMIN" }
+	]
+}
+```
+
 ## Working with Petclinic in Eclipse/STS
 
 ### prerequisites
diff --git a/src/main/java/org/springframework/samples/petclinic/model/Role.java b/src/main/java/org/springframework/samples/petclinic/model/Role.java
new file mode 100644
index 0000000000000000000000000000000000000000..8dd19a10274326357bbb66817d04eb7801136d0b
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/model/Role.java
@@ -0,0 +1,39 @@
+package org.springframework.samples.petclinic.model;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+@Entity
+@Table(name = "roles" ,uniqueConstraints = @UniqueConstraint(columnNames = {"username", "role"}))
+public class Role extends BaseEntity {
+
+    @ManyToOne
+    @JoinColumn(name = "username")
+    @JsonIgnore
+    private User user;
+
+    @Column( name = "role")
+    private String name;
+
+    public User getUser() {
+        return user;
+    }
+
+    public void setUser(User user) {
+        this.user = user;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/model/User.java b/src/main/java/org/springframework/samples/petclinic/model/User.java
new file mode 100644
index 0000000000000000000000000000000000000000..1bfe90a418ad20516409bd4d3bc00637f43d0fbe
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/model/User.java
@@ -0,0 +1,74 @@
+package org.springframework.samples.petclinic.model;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+@Entity
+@Table(name = "users")
+public class User {
+
+    @Id
+    @Column(name = "username")
+    private String username;
+
+    @Column(name = "password")
+    private String password;
+
+    @Column(name = "enabled")
+    private Boolean enabled;
+
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "user", fetch = FetchType.EAGER)
+    private Set<Role> roles;
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public Boolean getEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(Boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public Set<Role> getRoles() {
+        return roles;
+    }
+
+    public void setRoles(Set<Role> roles) {
+        this.roles = roles;
+    }
+
+    @JsonIgnore
+    public void addRole(String roleName) {
+        if(this.roles == null) {
+            this.roles = new HashSet<>();
+        }
+        Role role = new Role();
+        role.setName(roleName);
+        this.roles.add(role);
+    }
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/UserRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/UserRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..3e9b45ba7372250ce88a3d935ce3d8d960359892
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/repository/UserRepository.java
@@ -0,0 +1,9 @@
+package org.springframework.samples.petclinic.repository;
+
+import org.springframework.dao.DataAccessException;
+import org.springframework.samples.petclinic.model.User;
+
+public interface UserRepository {
+
+    void save(User user) throws DataAccessException;
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcUserRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcUserRepositoryImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..7fc51ecbd97a5be5549fbecea60cbf68fd56c73f
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcUserRepositoryImpl.java
@@ -0,0 +1,68 @@
+package org.springframework.samples.petclinic.repository.jdbc;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.sql.DataSource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Profile;
+import org.springframework.dao.DataAccessException;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
+import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
+import org.springframework.samples.petclinic.model.Role;
+import org.springframework.samples.petclinic.model.User;
+import org.springframework.samples.petclinic.repository.UserRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+@Profile("jdbc")
+public class JdbcUserRepositoryImpl implements UserRepository {
+
+    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
+    private SimpleJdbcInsert insertUser;
+
+    @Autowired
+    public JdbcUserRepositoryImpl(DataSource dataSource) {
+        this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
+        this.insertUser = new SimpleJdbcInsert(dataSource).withTableName("users");
+    }
+
+    @Override
+    public void save(User user) throws DataAccessException {
+
+        BeanPropertySqlParameterSource parameterSource = new BeanPropertySqlParameterSource(user);
+
+        try {
+            getByUsername(user.getUsername());
+            this.namedParameterJdbcTemplate.update("UPDATE users SET password=:password, enabled=:enabled WHERE username=:username", parameterSource);
+        } catch (EmptyResultDataAccessException e) {
+            this.insertUser.execute(parameterSource);
+        } finally {
+            updateUserRoles(user);
+        }
+    }
+
+    private User getByUsername(String username) {
+
+        Map<String, Object> params = new HashMap<>();
+        params.put("username", username);
+        return this.namedParameterJdbcTemplate.queryForObject("SELECT * FROM users WHERE username=:username",
+            params, BeanPropertyRowMapper.newInstance(User.class));
+    }
+
+    private void updateUserRoles(User user) {
+        Map<String, Object> params = new HashMap<>();
+        params.put("username", user.getUsername());
+        this.namedParameterJdbcTemplate.update("DELETE FROM roles WHERE username=:username", params);
+        for (Role role : user.getRoles()) {
+            params.put("role", role.getName());
+            if (role.getName() != null) {
+                this.namedParameterJdbcTemplate.update("INSERT INTO roles(username, role) VALUES (:username, :role)", params);
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaUserRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaUserRepositoryImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..d73a7e9fbe69b20dd096f3596a6128ef052574c9
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaUserRepositoryImpl.java
@@ -0,0 +1,27 @@
+package org.springframework.samples.petclinic.repository.jpa;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+import org.springframework.context.annotation.Profile;
+import org.springframework.dao.DataAccessException;
+import org.springframework.samples.petclinic.model.User;
+import org.springframework.samples.petclinic.repository.UserRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+@Profile("jpa")
+public class JpaUserRepositoryImpl implements UserRepository {
+
+    @PersistenceContext
+    private EntityManager em;
+
+    @Override
+    public void save(User user) throws DataAccessException {
+        if (this.em.find(User.class, user.getUsername()) == null) {
+            this.em.persist(user);
+        } else {
+            this.em.merge(user);
+        }
+    }
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataUserRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataUserRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..4219df459fa5f8c83126ef5513d67871deda5e45
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataUserRepository.java
@@ -0,0 +1,11 @@
+package org.springframework.samples.petclinic.repository.springdatajpa;
+
+import org.springframework.context.annotation.Profile;
+import org.springframework.data.repository.Repository;
+import org.springframework.samples.petclinic.model.User;
+import org.springframework.samples.petclinic.repository.UserRepository;
+
+@Profile("spring-data-jpa")
+public interface SpringDataUserRepository extends UserRepository, Repository<User, Integer>  {
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/rest/OwnerRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/OwnerRestController.java
index e3b3aadb54dd26f4c800e59442dce6aa526e7118..ff60a276910b999c0af1daf39454b113c25e4c64 100644
--- a/src/main/java/org/springframework/samples/petclinic/rest/OwnerRestController.java
+++ b/src/main/java/org/springframework/samples/petclinic/rest/OwnerRestController.java
@@ -28,6 +28,7 @@ import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.samples.petclinic.model.Owner;
 import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.BindingResult;
 import org.springframework.web.bind.annotation.CrossOrigin;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -50,6 +51,7 @@ public class OwnerRestController {
 	@Autowired
 	private ClinicService clinicService;
 
+	@PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" )
 	@RequestMapping(value = "/*/lastname/{lastName}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Collection<Owner>> getOwnersList(@PathVariable("lastName") String ownerLastName) {
 		if (ownerLastName == null) {
@@ -62,6 +64,7 @@ public class OwnerRestController {
 		return new ResponseEntity<Collection<Owner>>(owners, HttpStatus.OK);
 	}
 
+    @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" )
 	@RequestMapping(value = "", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Collection<Owner>> getOwners() {
 		Collection<Owner> owners = this.clinicService.findAllOwners();
@@ -71,6 +74,7 @@ public class OwnerRestController {
 		return new ResponseEntity<Collection<Owner>>(owners, HttpStatus.OK);
 	}
 
+    @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" )
 	@RequestMapping(value = "/{ownerId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Owner> getOwner(@PathVariable("ownerId") int ownerId) {
 		Owner owner = null;
@@ -81,6 +85,7 @@ public class OwnerRestController {
 		return new ResponseEntity<Owner>(owner, HttpStatus.OK);
 	}
 
+    @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" )
 	@RequestMapping(value = "", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Owner> addOwner(@RequestBody @Valid Owner owner, BindingResult bindingResult,
 			UriComponentsBuilder ucBuilder) {
@@ -96,6 +101,7 @@ public class OwnerRestController {
 		return new ResponseEntity<Owner>(owner, headers, HttpStatus.CREATED);
 	}
 
+    @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" )
 	@RequestMapping(value = "/{ownerId}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Owner> updateOwner(@PathVariable("ownerId") int ownerId, @RequestBody @Valid Owner owner,
 			BindingResult bindingResult, UriComponentsBuilder ucBuilder) {
@@ -119,6 +125,7 @@ public class OwnerRestController {
 		return new ResponseEntity<Owner>(currentOwner, HttpStatus.NO_CONTENT);
 	}
 
+    @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" )
 	@RequestMapping(value = "/{ownerId}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	@Transactional
 	public ResponseEntity<Void> deleteOwner(@PathVariable("ownerId") int ownerId) {
diff --git a/src/main/java/org/springframework/samples/petclinic/rest/PetRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/PetRestController.java
index 6759cdcf050754ebd187c798eda495ca5fa82435..79d971d66a4c1885133384f70e8caa451de9e5ac 100644
--- a/src/main/java/org/springframework/samples/petclinic/rest/PetRestController.java
+++ b/src/main/java/org/springframework/samples/petclinic/rest/PetRestController.java
@@ -29,6 +29,7 @@ import org.springframework.http.ResponseEntity;
 import org.springframework.samples.petclinic.model.Pet;
 import org.springframework.samples.petclinic.model.PetType;
 import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.BindingResult;
 import org.springframework.web.bind.annotation.CrossOrigin;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -51,6 +52,7 @@ public class PetRestController {
 	@Autowired
 	private ClinicService clinicService;
 
+    @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" )
 	@RequestMapping(value = "/{petId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Pet> getPet(@PathVariable("petId") int petId){
 		Pet pet = this.clinicService.findPetById(petId);
@@ -60,6 +62,7 @@ public class PetRestController {
 		return new ResponseEntity<Pet>(pet, HttpStatus.OK);
 	}
 
+    @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" )
 	@RequestMapping(value = "", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Collection<Pet>> getPets(){
 		Collection<Pet> pets = this.clinicService.findAllPets();
@@ -69,11 +72,13 @@ public class PetRestController {
 		return new ResponseEntity<Collection<Pet>>(pets, HttpStatus.OK);
 	}
 
+    @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" )
 	@RequestMapping(value = "/pettypes", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Collection<PetType>> getPetTypes(){
 		return new ResponseEntity<Collection<PetType>>(this.clinicService.findPetTypes(), HttpStatus.OK);
 	}
 
+    @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" )
 	@RequestMapping(value = "", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Pet> addPet(@RequestBody @Valid Pet pet, BindingResult bindingResult, UriComponentsBuilder ucBuilder){
 		BindingErrorsResponse errors = new BindingErrorsResponse();
@@ -88,6 +93,7 @@ public class PetRestController {
 		return new ResponseEntity<Pet>(pet, headers, HttpStatus.CREATED);
 	}
 
+    @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" )
 	@RequestMapping(value = "/{petId}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Pet> updatePet(@PathVariable("petId") int petId, @RequestBody @Valid Pet pet, BindingResult bindingResult){
 		BindingErrorsResponse errors = new BindingErrorsResponse();
@@ -109,6 +115,7 @@ public class PetRestController {
 		return new ResponseEntity<Pet>(currentPet, HttpStatus.NO_CONTENT);
 	}
 
+    @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" )
 	@RequestMapping(value = "/{petId}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	@Transactional
 	public ResponseEntity<Void> deletePet(@PathVariable("petId") int petId){
diff --git a/src/main/java/org/springframework/samples/petclinic/rest/PetTypeRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/PetTypeRestController.java
index 239397c1eedb490283e11d8893538f9f857f08d1..e16f51e81c5b5cac4ec27374873e2091d9af9336 100644
--- a/src/main/java/org/springframework/samples/petclinic/rest/PetTypeRestController.java
+++ b/src/main/java/org/springframework/samples/petclinic/rest/PetTypeRestController.java
@@ -29,6 +29,7 @@ import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.samples.petclinic.model.PetType;
 import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.BindingResult;
 import org.springframework.web.bind.annotation.CrossOrigin;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -42,10 +43,11 @@ import org.springframework.web.util.UriComponentsBuilder;
 @CrossOrigin(exposedHeaders = "errors, content-type")
 @RequestMapping("api/pettypes")
 public class PetTypeRestController {
-	
+
 	@Autowired
 	private ClinicService clinicService;
-	
+
+    @PreAuthorize( "hasAnyRole(@roles.OWNER_ADMIN, @roles.VET_ADMIN)" )
 	@RequestMapping(value = "", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Collection<PetType>> getAllPetTypes(){
 		Collection<PetType> petTypes = new ArrayList<PetType>();
@@ -55,7 +57,8 @@ public class PetTypeRestController {
 		}
 		return new ResponseEntity<Collection<PetType>>(petTypes, HttpStatus.OK);
 	}
-	
+
+    @PreAuthorize( "hasAnyRole(@roles.OWNER_ADMIN, @roles.VET_ADMIN)" )
 	@RequestMapping(value = "/{petTypeId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<PetType> getPetType(@PathVariable("petTypeId") int petTypeId){
 		PetType petType = this.clinicService.findPetTypeById(petTypeId);
@@ -64,8 +67,8 @@ public class PetTypeRestController {
 		}
 		return new ResponseEntity<PetType>(petType, HttpStatus.OK);
 	}
-	
-	
+
+    @PreAuthorize( "hasRole(@roles.VET_ADMIN)" )
 	@RequestMapping(value = "", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<PetType> addPetType(@RequestBody @Valid PetType petType, BindingResult bindingResult, UriComponentsBuilder ucBuilder){
 		BindingErrorsResponse errors = new BindingErrorsResponse();
@@ -79,7 +82,8 @@ public class PetTypeRestController {
 		headers.setLocation(ucBuilder.path("/api/pettypes/{id}").buildAndExpand(petType.getId()).toUri());
 		return new ResponseEntity<PetType>(petType, headers, HttpStatus.CREATED);
 	}
-	
+
+    @PreAuthorize( "hasRole(@roles.VET_ADMIN)" )
 	@RequestMapping(value = "/{petTypeId}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<PetType> updatePetType(@PathVariable("petTypeId") int petTypeId, @RequestBody @Valid PetType petType, BindingResult bindingResult){
 		BindingErrorsResponse errors = new BindingErrorsResponse();
@@ -97,7 +101,8 @@ public class PetTypeRestController {
 		this.clinicService.savePetType(currentPetType);
 		return new ResponseEntity<PetType>(currentPetType, HttpStatus.NO_CONTENT);
 	}
-	
+
+    @PreAuthorize( "hasRole(@roles.VET_ADMIN)" )
 	@RequestMapping(value = "/{petTypeId}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	@Transactional
 	public ResponseEntity<Void> deletePetType(@PathVariable("petTypeId") int petTypeId){
diff --git a/src/main/java/org/springframework/samples/petclinic/rest/SpecialtyRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/SpecialtyRestController.java
index 4ee8829204a1322c51982f284a50ca6f0007dc6e..eb63b7064b43140a50c90d513e3275aa264a1147 100644
--- a/src/main/java/org/springframework/samples/petclinic/rest/SpecialtyRestController.java
+++ b/src/main/java/org/springframework/samples/petclinic/rest/SpecialtyRestController.java
@@ -29,6 +29,7 @@ import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.samples.petclinic.model.Specialty;
 import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.BindingResult;
 import org.springframework.web.bind.annotation.CrossOrigin;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -47,10 +48,11 @@ import org.springframework.web.util.UriComponentsBuilder;
 @CrossOrigin(exposedHeaders = "errors, content-type")
 @RequestMapping("api/specialties")
 public class SpecialtyRestController {
-	
+
 	@Autowired
 	private ClinicService clinicService;
-	
+
+    @PreAuthorize( "hasRole(@roles.VET_ADMIN)" )
 	@RequestMapping(value = "", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Collection<Specialty>> getAllSpecialtys(){
 		Collection<Specialty> specialties = new ArrayList<Specialty>();
@@ -60,7 +62,8 @@ public class SpecialtyRestController {
 		}
 		return new ResponseEntity<Collection<Specialty>>(specialties, HttpStatus.OK);
 	}
-	
+
+    @PreAuthorize( "hasRole(@roles.VET_ADMIN)" )
 	@RequestMapping(value = "/{specialtyId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Specialty> getSpecialty(@PathVariable("specialtyId") int specialtyId){
 		Specialty specialty = this.clinicService.findSpecialtyById(specialtyId);
@@ -69,8 +72,8 @@ public class SpecialtyRestController {
 		}
 		return new ResponseEntity<Specialty>(specialty, HttpStatus.OK);
 	}
-	
-	
+
+    @PreAuthorize( "hasRole(@roles.VET_ADMIN)" )
 	@RequestMapping(value = "", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Specialty> addSpecialty(@RequestBody @Valid Specialty specialty, BindingResult bindingResult, UriComponentsBuilder ucBuilder){
 		BindingErrorsResponse errors = new BindingErrorsResponse();
@@ -84,7 +87,8 @@ public class SpecialtyRestController {
 		headers.setLocation(ucBuilder.path("/api/specialtys/{id}").buildAndExpand(specialty.getId()).toUri());
 		return new ResponseEntity<Specialty>(specialty, headers, HttpStatus.CREATED);
 	}
-	
+
+    @PreAuthorize( "hasRole(@roles.VET_ADMIN)" )
 	@RequestMapping(value = "/{specialtyId}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Specialty> updateSpecialty(@PathVariable("specialtyId") int specialtyId, @RequestBody @Valid Specialty specialty, BindingResult bindingResult){
 		BindingErrorsResponse errors = new BindingErrorsResponse();
@@ -102,7 +106,8 @@ public class SpecialtyRestController {
 		this.clinicService.saveSpecialty(currentSpecialty);
 		return new ResponseEntity<Specialty>(currentSpecialty, HttpStatus.NO_CONTENT);
 	}
-	
+
+    @PreAuthorize( "hasRole(@roles.VET_ADMIN)" )
 	@RequestMapping(value = "/{specialtyId}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	@Transactional
 	public ResponseEntity<Void> deleteSpecialty(@PathVariable("specialtyId") int specialtyId){
diff --git a/src/main/java/org/springframework/samples/petclinic/rest/UserRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/UserRestController.java
new file mode 100644
index 0000000000000000000000000000000000000000..7abb07cb959a3fa0904ec1c85b0636513c9b47f5
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/rest/UserRestController.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2016-2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.samples.petclinic.rest;
+
+import javax.validation.Valid;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.samples.petclinic.model.User;
+import org.springframework.samples.petclinic.service.UserService;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@CrossOrigin(exposedHeaders = "errors, content-type")
+@RequestMapping("api/users")
+public class UserRestController {
+
+    @Autowired
+    private UserService userService;
+
+    @PreAuthorize( "hasRole(@roles.ADMIN)" )
+    @RequestMapping(value = "", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+    public ResponseEntity<User> addOwner(@RequestBody @Valid User user,  BindingResult bindingResult) throws Exception {
+        BindingErrorsResponse errors = new BindingErrorsResponse();
+        HttpHeaders headers = new HttpHeaders();
+        if (bindingResult.hasErrors() || (user == null)) {
+            errors.addAllErrors(bindingResult);
+            headers.add("errors", errors.toJSON());
+            return new ResponseEntity<User>(user, headers, HttpStatus.BAD_REQUEST);
+        }
+
+        this.userService.saveUser(user);
+        return new ResponseEntity<User>(user, headers, HttpStatus.CREATED);
+    }
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/rest/VetRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/VetRestController.java
index b2fd3ee2b1f83de84945faaa40c1b0a99a1bc4f4..c666976e56a477fad5f868af7cecef04b2dfc15c 100644
--- a/src/main/java/org/springframework/samples/petclinic/rest/VetRestController.java
+++ b/src/main/java/org/springframework/samples/petclinic/rest/VetRestController.java
@@ -29,6 +29,7 @@ import org.springframework.http.ResponseEntity;
 import org.springframework.samples.petclinic.model.Specialty;
 import org.springframework.samples.petclinic.model.Vet;
 import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.BindingResult;
 import org.springframework.web.bind.annotation.CrossOrigin;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -47,10 +48,11 @@ import org.springframework.web.util.UriComponentsBuilder;
 @CrossOrigin(exposedHeaders = "errors, content-type")
 @RequestMapping("api/vets")
 public class VetRestController {
-	
+
 	@Autowired
 	private ClinicService clinicService;
-	
+
+    @PreAuthorize( "hasRole(@roles.VET_ADMIN)" )
 	@RequestMapping(value = "", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Collection<Vet>> getAllVets(){
 		Collection<Vet> vets = new ArrayList<Vet>();
@@ -60,7 +62,8 @@ public class VetRestController {
 		}
 		return new ResponseEntity<Collection<Vet>>(vets, HttpStatus.OK);
 	}
-	
+
+    @PreAuthorize( "hasRole(@roles.VET_ADMIN)" )
 	@RequestMapping(value = "/{vetId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Vet> getVet(@PathVariable("vetId") int vetId){
 		Vet vet = this.clinicService.findVetById(vetId);
@@ -69,8 +72,8 @@ public class VetRestController {
 		}
 		return new ResponseEntity<Vet>(vet, HttpStatus.OK);
 	}
-	
-	
+
+    @PreAuthorize( "hasRole(@roles.VET_ADMIN)" )
 	@RequestMapping(value = "", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Vet> addVet(@RequestBody @Valid Vet vet, BindingResult bindingResult, UriComponentsBuilder ucBuilder){
 		BindingErrorsResponse errors = new BindingErrorsResponse();
@@ -84,7 +87,8 @@ public class VetRestController {
 		headers.setLocation(ucBuilder.path("/api/vets/{id}").buildAndExpand(vet.getId()).toUri());
 		return new ResponseEntity<Vet>(vet, headers, HttpStatus.CREATED);
 	}
-	
+
+    @PreAuthorize( "hasRole(@roles.VET_ADMIN)" )
 	@RequestMapping(value = "/{vetId}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Vet> updateVet(@PathVariable("vetId") int vetId, @RequestBody @Valid Vet vet, BindingResult bindingResult){
 		BindingErrorsResponse errors = new BindingErrorsResponse();
@@ -107,7 +111,8 @@ public class VetRestController {
 		this.clinicService.saveVet(currentVet);
 		return new ResponseEntity<Vet>(currentVet, HttpStatus.NO_CONTENT);
 	}
-	
+
+    @PreAuthorize( "hasRole(@roles.VET_ADMIN)" )
 	@RequestMapping(value = "/{vetId}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	@Transactional
 	public ResponseEntity<Void> deleteVet(@PathVariable("vetId") int vetId){
@@ -118,7 +123,7 @@ public class VetRestController {
 		this.clinicService.deleteVet(vet);
 		return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
 	}
-	
-	
+
+
 
 }
diff --git a/src/main/java/org/springframework/samples/petclinic/rest/VisitRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/VisitRestController.java
index dfbbee35c1625badff550d1d0fc40b25abe209fe..ba1638e6f86bae1958e59d9e201b4ed7e0287ef9 100644
--- a/src/main/java/org/springframework/samples/petclinic/rest/VisitRestController.java
+++ b/src/main/java/org/springframework/samples/petclinic/rest/VisitRestController.java
@@ -29,6 +29,7 @@ import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.samples.petclinic.model.Visit;
 import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.BindingResult;
 import org.springframework.web.bind.annotation.CrossOrigin;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -47,10 +48,11 @@ import org.springframework.web.util.UriComponentsBuilder;
 @CrossOrigin(exposedHeaders = "errors, content-type")
 @RequestMapping("api/visits")
 public class VisitRestController {
-	
+
 	@Autowired
 	private ClinicService clinicService;
-	
+
+    @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" )
 	@RequestMapping(value = "", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Collection<Visit>> getAllVisits(){
 		Collection<Visit> visits = new ArrayList<Visit>();
@@ -60,7 +62,8 @@ public class VisitRestController {
 		}
 		return new ResponseEntity<Collection<Visit>>(visits, HttpStatus.OK);
 	}
-	
+
+    @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" )
 	@RequestMapping(value = "/{visitId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Visit> getVisit(@PathVariable("visitId") int visitId){
 		Visit visit = this.clinicService.findVisitById(visitId);
@@ -69,8 +72,8 @@ public class VisitRestController {
 		}
 		return new ResponseEntity<Visit>(visit, HttpStatus.OK);
 	}
-	
-	
+
+    @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" )
 	@RequestMapping(value = "", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Visit> addVisit(@RequestBody @Valid Visit visit, BindingResult bindingResult, UriComponentsBuilder ucBuilder){
 		BindingErrorsResponse errors = new BindingErrorsResponse();
@@ -84,7 +87,8 @@ public class VisitRestController {
 		headers.setLocation(ucBuilder.path("/api/visits/{id}").buildAndExpand(visit.getId()).toUri());
 		return new ResponseEntity<Visit>(visit, headers, HttpStatus.CREATED);
 	}
-	
+
+    @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" )
 	@RequestMapping(value = "/{visitId}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	public ResponseEntity<Visit> updateVisit(@PathVariable("visitId") int visitId, @RequestBody @Valid Visit visit, BindingResult bindingResult){
 		BindingErrorsResponse errors = new BindingErrorsResponse();
@@ -104,7 +108,8 @@ public class VisitRestController {
 		this.clinicService.saveVisit(currentVisit);
 		return new ResponseEntity<Visit>(currentVisit, HttpStatus.NO_CONTENT);
 	}
-	
+
+    @PreAuthorize( "hasRole(@roles.OWNER_ADMIN)" )
 	@RequestMapping(value = "/{visitId}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
 	@Transactional
 	public ResponseEntity<Void> deleteVisit(@PathVariable("visitId") int visitId){
diff --git a/src/main/java/org/springframework/samples/petclinic/security/BasicAuthenticationAdapter.java b/src/main/java/org/springframework/samples/petclinic/security/BasicAuthenticationAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..b9c9dfb09fbd3acea2c91dc91ba263f071dd0572
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/security/BasicAuthenticationAdapter.java
@@ -0,0 +1,41 @@
+package org.springframework.samples.petclinic.security;
+
+import javax.sql.DataSource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+@ConditionalOnProperty( "basic.authentication.enabled" )
+public class BasicAuthenticationAdapter extends WebSecurityConfigurerAdapter {
+
+    @Autowired
+    private DataSource dataSource;
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http.authorizeRequests()
+                .antMatchers("/securityNone").permitAll()
+                .anyRequest().authenticated()
+                .and()
+            .httpBasic().and()
+            .csrf().disable();
+    }
+
+    @Autowired
+    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
+        auth
+            .jdbcAuthentication()
+                .dataSource(dataSource)
+                .usersByUsernameQuery("select username,password,enabled from users where username=?")
+                .authoritiesByUsernameQuery("select username,role from roles where username=?");
+    }
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/security/Roles.java b/src/main/java/org/springframework/samples/petclinic/security/Roles.java
new file mode 100644
index 0000000000000000000000000000000000000000..d60f04972284faeaf0259966ae220fc3061bc9d8
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/security/Roles.java
@@ -0,0 +1,11 @@
+package org.springframework.samples.petclinic.security;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class Roles {
+
+    public final String OWNER_ADMIN = "ROLE_OWNER_ADMIN";
+    public final String VET_ADMIN = "ROLE_VET_ADMIN";
+    public final String ADMIN = "ROLE_ADMIN";
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/service/UserService.java b/src/main/java/org/springframework/samples/petclinic/service/UserService.java
new file mode 100644
index 0000000000000000000000000000000000000000..e637e5ecf5bb89ec0be2b58a1ea60e3caf4a0c8c
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/service/UserService.java
@@ -0,0 +1,8 @@
+package org.springframework.samples.petclinic.service;
+
+import org.springframework.samples.petclinic.model.User;
+
+public interface UserService {
+
+    void saveUser(User user) throws Exception;
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/service/UserServiceImpl.java b/src/main/java/org/springframework/samples/petclinic/service/UserServiceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..1075640a1017fc0a62911070354bb45a6fe87033
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/service/UserServiceImpl.java
@@ -0,0 +1,36 @@
+package org.springframework.samples.petclinic.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.samples.petclinic.model.User;
+import org.springframework.samples.petclinic.model.Role;
+import org.springframework.samples.petclinic.repository.UserRepository;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class UserServiceImpl implements UserService {
+
+    @Autowired
+    private UserRepository userRepository;
+
+    @Override
+    @Transactional
+    public void saveUser(User user) throws Exception {
+
+        if(user.getRoles() == null || user.getRoles().isEmpty()) {
+            throw new Exception("User must have at least a role set!");
+        }
+
+        for (Role role : user.getRoles()) {
+            if(!role.getName().startsWith("ROLE_")) {
+                role.setName("ROLE_" + role.getName());
+            }
+
+            if(role.getUser() == null) {
+                role.setUser(user);
+            }
+        }
+
+        userRepository.save(user);
+    }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 13904f040be640ef652547e0f850d236e1b46134..77f1022a6db6dfcb1f3f690d8e2bbeaf881b1211 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -30,3 +30,8 @@ logging.level.org.springframework=INFO
 
 #logging.level.org.hibernate.SQL=DEBUG
 #logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
+
+# enable the desired authentication type
+# by default the authentication is disabled
+security.ignored=/**
+basic.authentication.enabled=false
diff --git a/src/main/resources/db/hsqldb/initDB.sql b/src/main/resources/db/hsqldb/initDB.sql
index f3c6947b7db1408f9f5d68b2d5c69a736b21df66..d14ecf3c29f78b85d34aa72d0bbe4503f2361b90 100644
--- a/src/main/resources/db/hsqldb/initDB.sql
+++ b/src/main/resources/db/hsqldb/initDB.sql
@@ -5,6 +5,8 @@ DROP TABLE visits IF EXISTS;
 DROP TABLE pets IF EXISTS;
 DROP TABLE types IF EXISTS;
 DROP TABLE owners IF EXISTS;
+DROP TABLE roles IF EXISTS;
+DROP TABLE users IF EXISTS;
 
 
 CREATE TABLE vets (
@@ -62,3 +64,19 @@ CREATE TABLE visits (
 );
 ALTER TABLE visits ADD CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets (id);
 CREATE INDEX visits_pet_id ON visits (pet_id);
+
+CREATE  TABLE users (
+  username    VARCHAR(20) NOT NULL ,
+  password    VARCHAR(20) NOT NULL ,
+  enabled     BOOLEAN DEFAULT TRUE NOT NULL ,
+  PRIMARY KEY (username)
+);
+
+CREATE TABLE roles (
+  id              INTEGER IDENTITY PRIMARY KEY,
+  username        VARCHAR(20) NOT NULL,
+  role            VARCHAR(20) NOT NULL
+);
+ALTER TABLE roles ADD CONSTRAINT fk_username FOREIGN KEY (username) REFERENCES users (username);
+CREATE INDEX fk_username_idx ON roles (username);
+
diff --git a/src/main/resources/db/hsqldb/populateDB.sql b/src/main/resources/db/hsqldb/populateDB.sql
index 16dda3e8485cd38ddb915f4360d9fff7c213d40b..01a0f404cda03db7f52149519c2e110658f80346 100644
--- a/src/main/resources/db/hsqldb/populateDB.sql
+++ b/src/main/resources/db/hsqldb/populateDB.sql
@@ -51,3 +51,9 @@ INSERT INTO visits VALUES (1, 7, '2013-01-01', 'rabies shot');
 INSERT INTO visits VALUES (2, 8, '2013-01-02', 'rabies shot');
 INSERT INTO visits VALUES (3, 8, '2013-01-03', 'neutered');
 INSERT INTO visits VALUES (4, 7, '2013-01-04', 'spayed');
+
+INSERT INTO users(username,password,enabled) VALUES ('admin','admin', true);
+
+INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_OWNER_ADMIN');
+INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_VET_ADMIN');
+INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_ADMIN');
diff --git a/src/main/resources/db/mysql/initDB.sql b/src/main/resources/db/mysql/initDB.sql
index 6a982598373c3d641bea6d33bcfa8e9f417629e4..b7ab4c82d8f417cb651fdb250b0cc9a85844915c 100644
--- a/src/main/resources/db/mysql/initDB.sql
+++ b/src/main/resources/db/mysql/initDB.sql
@@ -63,3 +63,20 @@ CREATE TABLE IF NOT EXISTS visits (
   description VARCHAR(255),
   FOREIGN KEY (pet_id) REFERENCES pets(id)
 ) engine=InnoDB;
+
+CREATE TABLE IF NOT EXISTS users (
+  username VARCHAR(20) NOT NULL ,
+  password VARCHAR(20) NOT NULL ,
+  enabled TINYINT NOT NULL DEFAULT 1 ,
+  PRIMARY KEY (username)
+) engine=InnoDB;
+
+CREATE TABLE IF NOT EXISTS roles (
+  id int(11) NOT NULL AUTO_INCREMENT,
+  username varchar(20) NOT NULL,
+  role varchar(20) NOT NULL,
+  PRIMARY KEY (id),
+  UNIQUE KEY uni_username_role (role,username),
+  KEY fk_username_idx (username),
+  CONSTRAINT fk_username FOREIGN KEY (username) REFERENCES users (username)
+) engine=InnoDB;
diff --git a/src/main/resources/db/mysql/populateDB.sql b/src/main/resources/db/mysql/populateDB.sql
index 3f1dcf8ea161c9ab2baa54e2b2a2ac55bf381458..48a354697ceee8f0489d0a2c291632fd01b4e9a3 100644
--- a/src/main/resources/db/mysql/populateDB.sql
+++ b/src/main/resources/db/mysql/populateDB.sql
@@ -51,3 +51,9 @@ INSERT IGNORE INTO visits VALUES (1, 7, '2010-03-04', 'rabies shot');
 INSERT IGNORE INTO visits VALUES (2, 8, '2011-03-04', 'rabies shot');
 INSERT IGNORE INTO visits VALUES (3, 8, '2009-06-04', 'neutered');
 INSERT IGNORE INTO visits VALUES (4, 7, '2008-09-04', 'spayed');
+
+INSERT IGNORE INTO users(username,password,enabled) VALUES ('admin','admin', true);
+
+INSERT IGNORE INTO roles (username, role) VALUES ('admin', 'ROLE_OWNER_ADMIN');
+INSERT IGNORE INTO roles (username, role) VALUES ('admin', 'ROLE_VET_ADMIN');
+INSERT IGNORE INTO roles (username, role) VALUES ('admin', 'ROLE_ADMIN');
diff --git a/src/main/resources/db/postgresql/initDB.sql b/src/main/resources/db/postgresql/initDB.sql
index 8fa482a364685579d1831af1c91d1e74ba0c9aae..49f997b76d5a983bc45d2e2ff5fe114a925f0266 100644
--- a/src/main/resources/db/postgresql/initDB.sql
+++ b/src/main/resources/db/postgresql/initDB.sql
@@ -82,3 +82,21 @@ CREATE TABLE IF NOT EXISTS visits (
 );
 
 ALTER SEQUENCE visits_id_seq RESTART WITH 100;
+
+CREATE TABLE IF NOT EXISTS users (
+  username VARCHAR(20) NOT NULL ,
+  password VARCHAR(20) NOT NULL ,
+  enabled boolean NOT NULL DEFAULT true ,
+  CONSTRAINT pk_users PRIMARY KEY (username)
+);
+
+CREATE TABLE IF NOT EXISTS roles (
+  id SERIAL,
+  username varchar(20) NOT NULL,
+  role varchar(20) NOT NULL,
+  CONSTRAINT pk_roles PRIMARY KEY (id),
+  FOREIGN KEY (username) REFERENCES users (username)
+);
+
+ALTER TABLE roles ADD CONSTRAINT uni_username_role UNIQUE (role,username);
+ALTER SEQUENCE roles_id_seq RESTART WITH 100;
diff --git a/src/main/resources/db/postgresql/populateDB.sql b/src/main/resources/db/postgresql/populateDB.sql
index 0f7a94dc7258b0aa750e88414ebe6a5213d9f98f..2c429485a28796d49457020f7d4298b7ee7be4a2 100644
--- a/src/main/resources/db/postgresql/populateDB.sql
+++ b/src/main/resources/db/postgresql/populateDB.sql
@@ -51,3 +51,9 @@ INSERT INTO visits VALUES (1, 7, '2010-03-04', 'rabies shot') ON CONFLICT DO NOT
 INSERT INTO visits VALUES (2, 8, '2011-03-04', 'rabies shot') ON CONFLICT DO NOTHING;
 INSERT INTO visits VALUES (3, 8, '2009-06-04', 'neutered') ON CONFLICT DO NOTHING;
 INSERT INTO visits VALUES (4, 7, '2008-09-04', 'spayed') ON CONFLICT DO NOTHING;
+
+INSERT INTO users(username,password,enabled) VALUES ('admin','admin', true) ON CONFLICT DO NOTHING;
+
+INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_OWNER_ADMIN') ON CONFLICT DO NOTHING;
+INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_VET_ADMIN') ON CONFLICT DO NOTHING;
+INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_ADMIN') ON CONFLICT DO NOTHING;
diff --git a/src/test/java/org/springframework/samples/petclinic/rest/OwnerRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/OwnerRestControllerTests.java
index d52242742c3afa1cbbb51e92d5f7103cdabb4203..75d8f5f8b149feee863993e5b111c8b20ddb56f3 100644
--- a/src/test/java/org/springframework/samples/petclinic/rest/OwnerRestControllerTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/rest/OwnerRestControllerTests.java
@@ -36,8 +36,9 @@ import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.http.MediaType;
 import org.springframework.samples.petclinic.model.Owner;
-import org.springframework.samples.petclinic.service.ApplicationTestConfig;
+import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig;
 import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 import org.springframework.test.context.web.WebAppConfiguration;
@@ -115,6 +116,7 @@ public class OwnerRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testGetOwnerSuccess() throws Exception {
     	given(this.clinicService.findOwnerById(1)).willReturn(owners.get(0));
         this.mockMvc.perform(get("/api/owners/1")
@@ -126,6 +128,7 @@ public class OwnerRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testGetOwnerNotFound() throws Exception {
     	given(this.clinicService.findOwnerById(-1)).willReturn(null);
         this.mockMvc.perform(get("/api/owners/-1")
@@ -134,6 +137,7 @@ public class OwnerRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testGetOwnersListSuccess() throws Exception {
     	owners.remove(0);
     	owners.remove(1);
@@ -149,6 +153,7 @@ public class OwnerRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testGetOwnersListNotFound() throws Exception {
     	owners.clear();
     	given(this.clinicService.findOwnerByLastName("0")).willReturn(owners);
@@ -158,6 +163,7 @@ public class OwnerRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testGetAllOwnersSuccess() throws Exception {
     	owners.remove(0);
     	owners.remove(1);
@@ -173,6 +179,7 @@ public class OwnerRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testGetAllOwnersNotFound() throws Exception {
     	owners.clear();
     	given(this.clinicService.findAllOwners()).willReturn(owners);
@@ -182,6 +189,7 @@ public class OwnerRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testCreateOwnerSuccess() throws Exception {
     	Owner newOwner = owners.get(0);
     	newOwner.setId(999);
@@ -193,6 +201,7 @@ public class OwnerRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testCreateOwnerError() throws Exception {
     	Owner newOwner = owners.get(0);
     	newOwner.setId(null);
@@ -205,6 +214,7 @@ public class OwnerRestControllerTests {
      }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testUpdateOwnerSuccess() throws Exception {
     	given(this.clinicService.findOwnerById(1)).willReturn(owners.get(0));
     	Owner newOwner = owners.get(0);
@@ -226,6 +236,7 @@ public class OwnerRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testUpdateOwnerError() throws Exception {
     	Owner newOwner = owners.get(0);
     	newOwner.setFirstName("");
@@ -237,6 +248,7 @@ public class OwnerRestControllerTests {
      }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testDeleteOwnerSuccess() throws Exception {
     	Owner newOwner = owners.get(0);
     	ObjectMapper mapper = new ObjectMapper();
@@ -248,6 +260,7 @@ public class OwnerRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testDeleteOwnerError() throws Exception {
     	Owner newOwner = owners.get(0);
     	ObjectMapper mapper = new ObjectMapper();
diff --git a/src/test/java/org/springframework/samples/petclinic/rest/PetRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/PetRestControllerTests.java
index 178d7178db6f77e49fe52c14e81873a833d38d50..1a421170ab6cf182dd8b601551853bba1c8c7d5f 100644
--- a/src/test/java/org/springframework/samples/petclinic/rest/PetRestControllerTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/rest/PetRestControllerTests.java
@@ -39,8 +39,9 @@ import org.springframework.http.MediaType;
 import org.springframework.samples.petclinic.model.Owner;
 import org.springframework.samples.petclinic.model.Pet;
 import org.springframework.samples.petclinic.model.PetType;
-import org.springframework.samples.petclinic.service.ApplicationTestConfig;
+import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig;
 import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 import org.springframework.test.context.web.WebAppConfiguration;
@@ -109,6 +110,7 @@ public class PetRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testGetPetSuccess() throws Exception {
     	given(this.clinicService.findPetById(3)).willReturn(pets.get(0));
         this.mockMvc.perform(get("/api/pets/3")
@@ -120,6 +122,7 @@ public class PetRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testGetPetNotFound() throws Exception {
     	given(this.clinicService.findPetById(-1)).willReturn(null);
         this.mockMvc.perform(get("/api/pets/-1")
@@ -128,6 +131,7 @@ public class PetRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testGetAllPetsSuccess() throws Exception {
     	given(this.clinicService.findAllPets()).willReturn(pets);
         this.mockMvc.perform(get("/api/pets/")
@@ -141,6 +145,7 @@ public class PetRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testGetAllPetsNotFound() throws Exception {
     	pets.clear();
     	given(this.clinicService.findAllPets()).willReturn(pets);
@@ -150,6 +155,7 @@ public class PetRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testCreatePetSuccess() throws Exception {
     	Pet newPet = pets.get(0);
     	newPet.setId(999);
@@ -161,6 +167,7 @@ public class PetRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testCreatePetError() throws Exception {
     	Pet newPet = pets.get(0);
     	newPet.setId(null);
@@ -173,6 +180,7 @@ public class PetRestControllerTests {
      }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testUpdatePetSuccess() throws Exception {
     	given(this.clinicService.findPetById(3)).willReturn(pets.get(0));
     	Pet newPet = pets.get(0);
@@ -194,6 +202,7 @@ public class PetRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testUpdatePetError() throws Exception {
     	Pet newPet = pets.get(0);
     	newPet.setName("");
@@ -205,6 +214,7 @@ public class PetRestControllerTests {
      }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testDeletePetSuccess() throws Exception {
     	Pet newPet = pets.get(0);
     	ObjectMapper mapper = new ObjectMapper();
@@ -216,6 +226,7 @@ public class PetRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testDeletePetError() throws Exception {
     	Pet newPet = pets.get(0);
     	ObjectMapper mapper = new ObjectMapper();
diff --git a/src/test/java/org/springframework/samples/petclinic/rest/PetTypeRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/PetTypeRestControllerTests.java
index 4b11bf3330627d97702bb8626251cdac3b498e96..e0a3c7cb0d2865c0f7ca85a4a05ea2b4a25274e6 100644
--- a/src/test/java/org/springframework/samples/petclinic/rest/PetTypeRestControllerTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/rest/PetTypeRestControllerTests.java
@@ -36,8 +36,9 @@ import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.http.MediaType;
 import org.springframework.samples.petclinic.model.PetType;
-import org.springframework.samples.petclinic.service.ApplicationTestConfig;
+import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig;
 import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 import org.springframework.test.context.web.WebAppConfiguration;
@@ -97,7 +98,8 @@ public class PetTypeRestControllerTests {
     }
 
     @Test
-    public void testGetPetTypeSuccess() throws Exception {
+    @WithMockUser(roles="OWNER_ADMIN")
+    public void testGetPetTypeSuccessAsOwnerAdmin() throws Exception {
     	given(this.clinicService.findPetTypeById(1)).willReturn(petTypes.get(0));
         this.mockMvc.perform(get("/api/pettypes/1")
         	.accept(MediaType.APPLICATION_JSON_VALUE))
@@ -108,6 +110,19 @@ public class PetTypeRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
+    public void testGetPetTypeSuccessAsVetAdmin() throws Exception {
+        given(this.clinicService.findPetTypeById(1)).willReturn(petTypes.get(0));
+        this.mockMvc.perform(get("/api/pettypes/1")
+            .accept(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json;charset=UTF-8"))
+            .andExpect(jsonPath("$.id").value(1))
+            .andExpect(jsonPath("$.name").value("cat"));
+    }
+
+    @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testGetPetTypeNotFound() throws Exception {
     	given(this.clinicService.findPetTypeById(-1)).willReturn(null);
         this.mockMvc.perform(get("/api/pettypes/-1")
@@ -116,7 +131,8 @@ public class PetTypeRestControllerTests {
     }
 
     @Test
-    public void testGetAllPetTypesSuccess() throws Exception {
+    @WithMockUser(roles="OWNER_ADMIN")
+    public void testGetAllPetTypesSuccessAsOwnerAdmin() throws Exception {
     	petTypes.remove(0);
     	petTypes.remove(1);
     	given(this.clinicService.findAllPetTypes()).willReturn(petTypes);
@@ -131,6 +147,23 @@ public class PetTypeRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
+    public void testGetAllPetTypesSuccessAsVetAdmin() throws Exception {
+        petTypes.remove(0);
+        petTypes.remove(1);
+        given(this.clinicService.findAllPetTypes()).willReturn(petTypes);
+        this.mockMvc.perform(get("/api/pettypes/")
+            .accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json;charset=UTF-8"))
+            .andExpect(jsonPath("$.[0].id").value(2))
+            .andExpect(jsonPath("$.[0].name").value("dog"))
+            .andExpect(jsonPath("$.[1].id").value(4))
+            .andExpect(jsonPath("$.[1].name").value("snake"));
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testGetAllPetTypesNotFound() throws Exception {
     	petTypes.clear();
     	given(this.clinicService.findAllPetTypes()).willReturn(petTypes);
@@ -140,6 +173,7 @@ public class PetTypeRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testCreatePetTypeSuccess() throws Exception {
     	PetType newPetType = petTypes.get(0);
     	newPetType.setId(999);
@@ -151,6 +185,7 @@ public class PetTypeRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testCreatePetTypeError() throws Exception {
     	PetType newPetType = petTypes.get(0);
     	newPetType.setId(null);
@@ -163,6 +198,7 @@ public class PetTypeRestControllerTests {
      }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testUpdatePetTypeSuccess() throws Exception {
     	given(this.clinicService.findPetTypeById(2)).willReturn(petTypes.get(1));
     	PetType newPetType = petTypes.get(1);
@@ -183,6 +219,7 @@ public class PetTypeRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testUpdatePetTypeError() throws Exception {
     	PetType newPetType = petTypes.get(0);
     	newPetType.setName("");
@@ -194,6 +231,7 @@ public class PetTypeRestControllerTests {
      }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testDeletePetTypeSuccess() throws Exception {
     	PetType newPetType = petTypes.get(0);
     	ObjectMapper mapper = new ObjectMapper();
@@ -205,6 +243,7 @@ public class PetTypeRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testDeletePetTypeError() throws Exception {
     	PetType newPetType = petTypes.get(0);
     	ObjectMapper mapper = new ObjectMapper();
diff --git a/src/test/java/org/springframework/samples/petclinic/rest/SpecialtyRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/SpecialtyRestControllerTests.java
index 4b0c527225cc14b189494a9c276f80f1f8b2fe45..1f99c1cccda0fe6dc39c216b4e469098a701e833 100644
--- a/src/test/java/org/springframework/samples/petclinic/rest/SpecialtyRestControllerTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/rest/SpecialtyRestControllerTests.java
@@ -36,8 +36,9 @@ import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.http.MediaType;
 import org.springframework.samples.petclinic.model.Specialty;
-import org.springframework.samples.petclinic.service.ApplicationTestConfig;
+import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig;
 import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 import org.springframework.test.context.web.WebAppConfiguration;
@@ -92,6 +93,7 @@ public class SpecialtyRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testGetSpecialtySuccess() throws Exception {
     	given(this.clinicService.findSpecialtyById(1)).willReturn(specialties.get(0));
         this.mockMvc.perform(get("/api/specialties/1")
@@ -103,6 +105,7 @@ public class SpecialtyRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testGetSpecialtyNotFound() throws Exception {
     	given(this.clinicService.findSpecialtyById(-1)).willReturn(null);
         this.mockMvc.perform(get("/api/specialties/-1")
@@ -111,6 +114,7 @@ public class SpecialtyRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testGetAllSpecialtysSuccess() throws Exception {
     	specialties.remove(0);
     	given(this.clinicService.findAllSpecialties()).willReturn(specialties);
@@ -125,6 +129,7 @@ public class SpecialtyRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testGetAllSpecialtysNotFound() throws Exception {
     	specialties.clear();
     	given(this.clinicService.findAllSpecialties()).willReturn(specialties);
@@ -134,6 +139,7 @@ public class SpecialtyRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testCreateSpecialtySuccess() throws Exception {
     	Specialty newSpecialty = specialties.get(0);
     	newSpecialty.setId(999);
@@ -145,6 +151,7 @@ public class SpecialtyRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testCreateSpecialtyError() throws Exception {
     	Specialty newSpecialty = specialties.get(0);
     	newSpecialty.setId(null);
@@ -157,6 +164,7 @@ public class SpecialtyRestControllerTests {
      }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testUpdateSpecialtySuccess() throws Exception {
     	given(this.clinicService.findSpecialtyById(2)).willReturn(specialties.get(1));
     	Specialty newSpecialty = specialties.get(1);
@@ -177,6 +185,7 @@ public class SpecialtyRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testUpdateSpecialtyError() throws Exception {
     	Specialty newSpecialty = specialties.get(0);
     	newSpecialty.setName("");
@@ -188,6 +197,7 @@ public class SpecialtyRestControllerTests {
      }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testDeleteSpecialtySuccess() throws Exception {
     	Specialty newSpecialty = specialties.get(0);
     	ObjectMapper mapper = new ObjectMapper();
@@ -199,6 +209,7 @@ public class SpecialtyRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testDeleteSpecialtyError() throws Exception {
     	Specialty newSpecialty = specialties.get(0);
     	ObjectMapper mapper = new ObjectMapper();
diff --git a/src/test/java/org/springframework/samples/petclinic/rest/UserRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/UserRestControllerTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..c16676407ec4a00a3967d6f473c1f527b34a6c8b
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/rest/UserRestControllerTests.java
@@ -0,0 +1,74 @@
+package org.springframework.samples.petclinic.rest;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.samples.petclinic.model.User;
+import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig;
+import org.springframework.samples.petclinic.service.UserService;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@SpringBootTest
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = ApplicationTestConfig.class)
+@WebAppConfiguration
+public class UserRestControllerTests {
+
+    @Mock
+    private UserService userService;
+
+    @Autowired
+    private UserRestController userRestController;
+
+    private MockMvc mockMvc;
+
+    @Before
+    public void initVets() {
+        this.mockMvc = MockMvcBuilders.standaloneSetup(userRestController)
+            .setControllerAdvice(new ExceptionControllerAdvice()).build();
+    }
+
+    @Test
+    @WithMockUser(roles="ADMIN")
+    public void testCreateUserSuccess() throws Exception {
+        User user = new User();
+        user.setUsername("username");
+        user.setPassword("password");
+        user.setEnabled(true);
+        user.addRole( "OWNER_ADMIN" );
+        ObjectMapper mapper = new ObjectMapper();
+        String newVetAsJSON = mapper.writeValueAsString(user);
+        this.mockMvc.perform(post("/api/users/")
+            .content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isCreated());
+    }
+
+    @Test
+    @WithMockUser(roles="ADMIN")
+    public void testCreateUserError() throws Exception {
+        User user = new User();
+        user.setUsername("username");
+        user.setPassword("password");
+        user.setEnabled(true);
+        ObjectMapper mapper = new ObjectMapper();
+        String newVetAsJSON = mapper.writeValueAsString(user);
+        this.mockMvc.perform(post("/api/users/")
+            .content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isBadRequest());
+    }
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/rest/VetRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/VetRestControllerTests.java
index a1adbea6bb513a7425ec45c55db7d5fe2e42aced..9358b6daf6aded04b881854361a5195723952c00 100644
--- a/src/test/java/org/springframework/samples/petclinic/rest/VetRestControllerTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/rest/VetRestControllerTests.java
@@ -36,8 +36,9 @@ import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.http.MediaType;
 import org.springframework.samples.petclinic.model.Vet;
-import org.springframework.samples.petclinic.service.ApplicationTestConfig;
+import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig;
 import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 import org.springframework.test.context.web.WebAppConfiguration;
@@ -95,6 +96,7 @@ public class VetRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testGetVetSuccess() throws Exception {
     	given(this.clinicService.findVetById(1)).willReturn(vets.get(0));
         this.mockMvc.perform(get("/api/vets/1")
@@ -106,6 +108,7 @@ public class VetRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testGetVetNotFound() throws Exception {
     	given(this.clinicService.findVetById(-1)).willReturn(null);
         this.mockMvc.perform(get("/api/vets/-1")
@@ -114,6 +117,7 @@ public class VetRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testGetAllVetsSuccess() throws Exception {
     	given(this.clinicService.findAllVets()).willReturn(vets);
         this.mockMvc.perform(get("/api/vets/")
@@ -127,6 +131,7 @@ public class VetRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testGetAllVetsNotFound() throws Exception {
     	vets.clear();
     	given(this.clinicService.findAllVets()).willReturn(vets);
@@ -136,6 +141,7 @@ public class VetRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testCreateVetSuccess() throws Exception {
     	Vet newVet = vets.get(0);
     	newVet.setId(999);
@@ -147,6 +153,7 @@ public class VetRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testCreateVetError() throws Exception {
     	Vet newVet = vets.get(0);
     	newVet.setId(null);
@@ -159,6 +166,7 @@ public class VetRestControllerTests {
      }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testUpdateVetSuccess() throws Exception {
     	given(this.clinicService.findVetById(1)).willReturn(vets.get(0));
     	Vet newVet = vets.get(0);
@@ -180,6 +188,7 @@ public class VetRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testUpdateVetError() throws Exception {
     	Vet newVet = vets.get(0);
     	newVet.setFirstName("");
@@ -191,6 +200,7 @@ public class VetRestControllerTests {
      }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testDeleteVetSuccess() throws Exception {
     	Vet newVet = vets.get(0);
     	ObjectMapper mapper = new ObjectMapper();
@@ -202,6 +212,7 @@ public class VetRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="VET_ADMIN")
     public void testDeleteVetError() throws Exception {
     	Vet newVet = vets.get(0);
     	ObjectMapper mapper = new ObjectMapper();
diff --git a/src/test/java/org/springframework/samples/petclinic/rest/VisitRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/VisitRestControllerTests.java
index 5d4dc5eef2d2897e7ef37642b09f75c3146c5cb4..1d0c1b2aac444dde05e1d6dd2aa14077353a3793 100644
--- a/src/test/java/org/springframework/samples/petclinic/rest/VisitRestControllerTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/rest/VisitRestControllerTests.java
@@ -41,8 +41,9 @@ import org.springframework.samples.petclinic.model.Owner;
 import org.springframework.samples.petclinic.model.Pet;
 import org.springframework.samples.petclinic.model.PetType;
 import org.springframework.samples.petclinic.model.Visit;
-import org.springframework.samples.petclinic.service.ApplicationTestConfig;
+import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig;
 import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 import org.springframework.test.context.web.WebAppConfiguration;
@@ -118,6 +119,7 @@ public class VisitRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testGetVisitSuccess() throws Exception {
     	given(this.clinicService.findVisitById(2)).willReturn(visits.get(0));
         this.mockMvc.perform(get("/api/visits/2")
@@ -129,6 +131,7 @@ public class VisitRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testGetVisitNotFound() throws Exception {
     	given(this.clinicService.findVisitById(-1)).willReturn(null);
         this.mockMvc.perform(get("/api/visits/-1")
@@ -137,6 +140,7 @@ public class VisitRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testGetAllVisitsSuccess() throws Exception {
     	given(this.clinicService.findAllVisits()).willReturn(visits);
         this.mockMvc.perform(get("/api/visits/")
@@ -150,6 +154,7 @@ public class VisitRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testGetAllVisitsNotFound() throws Exception {
     	visits.clear();
     	given(this.clinicService.findAllVisits()).willReturn(visits);
@@ -159,6 +164,7 @@ public class VisitRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testCreateVisitSuccess() throws Exception {
     	Visit newVisit = visits.get(0);
     	newVisit.setId(999);
@@ -171,6 +177,7 @@ public class VisitRestControllerTests {
     }
 
     @Test(expected = IOException.class)
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testCreateVisitError() throws Exception {
     	Visit newVisit = visits.get(0);
     	newVisit.setId(null);
@@ -183,6 +190,7 @@ public class VisitRestControllerTests {
      }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testUpdateVisitSuccess() throws Exception {
     	given(this.clinicService.findVisitById(2)).willReturn(visits.get(0));
     	Visit newVisit = visits.get(0);
@@ -203,6 +211,7 @@ public class VisitRestControllerTests {
     }
 
     @Test(expected = IOException.class)
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testUpdateVisitError() throws Exception {
     	Visit newVisit = visits.get(0);
     	newVisit.setPet(null);
@@ -214,6 +223,7 @@ public class VisitRestControllerTests {
      }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testDeleteVisitSuccess() throws Exception {
     	Visit newVisit = visits.get(0);
     	ObjectMapper mapper = new ObjectMapper();
@@ -225,6 +235,7 @@ public class VisitRestControllerTests {
     }
 
     @Test
+    @WithMockUser(roles="OWNER_ADMIN")
     public void testDeleteVisitError() throws Exception {
     	Visit newVisit = visits.get(0);
     	ObjectMapper mapper = new ObjectMapper();
diff --git a/src/test/java/org/springframework/samples/petclinic/service/AbstractClinicServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/clinicService/AbstractClinicServiceTests.java
similarity index 98%
rename from src/test/java/org/springframework/samples/petclinic/service/AbstractClinicServiceTests.java
rename to src/test/java/org/springframework/samples/petclinic/service/clinicService/AbstractClinicServiceTests.java
index d2625ad9c41bb83ded13a94643ebf2db725e00fc..50655895842775ddecc1877a3c36d30ca354fba3 100644
--- a/src/test/java/org/springframework/samples/petclinic/service/AbstractClinicServiceTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/service/clinicService/AbstractClinicServiceTests.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.springframework.samples.petclinic.service;
+package org.springframework.samples.petclinic.service.clinicService;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -30,6 +30,7 @@ import org.springframework.samples.petclinic.model.PetType;
 import org.springframework.samples.petclinic.model.Specialty;
 import org.springframework.samples.petclinic.model.Vet;
 import org.springframework.samples.petclinic.model.Visit;
+import org.springframework.samples.petclinic.service.ClinicService;
 import org.springframework.samples.petclinic.util.EntityUtils;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.transaction.annotation.Transactional;
@@ -58,7 +59,7 @@ public abstract class AbstractClinicServiceTests {
 
     @Autowired
     protected ClinicService clinicService;
-    
+
     @Before
     public void init() {
         MockitoAnnotations.initMocks(this);
@@ -207,7 +208,7 @@ public abstract class AbstractClinicServiceTests {
         assertThat(visitArr[0].getDate()).isNotNull();
         assertThat(visitArr[0].getPet().getId()).isEqualTo(7);
     }
-    
+
     @Test
     public void shouldFindAllPets(){
         Collection<Pet> pets = this.clinicService.findAllPets();
@@ -216,7 +217,7 @@ public abstract class AbstractClinicServiceTests {
         Pet pet3 = EntityUtils.getById(pets, Pet.class, 3);
         assertThat(pet3.getName()).isEqualTo("Rosy");
     }
-    
+
     @Test
     @Transactional
     public void shouldDeletePet(){
@@ -229,14 +230,14 @@ public abstract class AbstractClinicServiceTests {
 		}
         assertThat(pet).isNull();
     }
-    
+
     @Test
     public void shouldFindVisitDyId(){
     	Visit visit = this.clinicService.findVisitById(1);
     	assertThat(visit.getId()).isEqualTo(1);
     	assertThat(visit.getPet().getName()).isEqualTo("Samantha");
     }
-    
+
     @Test
     public void shouldFindAllVisits(){
         Collection<Visit> visits = this.clinicService.findAllVisits();
@@ -245,28 +246,28 @@ public abstract class AbstractClinicServiceTests {
         Visit visit3 = EntityUtils.getById(visits, Visit.class, 3);
         assertThat(visit3.getPet().getName()).isEqualTo("Max");
     }
-    
+
     @Test
     @Transactional
     public void shouldInsertVisit() {
         Collection<Visit> visits = this.clinicService.findAllVisits();
         int found = visits.size();
-        
+
         Pet pet = this.clinicService.findPetById(1);
 
         Visit visit = new Visit();
         visit.setPet(pet);
         visit.setDate(new Date());
         visit.setDescription("new visit");
-        
-                
+
+
         this.clinicService.saveVisit(visit);
         assertThat(visit.getId().longValue()).isNotEqualTo(0);
 
         visits = this.clinicService.findAllVisits();
         assertThat(visits.size()).isEqualTo(found + 1);
     }
-    
+
     @Test
     @Transactional
     public void shouldUpdateVisit(){
@@ -278,7 +279,7 @@ public abstract class AbstractClinicServiceTests {
         visit = this.clinicService.findVisitById(1);
         assertThat(visit.getDescription()).isEqualTo(newDesc);
     }
-    
+
     @Test
     @Transactional
     public void shouldDeleteVisit(){
@@ -291,14 +292,14 @@ public abstract class AbstractClinicServiceTests {
 		}
         assertThat(visit).isNull();
     }
-    
+
     @Test
     public void shouldFindVetDyId(){
     	Vet vet = this.clinicService.findVetById(1);
     	assertThat(vet.getFirstName()).isEqualTo("James");
     	assertThat(vet.getLastName()).isEqualTo("Carter");
     }
-    
+
     @Test
     @Transactional
     public void shouldInsertVet() {
@@ -308,14 +309,14 @@ public abstract class AbstractClinicServiceTests {
         Vet vet = new Vet();
         vet.setFirstName("John");
         vet.setLastName("Dow");
-                
+
         this.clinicService.saveVet(vet);
         assertThat(vet.getId().longValue()).isNotEqualTo(0);
 
         vets = this.clinicService.findAllVets();
         assertThat(vets.size()).isEqualTo(found + 1);
     }
-    
+
     @Test
     @Transactional
     public void shouldUpdateVet(){
@@ -327,7 +328,7 @@ public abstract class AbstractClinicServiceTests {
         vet = this.clinicService.findVetById(1);
         assertThat(vet.getLastName()).isEqualTo(newLastName);
     }
-    
+
     @Test
     @Transactional
     public void shouldDeleteVet(){
@@ -340,7 +341,7 @@ public abstract class AbstractClinicServiceTests {
 		}
         assertThat(vet).isNull();
     }
-    
+
     @Test
     public void shouldFindAllOwners(){
         Collection<Owner> owners = this.clinicService.findAllOwners();
@@ -349,7 +350,7 @@ public abstract class AbstractClinicServiceTests {
         Owner owner3 = EntityUtils.getById(owners, Owner.class, 3);
         assertThat(owner3.getFirstName()).isEqualTo("Eduardo");
     }
-    
+
     @Test
     @Transactional
     public void shouldDeleteOwner(){
@@ -362,13 +363,13 @@ public abstract class AbstractClinicServiceTests {
 		}
         assertThat(owner).isNull();
     }
-    
+
     @Test
     public void shouldFindPetTypeById(){
     	PetType petType = this.clinicService.findPetTypeById(1);
     	assertThat(petType.getName()).isEqualTo("cat");
     }
-    
+
     @Test
     public void shouldFindAllPetTypes(){
         Collection<PetType> petTypes = this.clinicService.findAllPetTypes();
@@ -377,7 +378,7 @@ public abstract class AbstractClinicServiceTests {
         PetType petType3 = EntityUtils.getById(petTypes, PetType.class, 3);
         assertThat(petType3.getName()).isEqualTo("lizard");
     }
-    
+
     @Test
     @Transactional
     public void shouldInsertPetType() {
@@ -386,14 +387,14 @@ public abstract class AbstractClinicServiceTests {
 
         PetType petType = new PetType();
         petType.setName("tiger");
-        
+
         this.clinicService.savePetType(petType);
         assertThat(petType.getId().longValue()).isNotEqualTo(0);
 
         petTypes = this.clinicService.findAllPetTypes();
         assertThat(petTypes.size()).isEqualTo(found + 1);
     }
-    
+
     @Test
     @Transactional
     public void shouldUpdatePetType(){
@@ -405,7 +406,7 @@ public abstract class AbstractClinicServiceTests {
         petType = this.clinicService.findPetTypeById(1);
         assertThat(petType.getName()).isEqualTo(newLastName);
     }
-    
+
     @Test
     @Transactional
     public void shouldDeletePetType(){
@@ -418,13 +419,13 @@ public abstract class AbstractClinicServiceTests {
 		}
         assertThat(petType).isNull();
     }
-    
+
     @Test
     public void shouldFindSpecialtyById(){
     	Specialty specialty = this.clinicService.findSpecialtyById(1);
     	assertThat(specialty.getName()).isEqualTo("radiology");
     }
-    
+
     @Test
     public void shouldFindAllSpecialtys(){
         Collection<Specialty> specialties = this.clinicService.findAllSpecialties();
@@ -433,7 +434,7 @@ public abstract class AbstractClinicServiceTests {
         Specialty specialty3 = EntityUtils.getById(specialties, Specialty.class, 3);
         assertThat(specialty3.getName()).isEqualTo("dentistry");
     }
-    
+
     @Test
     @Transactional
     public void shouldInsertSpecialty() {
@@ -442,14 +443,14 @@ public abstract class AbstractClinicServiceTests {
 
         Specialty specialty = new Specialty();
         specialty.setName("dermatologist");
-        
+
         this.clinicService.saveSpecialty(specialty);
         assertThat(specialty.getId().longValue()).isNotEqualTo(0);
 
         specialties = this.clinicService.findAllSpecialties();
         assertThat(specialties.size()).isEqualTo(found + 1);
     }
-    
+
     @Test
     @Transactional
     public void shouldUpdateSpecialty(){
@@ -461,7 +462,7 @@ public abstract class AbstractClinicServiceTests {
         specialty = this.clinicService.findSpecialtyById(1);
         assertThat(specialty.getName()).isEqualTo(newLastName);
     }
-    
+
     @Test
     @Transactional
     public void shouldDeleteSpecialty(){
@@ -474,7 +475,7 @@ public abstract class AbstractClinicServiceTests {
 		}
         assertThat(specialty).isNull();
     }
-       
+
 
 
 }
diff --git a/src/test/java/org/springframework/samples/petclinic/service/ApplicationTestConfig.java b/src/test/java/org/springframework/samples/petclinic/service/clinicService/ApplicationTestConfig.java
similarity index 77%
rename from src/test/java/org/springframework/samples/petclinic/service/ApplicationTestConfig.java
rename to src/test/java/org/springframework/samples/petclinic/service/clinicService/ApplicationTestConfig.java
index ac3898b3447f849ffa77f444cf215ce75c2c31e1..a20145521a53f7b61ae29abb0020181f54ac5db1 100644
--- a/src/test/java/org/springframework/samples/petclinic/service/ApplicationTestConfig.java
+++ b/src/test/java/org/springframework/samples/petclinic/service/clinicService/ApplicationTestConfig.java
@@ -1,11 +1,11 @@
-package org.springframework.samples.petclinic.service;
+package org.springframework.samples.petclinic.service.clinicService;
 
 import org.mockito.MockitoAnnotations;
 import org.springframework.boot.test.context.TestConfiguration;
 
 @TestConfiguration
 public class ApplicationTestConfig {
-	
+
 	public ApplicationTestConfig(){
 		MockitoAnnotations.initMocks(this);
 	}
diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceJdbcTests.java b/src/test/java/org/springframework/samples/petclinic/service/clinicService/ClinicServiceJdbcTests.java
similarity index 94%
rename from src/test/java/org/springframework/samples/petclinic/service/ClinicServiceJdbcTests.java
rename to src/test/java/org/springframework/samples/petclinic/service/clinicService/ClinicServiceJdbcTests.java
index c7735bfea4357d78e89a148459c235b3ce5a47b7..5c3ea71158d1463426ba35af4a6674abe3ef00bd 100644
--- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceJdbcTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/service/clinicService/ClinicServiceJdbcTests.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.springframework.samples.petclinic.service;
+package org.springframework.samples.petclinic.service.clinicService;
 
 import org.junit.runner.RunWith;
 import org.springframework.boot.test.context.SpringBootTest;
diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceJpaTests.java b/src/test/java/org/springframework/samples/petclinic/service/clinicService/ClinicServiceJpaTests.java
similarity index 89%
rename from src/test/java/org/springframework/samples/petclinic/service/ClinicServiceJpaTests.java
rename to src/test/java/org/springframework/samples/petclinic/service/clinicService/ClinicServiceJpaTests.java
index 7cb6ab6e440df746a896bdc4cecffb99a84280f3..d0ada35b7cccafd1695ef4834beeee8185a71e37 100644
--- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceJpaTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/service/clinicService/ClinicServiceJpaTests.java
@@ -1,4 +1,4 @@
-package org.springframework.samples.petclinic.service;
+package org.springframework.samples.petclinic.service.clinicService;
 
 import org.junit.runner.RunWith;
 import org.springframework.boot.test.context.SpringBootTest;
diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceSpringDataJpaTests.java b/src/test/java/org/springframework/samples/petclinic/service/clinicService/ClinicServiceSpringDataJpaTests.java
similarity index 89%
rename from src/test/java/org/springframework/samples/petclinic/service/ClinicServiceSpringDataJpaTests.java
rename to src/test/java/org/springframework/samples/petclinic/service/clinicService/ClinicServiceSpringDataJpaTests.java
index 041e8971e936894da2bc51ef8f2317f675255a08..d3f27fbfbce68dc3972d8dd292c72495a36000ba 100644
--- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceSpringDataJpaTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/service/clinicService/ClinicServiceSpringDataJpaTests.java
@@ -1,4 +1,4 @@
-package org.springframework.samples.petclinic.service;
+package org.springframework.samples.petclinic.service.clinicService;
 
 import org.junit.runner.RunWith;
 import org.springframework.boot.test.context.SpringBootTest;
diff --git a/src/test/java/org/springframework/samples/petclinic/service/userService/AbstractUserServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/userService/AbstractUserServiceTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..ef82d68d70a1f468245347171e74d53339347b87
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/service/userService/AbstractUserServiceTests.java
@@ -0,0 +1,36 @@
+package org.springframework.samples.petclinic.service.userService;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.startsWith;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.MockitoAnnotations;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.samples.petclinic.model.User;
+import org.springframework.samples.petclinic.service.UserService;
+
+public abstract class AbstractUserServiceTests {
+
+    @Autowired
+    private UserService userService;
+
+    @Before
+    public void init() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void shouldAddUser() throws Exception {
+        User user = new User();
+        user.setUsername("username");
+        user.setPassword("password");
+        user.setEnabled(true);
+        user.addRole("OWNER_ADMIN");
+
+        userService.saveUser(user);
+        assertThat(user.getRoles().parallelStream().allMatch(role -> role.getName().startsWith("ROLE_")), is(true));
+        assertThat(user.getRoles().parallelStream().allMatch(role -> role.getUser() != null), is(true));
+    }
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/service/userService/UserServiceJdbcTests.java b/src/test/java/org/springframework/samples/petclinic/service/userService/UserServiceJdbcTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..790a1ff7f89c1feb2ebab6f7cd71eeecc2a64924
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/service/userService/UserServiceJdbcTests.java
@@ -0,0 +1,13 @@
+package org.springframework.samples.petclinic.service.userService;
+
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@SpringBootTest
+@RunWith(SpringJUnit4ClassRunner.class)
+@ActiveProfiles("jdbc, hsqldb")
+public class UserServiceJdbcTests extends AbstractUserServiceTests {
+
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/service/userService/UserServiceJpaTests.java b/src/test/java/org/springframework/samples/petclinic/service/userService/UserServiceJpaTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..370c6675715cccc3cac55cd07d04be66a9f1bb4b
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/service/userService/UserServiceJpaTests.java
@@ -0,0 +1,13 @@
+package org.springframework.samples.petclinic.service.userService;
+
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@SpringBootTest
+@RunWith(SpringJUnit4ClassRunner.class)
+@ActiveProfiles("jpa, hsqldb")
+public class UserServiceJpaTests extends AbstractUserServiceTests {
+
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/service/userService/UserServiceSpringDataJpaTests.java b/src/test/java/org/springframework/samples/petclinic/service/userService/UserServiceSpringDataJpaTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..09d13146cfcbf08fd00b1be60b13c1ec824f2029
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/service/userService/UserServiceSpringDataJpaTests.java
@@ -0,0 +1,13 @@
+package org.springframework.samples.petclinic.service.userService;
+
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@SpringBootTest
+@RunWith(SpringJUnit4ClassRunner.class)
+@ActiveProfiles("spring-data-jpa, hsqldb")
+public class UserServiceSpringDataJpaTests extends AbstractUserServiceTests {
+
+}