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

12044 - Testing the application #21

Closed
Tracked by #1
njtalba5127 opened this issue Dec 8, 2022 · 19 comments · Fixed by #39 or #40
Closed
Tracked by #1

12044 - Testing the application #21

njtalba5127 opened this issue Dec 8, 2022 · 19 comments · Fixed by #39 or #40
Assignees
Labels
enhancement New feature or request

Comments

@njtalba5127
Copy link
Member

njtalba5127 commented Dec 8, 2022

Timestamp: (12044) 12628 / 12948

@njtalba5127 njtalba5127 mentioned this issue Dec 8, 2022
23 tasks
@njtalba5127 njtalba5127 added the enhancement New feature or request label Dec 8, 2022
@njtalba5127 njtalba5127 self-assigned this Dec 8, 2022
@njtalba5127
Copy link
Member Author

njtalba5127 commented Dec 16, 2022

they said to rerun the spring boot app just to make sure so lets rerun that

./mvnw spring-boot:run  

@njtalba5127
Copy link
Member Author

they gonna use postman to test the application, well use thunderclient

@njtalba5127
Copy link
Member Author

njtalba5127 commented Dec 16, 2022

had a error when running, basically wrong Date import. heres the corrected code for JwtUtils.java

JwtUtils.java

package com.nellyxinwei.backend.config;

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

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 JwtUtils {
  private String jwtSigningKey = "secret";

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

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

  public boolean hasClaim(String token, String claimName) {
    final Claims claims = extractAllClaims(token);
    return claims.get(claimName) != null;
  }

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

  public String generateToken(UserDetails userDetails, Map<String, Object> claims) {
    return createToken(claims, jwtSigningKey);
  }

  private String createToken(Map<String, Object> claims, String subject) {
    return Jwts.builder().setClaims(claims)
        .setSubject(userDetails.getUsername())
        .claim("authorities", userDetails.getAuthorities())
        .setIssuedAt(new Date(System.currentTimeMillis()))
        .setExpiration(new Date(System.currentTimeMillis() + TimeUnit.HOURS.toMillis(24)))
        .signWith(SignatureAlgorithm.HS256, jwtSigningKey).compact();
  }

  public Boolean isTokenValid(String token, UserDetails userDetails) {
    final String username = extractUsername(token);
    return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
  }

}

@njtalba5127
Copy link
Member Author

njtalba5127 commented Dec 16, 2022

now lets proceed with testing

thunderclient:

POST
http://localhost:8080/api/v1/auth/authenticate
BODY - JSON:
{
  "email": "[email protected]",
  "password": "password"
}

output:

403 Forbidden


@njtalba5127
Copy link
Member Author

ugh they added more stuff to the SecurityConfig.java in the background (not recorded in the vid) cuz they forgot something

SecurityConfig.java:

package com.nellyxinwei.backend.config;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.apache.tomcat.jni.User;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
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.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.nellyxinwei.backend.dao.UserDao;

import io.jsonwebtoken.lang.Arrays;
import lombok.RequiredArgsConstructor;

@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

  private final JwtAthFilter jwtAthFilter;
  private final UserDao userDao;

  @Bean
  public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .authorizeRequests()
        .anyRequest()
        .authenticated()
        .and()
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authenticationProvider(authenticationProvider())
        .addFilterBefore(jwtAthFilter, UsernamePasswordAuthenticationFilter.class);
    return http.build();
  }

  @Bean
  public AuthenticationProvider authenticationProvider() {
    final DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
    authenticationProvider.setUserDetailsService(userDetailsService());
    authenticationProvider.setPasswordEncoder(passwordEncoder());
    return authenticationProvider;
  }

  @Bean
  public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
    return config.getAuthenticationManager();
  }

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

  @Bean
  public UserDetailsService userDetailsService() {
    return new UserDetailsService() {
      @Override
      public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        return userDao.findUserByEmail(email);
      }
    };
  }
}

they forgot the .csrf().disable inside the securityfilterchain bean

@njtalba5127
Copy link
Member Author

ok we have more edits again for SecurityConfig.json

SecurityConfig.java

package com.nellyxinwei.backend.config;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.apache.tomcat.jni.User;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
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.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.nellyxinwei.backend.dao.UserDao;

import io.jsonwebtoken.lang.Arrays;
import lombok.RequiredArgsConstructor;

@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

  private final JwtAthFilter jwtAthFilter;
  private final UserDao userDao;

  @Bean
  public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .authorizeRequests()
        .antMatchers("/**/auth/**")
        .permitAll()
        .anyRequest()
        .authenticated()
        .and()
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authenticationProvider(authenticationProvider())
        .addFilterBefore(jwtAthFilter, UsernamePasswordAuthenticationFilter.class);
    return http.build();
  }

  @Bean
  public AuthenticationProvider authenticationProvider() {
    final DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
    authenticationProvider.setUserDetailsService(userDetailsService());
    authenticationProvider.setPasswordEncoder(passwordEncoder());
    return authenticationProvider;
  }

  @Bean
  public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
    return config.getAuthenticationManager();
  }

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

  @Bean
  public UserDetailsService userDetailsService() {
    return new UserDetailsService() {
      @Override
      public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        return userDao.findUserByEmail(email);
      }
    };
  }
}

also in the same bean, they added antmatchers and permitall()

@njtalba5127
Copy link
Member Author

rerun the spring boot app

./mvnw spring-boot:run  

@njtalba5127
Copy link
Member Author

thunderclient:

POST
http://localhost:8080/api/v1/auth/authenticate
BODY - JSON:
{
  "email": "[email protected]",
  "password": "password"
}

