Skip to content

Upgrading Spring Boot, Hibernate, Spring Security, and other dependencies #12

@aidanywu

Description

@aidanywu

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions