Skip to content

Commit

Permalink
Merge pull request #67 from rishabhrawat05/security
Browse files Browse the repository at this point in the history
Implemented Jwt and Oauth2.0 Authentication
  • Loading branch information
Guhapriya01 authored Oct 12, 2024
2 parents 2e8984f + 9e813c1 commit c3fd7a4
Show file tree
Hide file tree
Showing 23 changed files with 609 additions and 72 deletions.
47 changes: 36 additions & 11 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,30 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.3</version>
<relativePath/> <!-- lookup parent from repository -->
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com</groupId>
<artifactId>libraryman-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>libraryman-api</name>
<description>Revolutionize book management with LibraryMan! Easily track stock, borrowers, and due dates, streamlining operations for schools, companies, and libraries worldwide, ensuring efficient and organized book lending.</description>
<url/>
<description>Revolutionize book management with LibraryMan! Easily track
stock, borrowers, and due dates, streamlining operations for schools,
companies, and libraries worldwide, ensuring efficient and organized
book lending.</description>
<url />
<licenses>
<license/>
<license />
</licenses>
<developers>
<developer/>
<developer />
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
<connection />
<developerConnection />
<tag />
<url />
</scm>
<properties>
<java.version>17</java.version>
Expand All @@ -50,7 +54,23 @@
<scope>runtime</scope>
<optional>true</optional>
</dependency>

<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>com.mysql</groupId>
Expand Down Expand Up @@ -80,6 +100,11 @@
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>

</dependency>

