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

logic for jwt auth-NOT-WORKING #1

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.exam.config;

import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized: Server");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.exam.config;

import com.exam.service.impl.UserDetailsServiceImpl;
import io.jsonwebtoken.ExpiredJwtException;
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.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

@Autowired
private UserDetailsServiceImpl userDetailsService;

@Autowired
private JwtUtils jwtUtils;

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
// extract authorization header
System.out.println("request: "+ request);
System.out.println("request header names: "+ request.toString());
final String requestTokenHeader = request.getHeader("Authorization");
System.out.println("requestTokenHeader: " + requestTokenHeader);

String username = null;
String jwtToken = null;

if(requestTokenHeader!=null && requestTokenHeader.startsWith("Bearer ")){
try{
// extract JWT token and username
jwtToken = requestTokenHeader.substring(7);
username = this.jwtUtils.extractUsername(jwtToken);
System.out.println("jwtToken: "+ jwtToken + "username: "+ username);
}
catch(ExpiredJwtException e){
e.printStackTrace();
System.out.println("jwt token has expired !!");
}
catch(Exception e){
e.printStackTrace();
System.out.println("error !!");
}
}
else{
System.out.println("Invalid JWT token: Not starts with Bearer !");
}

// once the token is validated, load user service and load user data
if(username!=null && SecurityContextHolder.getContext().getAuthentication()==null) {
final UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (this.jwtUtils.validateToken(jwtToken, userDetails)) {
// token is valid
// set authentication in security context holder
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());

usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
} else {
System.out.println("JWT token is not valid !!");
}

// forward request after authorizing and filtering requests
filterChain.doFilter(request, response);
}
}
}
56 changes: 56 additions & 0 deletions examserver/src/main/java/com/exam/config/JwtUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.exam.config;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

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

@Component
public class JwtUtils {
private String SECRET_KEY = "examportal";

public String extractUsername(String token) {
return extractClaim(token, Claims::getSubject);
}

public Date extractExpiration(String token) {
return extractClaim(token, Claims::getExpiration);
}

public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
final Claims claims = extractAllClaims(token);
return claimsResolver.apply(claims);
}
private Claims extractAllClaims(String token) {
return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
}

private Boolean isTokenExpired(String token) {
return extractExpiration(token).before(new Date());
}

public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
return createToken(claims, userDetails.getUsername());
}

private String createToken(Map<String, Object> claims, String subject) {

return Jwts.builder().setClaims(claims).setSubject(subject)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();
}

public Boolean validateToken(String token, UserDetails userDetails) {
final String username = extractUsername(token);
return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
}
}
70 changes: 70 additions & 0 deletions examserver/src/main/java/com/exam/config/MySecurityConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.exam.config;

import com.exam.service.impl.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
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;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private UserDetailsServiceImpl userDetailsServiceImpl;

@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;

@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;

@Bean
public PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}

@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(this.userDetailsServiceImpl).passwordEncoder(passwordEncoder());
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.cors()
.disable()
.authorizeRequests()
.antMatchers("/generate-token","/user/").permitAll()
.antMatchers(HttpMethod.OPTIONS).permitAll()
. anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler)
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
//
// super.configure(http);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.exam.controller;

import com.exam.config.JwtUtils;
import com.exam.model.JwtRequest;
import com.exam.model.JwtResponse;
import com.exam.service.impl.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AuthenticateController {

@Autowired
private AuthenticationManager authenticationManager;

@Autowired
private UserDetailsServiceImpl userDetailsService;

@Autowired
private JwtUtils jwtUtils;

// generate token
@PostMapping("/generate-token")
public ResponseEntity<?> generateToken(@RequestBody JwtRequest jwtRequest) throws Exception {
System.out.println("jwtRequest: "+ jwtRequest);
try{
authenticate(jwtRequest.getUsername(), jwtRequest.getPassword());
}
catch(UsernameNotFoundException e){
e.printStackTrace();
throw new Exception("User Not Found !");
}

// authentication successful
// load user from userdetail service
UserDetails userDetails = this.userDetailsService.loadUserByUsername((jwtRequest.getUsername()));
String token = this.jwtUtils.generateToken((userDetails));
return ResponseEntity.ok(new JwtResponse(token));
}

private void authenticate(String username, String password) throws Exception {
try{
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
}
catch(DisabledException e){
throw new Exception("USER DISABLED " + e.getMessage());
}
catch(BadCredentialsException e){
throw new Exception("Invalid Credentials "+ e.getMessage());
}
}
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,26 @@
package com.exam.service.impl;public class UserDetailsServiceImpl {
package com.exam.service.impl;

import com.exam.model.User;
import com.exam.repo.UserRepository;
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;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

@Autowired
private UserRepository userRepository;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = this.userRepository.findByUsername(username);
if(user == null){
System.out.println("User not found!");
throw new UsernameNotFoundException("No user found !!");
}
return user;
}
}