-
Notifications
You must be signed in to change notification settings - Fork 94
Description
Explanation of changes in code after dependency upgrades
Commit 1
Upgrading all versions in pom.xml to latest possible based on https://mvnrepository.com/.
Commit 2
javax has been renamed to jakarta, so replace all namespaces javax.* to jakarta.*
Commit 3
Many functions of Jwts have been renamed, particularly the ones after parser() and builder() for this code. Another major change is that instead of just using a secret string, we need a SecretKey object that includes a signature algorithm. The SecretKey is created using Keys.hmacShaKeyFor(Base64.getDecoder().decode(this.secret)) where the secret is the base64 encrypted version of our secret. The .verifyWith() to get the claims from the JWT and .signWith() to create the JWT now needs the Secret Key as a parameter instead of a secret string (and a Signature Algorithm (which was removed) for .signWith()).
Commit 4
@TypeDef was removed and now @Convert needs to be used. @Type was removed and instead @JdbcTypeCode should be used.
Commit 5
Spring Security 6 removed WebSecurityConfigurerAdapter. For HttpSecurity, change
@Override
protected void configure(HttpSecurity httpSecurity)
to
@Bean
public SecurityFilterChain filterChain(HttpSecurity http)
. It also wants HttpSecurity to be in Lambda DSL syntax. Lambda DSL Syntax can be observed in the code (with the -> and Customizer.withDefaults()). .antMatchers was replaced with .requestMatchers. @EnableGlobalMethodSecurity was replaced with @EnableMethodSecurity.
Commit 6
The old dependency sqlite-dialect from com.zsoltfabok does not support Hibernate 6. Instead, we can use the community contributed hibernate-community-dialects which includes SQLite. Therefore we just need to specify platform=org.hibernate.community.dialect.SQLiteDialect in applications.properties instead of spring.jpa.database-platform=com.nighthawk.spring_portfolio.SQLDialect and SQLDialect.java is no longer needed.
Commit 7
A cyclic dependency error appeared after previous changes since JwtRequestFilter needs PersonDetailsService, PersonDetailsService's PasswordEncoder labeled with @Autowired was implemented in SecurityConfig, and SecurityConfig needs both JwtRequestFilter and PersonDetailsService. To fix this, we can just remove the PasswordEncoder dependency. Instead of injecting the bean for the PasswordEncoder, define it separately in both files:
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
Commit 8
There was a null byte error so I created a method to get the SecretKey instead of it being as an attribute, which is better for troubleshooting.
Commit 9
Previously, AuthenticationManager was exposed with
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
which depends on the authenticationManagerBean() method in the superclass WebSecurityConfigurerAdapter.
However, since WebSecurityConfigurerAdapter was removed, the new way to expose AuthenticationManager is
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
Commit 10
The new jjwt-impl of io.jsonwebtoken needs jjwt-impl and jjwt-jackson. The secret also needs at least 256 bits due to the HMAC algorithm needed to create the SecretKey so I lengthened the secret in application.properties. Also, I couldn't access the endpoints not specified in HttpSecurity without a JWT cookie so I included .requestMatchers("/authenticate").permitAll().
Note: Upgrading to Spring Boot 3.1.4, Hibernate 6, Spring Security 6, etc. comes with recommended ways to do stuff. These changes mainly address all the required changes so the code works, without the recommendations.
Commit 12 and Commit 13
The newest version of sqlite-jdbc (3.43.2.0) has problems with its supported features, so switch back.
Additional non-dependency fixes
Commit 11
Previously, the API that create users did not encode the password because it was directly calling the default JPA .save() and not the updated .save() in personDetailsService. Therefore, call personDetailsService.save(person) instead of repository.save(person)
Commit
Spring Security 6 might be implicitly requiring everyone to be authenticated if no rules are matched, so add a permitAll() matching all endpoints (/**) as the last .requestMatchers() rule.