I am using spring security with spring boot. But my spring security configuration is now working as expected.
Note : H2 database is running as a separate database in server mode ( Not in embedded mode ).
Here are my project details :
pom.xml
<dependency>
<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.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
Application.properties
server.port=8085
spring.datasource.url=jdbc:h2:tcp://localhost:9092/mem:testdb
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driverClassName=org.h2.Driver
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
EmployeeeResource.java
@RestController
@RequestMapping("/employee")
@Slf4j
public class EmployeeResource {
@Autowired
EmployeeRepository employeeRepository;
@GetMapping(path = "/greetEmployee", produces = MediaType.TEXT_PLAIN_VALUE)
public String sayHello() {
return "Hello Employee !!!";
}
@GetMapping(path = "/getAllEmployees", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<List<Employee>> getAllEmployee() {
List<Employee> employeeList = employeeRepository.findAll();
return new ResponseEntity<>(employeeList, HttpStatus.OK);
}
@GetMapping(path = "/getEmployee/{employeeId}", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<Employee> getEmployee(@PathVariable("employeeId") int employeeId) {
Optional<Employee> optionalEmployee = employeeRepository.findByEmployeeId(employeeId);
if (optionalEmployee.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<>(optionalEmployee.get(), HttpStatus.FOUND);
}
@PostMapping(path = "/createEmployee", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<HttpStatus> createEmployee(@RequestBody Employee employee) {
Random random = new Random();
employee.setEmployeeId(random.nextInt(9999));
employeeRepository.save(employee);
log.info("Created employee with Id : {}", employee.getEmployeeId());
return new ResponseEntity<>(HttpStatus.CREATED);
}
@PostMapping(path = "/createEmployees", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<String> createEmployees(@RequestBody List<Employee> employeeList) {
int count = 0;
Random random = new Random();
for (Employee employee : employeeList) {
employee.setEmployeeId(random.nextInt(999999));
employeeRepository.save(employee);
log.info("Created employee with Id : {}", employee.getEmployeeId());
count ;
}
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("countOfObjectCreated", String.valueOf(count));
return ResponseEntity.status(HttpStatus.CREATED).headers(responseHeaders).build();
}
@PutMapping(path = "/updateEmployee/{employeeId}", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<HttpStatus> updateCustomer(@PathVariable("employeeId") int employeeId, @RequestBody Employee employee) {
Optional<Employee> optionalDbEmployee = employeeRepository.findByEmployeeId(employeeId);
if (optionalDbEmployee.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
Employee dbEmployee = optionalDbEmployee.get();
dbEmployee.setFirstName(employee.getFirstName());
dbEmployee.setLastName(employee.getLastName());
dbEmployee.setExtension(employee.getExtension());
dbEmployee.setEmail(employee.getEmail());
dbEmployee.setOfficeCode(employee.getOfficeCode());
dbEmployee.setReportsTo(employee.getReportsTo());
dbEmployee.setJobTitle(employee.getJobTitle());
return new ResponseEntity<>(HttpStatus.OK);
}
@DeleteMapping(path = "/deleteEmployee/{employeeId}")
public ResponseEntity<HttpStatus> deleteCustomer(@PathVariable("employeeId") int employeeId) {
employeeRepository.deleteById(employeeId);
log.info("Employee with employee id {} Deleted successfully.", employeeId);
return new ResponseEntity<>(HttpStatus.OK);
}
}
Employee.java
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
@Entity
@Table(name = "EMPLOYEE")
public class Employee {
@Id
@Column(name = "EMPLOYEE_ID")
int employeeId;
@Column(name = "LAST_NAME")
String lastName;
@Column(name = "FIRST_NAME")
String firstName;
@Column(name = "EXTENSION")
String extension;
@Column(name = "EMAIL")
String email;
@Column(name = "OFFICE_CODE")
int officeCode;
@Column(name = "REPORTS_TO")
Integer reportsTo;
@Column(name = "JOB_TITLE")
String jobTitle;
}
OfficeResource.java
@RestController
@RequestMapping("/office")
@Slf4j
public class OfficeResource {
@Autowired
OfficeRepository officeRepository;
@GetMapping(path = "/greetOffice", produces = MediaType.TEXT_PLAIN_VALUE)
public String sayHello() {
return "Hello Office !!!";
}
@GetMapping(path = "/getAllOffices", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<List<Office>> getAllOffices() {
List<Office> officeList = officeRepository.findAll();
return new ResponseEntity<>(officeList, HttpStatus.OK);
}
@GetMapping(path = "/getOffice/{officeCode}", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<Office> getOffice(@PathVariable("officeCode") int officeCode) {
Optional<Office> optionalOffice = officeRepository.findByOfficeCode(officeCode);
if (optionalOffice.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<>(optionalOffice.get(), HttpStatus.FOUND);
}
@PostMapping(path = "/createOffice", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<HttpStatus> createOffice(@RequestBody Office office) {
Random random = new Random();
office.setOfficeCode(random.nextInt(999));
officeRepository.save(office);
log.info("Created office with office code : {}", office.getOfficeCode());
return new ResponseEntity<>(HttpStatus.CREATED);
}
@PostMapping(path = "/createOffices", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<String> createOffices(@RequestBody List<Office> officeList) {
int count = 0;
Random random = new Random();
for (Office office : officeList) {
office.setOfficeCode(random.nextInt(999));
officeRepository.save(office);
log.info("Created office with office code : {}", office.getOfficeCode());
count ;
}
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("countOfObjectCreated", String.valueOf(count));
return ResponseEntity.status(HttpStatus.CREATED).headers(responseHeaders).build();
}
@PutMapping(path = "/updateOffice/{officeCode}", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<HttpStatus> updateOffice(@PathVariable("officeCode") int officeCode, @RequestBody Office office) {
Optional<Office> optionalDbOffice = officeRepository.findByOfficeCode(officeCode);
if (optionalDbOffice.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
Office dbOffice = optionalDbOffice.get();
dbOffice.setCity(office.getCity());
dbOffice.setPhone(office.getPhone());
dbOffice.setAddressLine1(office.getAddressLine1());
dbOffice.setAddressLine2(office.getAddressLine2());
dbOffice.setState(office.getState());
dbOffice.setCountry(office.getCountry());
dbOffice.setPostalCode(office.getPostalCode());
dbOffice.setTerritory(office.getTerritory());
return new ResponseEntity<>(HttpStatus.OK);
}
@DeleteMapping(path = "/deleteOffice/{officeCode}")
public ResponseEntity<HttpStatus> deleteOffice(@PathVariable("officeCode") int officeCode) {
officeRepository.deleteById(officeCode);
log.info("Office with office code {} Deleted successfully.", officeCode);
return new ResponseEntity<>(HttpStatus.OK);
}
}
Office.java
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
@Entity
@Table(name = "OFFICE")
public class Office {
@Id
@Column(name = "OFFICE_CODE")
int officeCode;
@Column(name = "CITY")
String city;
@Column(name = "PHONE")
String phone;
@Column(name = "ADDRESS_LINE1")
String addressLine1;
@Column(name = "ADDRESS_LINE2")
String addressLine2;
@Column(name = "STATE")
String state;
@Column(name = "COUNTRY")
String country;
@Column(name = "POSTAL_CODE")
String postalCode;
@Column(name = "TERRITORY")
String territory;
}
SecurityConfiguration.java
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("select username,password,enabled from users where username = ?")
.authoritiesByUsernameQuery("select username,authority from authorities where username = ?")
.passwordEncoder(NoOpPasswordEncoder.getInstance());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/employee/createEmployee", "/employee/createEmployees", "/employee/updateEmployee/**", "/employee/deleteEmployee/**").hasRole("Admin")
.antMatchers("/office/createOffice", "/office/createOffices", "/office/updateOffice/**", "/office/deleteOffice/**").hasRole("Admin")
.antMatchers("/employee/getEmployee/**", "/employee/getAllEmployees").hasAnyRole("Admin","User")
.antMatchers("/office/getOffice/**", "/office/getAllOffices").hasAnyRole("Admin","User")
.and().formLogin();
}
After hitting the url "http://localhost:8085/employee/getEmployee/1002" from browser i am getting login form and after enter the credentials for "User1" who is "Admin" user and am getting "Forbidden, status=403" error.
Need Help.
CodePudding user response:
hasRole
and hasAnyRole
prefix your strings with ROLE_
. Use hasAuthoritiy
or hasAnyAuthority
instead. See spring docs