Home > Mobile >  Spring security configuration in spring boot not working as expected
Spring security configuration in spring boot not working as expected

Time:10-02

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();
    
        }

User Details

Authority details

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

  • Related