output:

500 Internal Server Error


@njtalba5127
Copy link
Member Author

idk i followed everything the best i can but it dont work

@njtalba5127
Copy link
Member Author

it was already confusing when they were doing things in the background or copy pasted something without the link. also no source code so idk

@njtalba5127
Copy link
Member Author

so i decided to go through my own deviation from the course with their JwtUtils.java. I went back to these links:


this link especially helped me fix the JwtUtils.java

and the AUTHORIZATION theng fixed it to just "Authorization" with the help of this link:


i then rerun the spring boot application as my editor doesnt give anymore errors, tested the request again then boom it worked and gave me a generated JWT token.

ill paste here all my files with the fixes. this has been so kinda annoying i swear but anyways thanks to the people who provided this course learning.

@njtalba5127
Copy link
Member Author

rerun the spring boot app

./mvnw spring-boot:run  

@njtalba5127
Copy link
Member Author

thunderclient:

POST
http://localhost:8080/api/v1/auth/authenticate
BODY - JSON:
{
  "email": "[email protected]",
  "password": "password"
}

output:

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0LnVzZXIxQG1haWwuY29tIiwiZXhwIjoxNjcxMjk2ODM3LCJpYXQiOjE2NzEyNjA4Mzd9.FQdiSU-RZVSlf2YakbiwmNDMzFG9f8sW-LjKezu4fMI

@njtalba5127
Copy link
Member Author

njtalba5127 commented Dec 17, 2022

they showed in the course using this website: https://jwt.io

Encoded:

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0LnVzZXIxQG1haWwuY29tIiwiZXhwIjoxNjcxMjk2ODM3LCJpYXQiOjE2NzEyNjA4Mzd9.FQdiSU-RZVSlf2YakbiwmNDMzFG9f8sW-LjKezu4fMI

Decoded:

Header - Algorithm and Token Type:

{
"alg":HS256
}

Payload - Data:

{
  "sub": "[email protected]",
  "exp": 1671296837,
  "iat": 1671260837
}

Verify Signature:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  
your-256-bit-secret

) secret base64 encoded

@njtalba5127
Copy link
Member Author

njtalba5127 commented Dec 17, 2022

ok so compared to when they did the jwt.io theng, in my payload its missing the authorities array...

@njtalba5127
Copy link
Member Author

njtalba5127 commented Dec 17, 2022

ok i fixed it UGHHH 😒 now its also showing the authorities

rerun the spring boot app

./mvnw spring-boot:run  

thunderclient:

POST
http://localhost:8080/api/v1/auth/authenticate
BODY - JSON:
{
  "email": "[email protected]",
  "password": "password"
}

output:

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0LnVzZXIxQG1haWwuY29tIiwiZXhwIjoxNjcxMzQ5MjQ0LCJpYXQiOjE2NzEyNjI4NDQsImF1dGhvcml0aWVzIjpbeyJhdXRob3JpdHkiOiJST0xFX0FETUlOIn1dfQ.EZ8ZlT7gAqx5l_d5BbBrWx5Uhx1zM5bdd1u139BR9iE

lets do the https://jwt.io again

jwt.io:
Encoded:

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0LnVzZXIxQG1haWwuY29tIiwiZXhwIjoxNjcxMzQ5MjQ0LCJpYXQiOjE2NzEyNjI4NDQsImF1dGhvcml0aWVzIjpbeyJhdXRob3JpdHkiOiJST0xFX0FETUlOIn1dfQ.EZ8ZlT7gAqx5l_d5BbBrWx5Uhx1zM5bdd1u139BR9iE

Decoded:

Header - Algorithm and Token Type:

{
"alg":HS256
}

Payload - Data:

{
  "sub": "[email protected]",
  "exp": 1671349244,
  "iat": 1671262844,
  "authorities": [
    {
      "authority": "ROLE_ADMIN"
    }
  ]
}

Verify Signature:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  
your-256-bit-secret

) secret base64 encoded

@njtalba5127
Copy link
Member Author

now with our bearer jwt token, lets try making the requests to greetingscontroller.

thunderclient:

GET
http://localhost:8080/api/v1/greetings
Authorisation - Bearer:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0LnVzZXIxQG1haWwuY29tIiwiZXhwIjoxNjcxMzQ5MjQ0LCJpYXQiOjE2NzEyNjI4NDQsImF1dGhvcml0aWVzIjpbeyJhdXRob3JpdHkiOiJST0xFX0FETUlOIn1dfQ.EZ8ZlT7gAqx5l_d5BbBrWx5Uhx1zM5bdd1u139BR9iE

output:

Hello from our API

thunderclient:

GET
http://localhost:8080/api/v1/greetings/say-good-bye
Authorisation - Bearer:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0LnVzZXIxQG1haWwuY29tIiwiZXhwIjoxNjcxMzQ5MjQ0LCJpYXQiOjE2NzEyNjI4NDQsImF1dGhvcml0aWVzIjpbeyJhdXRob3JpdHkiOiJST0xFX0FETUlOIn1dfQ.EZ8ZlT7gAqx5l_d5BbBrWx5Uhx1zM5bdd1u139BR9iE

output:

Goodbye and see you later

@njtalba5127
Copy link
Member Author

nice, it all worked out in the end 😌 😒 had to go through a lot of deviations and doing my own stuff still.

@njtalba5127
Copy link
Member Author

anyways. ill push up the correct codes instead of posting them each here. this project is done. let us now conclude our session

This was linked to pull requests Dec 17, 2022
Repository owner moved this from In Progress to Done in 2223-1202WinterFuyu-Projects Dec 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
1 participant