</dependencies>

Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/libraryman_api/book/BookController.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.libraryman_api.exception.ResourceNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;
Expand Down Expand Up @@ -51,6 +52,7 @@ public ResponseEntity<Book> getBookById(@PathVariable int id) {
* @return the added {@link Book} object.
*/
@PostMapping
@PreAuthorize("hasRole('LIBRARIAN') or hasRole('ADMIN')")
public Book addBook(@RequestBody Book book) {
return bookService.addBook(book);
}
Expand All @@ -63,6 +65,7 @@ public Book addBook(@RequestBody Book book) {
* @return the updated {@link Book} object.
*/
@PutMapping("/{id}")
@PreAuthorize("hasRole('LIBRARIAN') or hasRole('ADMIN')")
public Book updateBook(@PathVariable int id, @RequestBody Book bookDetails) {
return bookService.updateBook(id, bookDetails);
}
Expand All @@ -73,6 +76,7 @@ public Book updateBook(@PathVariable int id, @RequestBody Book bookDetails) {
* @param id the ID of the book to delete.
*/
@DeleteMapping("/{id}")
@PreAuthorize("hasRole('LIBRARIAN') or hasRole('ADMIN')")
public void deleteBook(@PathVariable int id) {
bookService.deleteBook(id);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.libraryman_api.borrowing;

import com.libraryman_api.exception.ResourceNotFoundException;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;
Expand Down Expand Up @@ -31,6 +33,7 @@ public BorrowingController(BorrowingService borrowingService) {
* @return a list of {@link Borrowings} objects representing all borrowings.
*/
@GetMapping
@PreAuthorize("hasRole('LIBRARIAN') or hasRole('ADMIN')")
public List<Borrowings> getAllBorrowings() {
return borrowingService.getAllBorrowings();
}
Expand Down Expand Up @@ -75,6 +78,7 @@ public String payFine(@PathVariable int id) {
* @return a list of {@link Borrowings} objects representing the member's borrowings.
*/
@GetMapping("member/{memberId}")
@PreAuthorize("hasRole('LIBRARIAN') or hasRole('ADMIN')")
public List<Borrowings> getAllBorrowingsOfAMember(@PathVariable int memberId) {
return borrowingService.getAllBorrowingsOfMember(memberId);
}
Expand All @@ -87,6 +91,7 @@ public List<Borrowings> getAllBorrowingsOfAMember(@PathVariable int memberId) {
* @throws ResourceNotFoundException if the borrowing record with the specified ID is not found.
*/
@GetMapping("{borrowingId}")
@PreAuthorize("hasRole('LIBRARIAN') or hasRole('ADMIN')")
public Borrowings getBorrowingById(@PathVariable int borrowingId) {
return borrowingService.getBorrowingById(borrowingId)
.orElseThrow(() -> new ResourceNotFoundException("Borrowing not found"));
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/libraryman_api/member/MemberController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.libraryman_api.exception.ResourceNotFoundException;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;
Expand Down Expand Up @@ -31,6 +32,7 @@ public MemberController(MemberService memberService) {
* @return a list of {@link Members} representing all members in the library
*/
@GetMapping
@PreAuthorize("hasRole('LIBRARIAN') or hasRole('ADMIN')")
public List<Members> getAllMembers() {
return memberService.getAllMembers();
}
Expand All @@ -43,6 +45,7 @@ public List<Members> getAllMembers() {
* @return a {@link ResponseEntity} containing the found {@link Members} object
*/
@GetMapping("/{id}")
@PreAuthorize("hasRole('LIBRARIAN') or hasRole('ADMIN')")
public ResponseEntity<Members> getMemberById(@PathVariable int id) {
return memberService.getMemberById(id)
.map(ResponseEntity::ok)
Expand Down Expand Up @@ -80,6 +83,7 @@ public Members updateMember(@PathVariable int id, @RequestBody Members memberDet
* @param id the ID of the member to delete
*/
@DeleteMapping("/{id}")
@PreAuthorize("hasRole('LIBRARIAN') or hasRole('ADMIN')")
public void deleteMember(@PathVariable int id) {
memberService.deleteMember(id);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public interface MemberRepository extends JpaRepository<Members, Integer> {

Optional<Members> findByMemberId(int memberId);

Optional<Members> findByUsername(String username);

/**
* SELECT SUM(amount) AS totalFines
Expand Down
27 changes: 26 additions & 1 deletion src/main/java/com/libraryman_api/member/Members.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@

import jakarta.persistence.*;

import java.util.Collection;
import java.util.Collections;
import java.util.Date;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;


@Entity
public class Members {
public class Members implements UserDetails{

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,
Expand All @@ -20,6 +26,9 @@ public class Members {
@Column(nullable = false)
private String name;

@Column(name = "username")
private String username;

@Column(unique = true, nullable = false)
private String email;

Expand All @@ -33,6 +42,7 @@ public class Members {
@Column(name = "membership_date")
private Date membershipDate;




public Members() {
Expand Down Expand Up @@ -89,4 +99,19 @@ public Date getMembershipDate() {
public void setMembershipDate(Date membershipDate) {
this.membershipDate = membershipDate;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// TODO Auto-generated method stub
return Collections.singletonList(new SimpleGrantedAuthority("ROLE_"+role.name()));
}

}
20 changes: 0 additions & 20 deletions src/main/java/com/libraryman_api/security/LoginController.java

This file was deleted.

This file was deleted.

33 changes: 0 additions & 33 deletions src/main/java/com/libraryman_api/security/WebConfiguration.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.libraryman_api.security;
package com.libraryman_api.security.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.libraryman_api.security.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
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.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import com.libraryman_api.security.jwt.JwtAuthenticationFilter;

import static org.springframework.security.config.Customizer.withDefaults;
import static org.springframework.security.config.http.SessionCreationPolicy.STATELESS;

@Configuration
@EnableWebSecurity(debug = true) // Do not use (debug=true) in a production system! as this contain sensitive information.
@EnableMethodSecurity(prePostEnabled = true)
public class WebConfiguration {

private JwtAuthenticationFilter jwtFilter;

public WebConfiguration(JwtAuthenticationFilter jwtFilter) {
this.jwtFilter=jwtFilter;
}
@Bean
public SecurityFilterChain web(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests((request) -> request
// make sure it is in order to access the proper Url

.requestMatchers("/api/signup").permitAll()
.requestMatchers("/api/login").permitAll()
.requestMatchers("/api/logout").permitAll()
.anyRequest().authenticated()
)
.logout(logout->logout
.deleteCookies("LibraryManCookie"))
.sessionManagement(session -> session.sessionCreationPolicy(STATELESS))
.formLogin(withDefaults());

http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
.httpBasic(httpBasic -> {});

http.oauth2Login(withDefaults());
return http.build();
}

@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration builder) throws Exception {
return builder.getAuthenticationManager();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowCredentials(true);
corsConfiguration.addAllowedOriginPattern("*");
corsConfiguration.addAllowedHeader("Authorization");
corsConfiguration.addAllowedHeader("Content-Type");
corsConfiguration.addAllowedHeader("Accept");
corsConfiguration.addAllowedMethod("POST");
corsConfiguration.addAllowedMethod("PUT");
corsConfiguration.addAllowedMethod("GET");
corsConfiguration.addAllowedMethod("DELETE");
corsConfiguration.addAllowedMethod("OPTIONS");
corsConfiguration.setMaxAge(3600L);

source.registerCorsConfiguration("/**", corsConfiguration);
return source;
}

@Bean
public CorsFilter corsFilter() {
return new CorsFilter(corsConfigurationSource());
}

}
Loading

0 comments on commit c3fd7a4

Please sign in to comment.