Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented Jwt and Oauth2.0 Authentication #67

Merged
merged 9 commits into from
Oct 12, 2024
Merged
18 changes: 17 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,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
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
25 changes: 24 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 @@ -33,6 +39,8 @@ public class Members {
@Column(name = "membership_date")
private Date membershipDate;

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


public Members() {
Expand Down Expand Up @@ -89,4 +97,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.name()));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.libraryman_api.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import com.libraryman_api.member.MemberRepository;
@Service
public class CustomUserDetailsService implements UserDetailsService{

@Autowired
MemberRepository memberRepository;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

return memberRepository.findByUsername(username).orElseThrow(()-> new UsernameNotFoundException("Username not Found"));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.libraryman_api.security;


import java.io.IOException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

@Autowired
JwtAuthenticationHelper jwtHelper;

@Autowired
UserDetailsService userDetailsService;

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {

String requestHeader=request.getHeader("Authorization");
String username=null;
String token=null;
if(requestHeader!=null && requestHeader.startsWith("Bearer ")) {
token=requestHeader.substring(7);
username=jwtHelper.getUsernameFromToken(token);
if(username!=null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails=userDetailsService.loadUserByUsername(username);
if(!(jwtHelper.isTokenExpired(token))) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken=new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);

}
else {
System.out.println("Token is expired or user details not found.");
}
}

}
filterChain.doFilter(request, response);
}




}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.libraryman_api.security;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.spec.SecretKeySpec;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

@Component
public class JwtAuthenticationHelper {

private static final long JWT_TOKEN_VALIDITY=60*60;
private String secret="thisisacodingninjasdemonstrationforsecretkeyinspringsecurityjsonwebtokenauthentication";
public String getUsernameFromToken(String token) {
String username=getClaimsFromToken(token).getSubject();
return username;
}

public Claims getClaimsFromToken(String token) {
Claims claims=Jwts.parserBuilder()
.setSigningKey(secret.getBytes())
.build().parseClaimsJws(token).getBody();
return claims;
}

public Boolean isTokenExpired(String token) {
Claims claims=getClaimsFromToken(token);
Date expDate=claims.getExpiration();
return expDate.before(new Date());
}

public String generateToken(UserDetails userDetails) {
Map<String,Object> claims=new HashMap<>();
return Jwts.builder().setClaims(claims).setSubject(userDetails.getUsername())
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis()+JWT_TOKEN_VALIDITY*1000))
.signWith(new SecretKeySpec(secret.getBytes(),SignatureAlgorithm.HS512.getJcaName()),SignatureAlgorithm.HS512)
.compact();
}
}
28 changes: 28 additions & 0 deletions src/main/java/com/libraryman_api/security/LoginRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.libraryman_api.security;

public class LoginRequest {

private String username;

private String password;



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


}
21 changes: 21 additions & 0 deletions src/main/java/com/libraryman_api/security/LoginResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.libraryman_api.security;


public class LoginResponse {

private String token;

public LoginResponse(String token) {
this.token=token;
}
public String getToken() {
return token;
}

public void setToken(String token) {
this.token = token;
}



}
47 changes: 47 additions & 0 deletions src/main/java/com/libraryman_api/security/LoginService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.libraryman_api.security;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;

import com.libraryman_api.member.MemberRepository;


@Service
public class LoginService {

@Autowired
AuthenticationManager authenticationManager;

@Autowired
UserDetailsService userDetailsService;

@Autowired
JwtAuthenticationHelper jwtHelper;

@Autowired
MemberRepository memberRepository;

public LoginResponse login(LoginRequest loginRequest) {
Authenticate(loginRequest.getUsername(), loginRequest.getPassword());
UserDetails userDetails=userDetailsService.loadUserByUsername(loginRequest.getUsername());
String token=jwtHelper.generateToken(userDetails);
LoginResponse loginResponse=new LoginResponse(token);
return loginResponse;
}

public void Authenticate(String username,String password) {
UsernamePasswordAuthenticationToken authenticateToken=new UsernamePasswordAuthenticationToken(username, password);
try {
authenticationManager.authenticate(authenticateToken);
}
catch(BadCredentialsException e){
throw new BadCredentialsException("Invalid Username or Password");
}
}
}
41 changes: 41 additions & 0 deletions src/main/java/com/libraryman_api/security/SignupService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.libraryman_api.security;

import java.util.Date;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import com.libraryman_api.exception.ResourceNotFoundException;
import com.libraryman_api.member.MemberRepository;
import com.libraryman_api.member.Members;

@Service
public class SignupService {

@Autowired
MemberRepository memberRepository;

@Autowired
PasswordEncoder passwordEncoder;
public void signup(Members members) {
Optional<Members> memberOptId=memberRepository.findById(members.getMemberId());
Optional<Members> memberOptUsername=memberRepository.findByUsername(members.getUsername());
if(memberOptId.isPresent()) {
throw new ResourceNotFoundException("User already Exists");
}
if(memberOptUsername.isPresent()) {
throw new ResourceNotFoundException("User already Exists");
}
String encoded_password=passwordEncoder.bCryptPasswordEncoder().encode(members.getPassword());
Members new_members=new Members();
new_members.setEmail(members.getEmail());
new_members.setName(members.getName());
new_members.setPassword(encoded_password);
new_members.setRole(members.getRole());
new_members.setMembershipDate(new Date());
new_members.setUsername(members.getUsername());
memberRepository.save(new_members);
}
}
Loading