Skip to content

Commit d259f10

Browse files
committed
feat: add new TokenProvider
1 parent e0ae7b8 commit d259f10

File tree

5 files changed

+77
-48
lines changed

5 files changed

+77
-48
lines changed
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package osahner.config
22

3-
import org.hibernate.validator.constraints.Length
43
import org.springframework.boot.context.properties.ConfigurationProperties
54

65
@ConfigurationProperties(prefix = "jwt-security")
76
class SecurityProperties {
8-
@Length(min = 42, message = "Minimum length for the secret is 42.")
9-
var secret = ""
7+
var secret = "" // Minimum length for the secret is 42.
108
var expirationTime: Int = 31 // in days
11-
var tokenPrefix = "Bearer "
12-
var headerString = "Authorization"
139
var strength = 10
10+
11+
// constant
12+
val tokenPrefix = "Bearer "
13+
val headerString = "Authorization"
1414
}

src/main/kotlin/osahner/config/WebConfig.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@ import org.springframework.web.cors.CorsConfigurationSource
1313
import org.springframework.web.cors.UrlBasedCorsConfigurationSource
1414
import osahner.security.JWTAuthenticationFilter
1515
import osahner.security.JWTAuthorizationFilter
16+
import osahner.security.TokenProvider
1617
import osahner.service.AppAuthenticationManager
17-
import osahner.service.AppUserDetailsService
1818

1919
@Configuration
2020
@EnableWebSecurity
2121
@EnableGlobalMethodSecurity(prePostEnabled = true)
2222
class WebConfig(
23-
val userDetailsService: AppUserDetailsService,
2423
val securityProperties: SecurityProperties,
25-
val authenticationManager: AppAuthenticationManager
24+
val authenticationManager: AppAuthenticationManager,
25+
val tokenProvider: TokenProvider
2626
) {
2727
@Bean
2828
@Throws(Exception::class)
@@ -38,8 +38,8 @@ class WebConfig(
3838
.antMatchers(HttpMethod.POST, "/login").permitAll()
3939
.anyRequest().authenticated()
4040
.and()
41-
.addFilter(JWTAuthenticationFilter(authenticationManager, securityProperties))
42-
.addFilter(JWTAuthorizationFilter(authenticationManager, userDetailsService, securityProperties))
41+
.addFilter(JWTAuthenticationFilter(authenticationManager, securityProperties, tokenProvider))
42+
.addFilter(JWTAuthorizationFilter(authenticationManager, securityProperties, tokenProvider))
4343
.build()
4444
}
4545

src/main/kotlin/osahner/security/JWTAuthenticationFilter.kt

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,23 @@ package osahner.security
22

33
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
44
import com.fasterxml.jackson.module.kotlin.readValue
5-
import io.jsonwebtoken.Jwts
6-
import io.jsonwebtoken.SignatureAlgorithm
7-
import io.jsonwebtoken.security.Keys
85
import org.springframework.security.authentication.AuthenticationManager
96
import org.springframework.security.authentication.AuthenticationServiceException
107
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
118
import org.springframework.security.core.Authentication
129
import org.springframework.security.core.AuthenticationException
1310
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
14-
import osahner.add
1511
import osahner.config.SecurityProperties
1612
import java.io.IOException
17-
import java.util.*
1813
import javax.servlet.FilterChain
1914
import javax.servlet.ServletException
2015
import javax.servlet.http.HttpServletRequest
2116
import javax.servlet.http.HttpServletResponse
2217

2318
class JWTAuthenticationFilter(
2419
private val authManager: AuthenticationManager,
25-
private val securityProperties: SecurityProperties
20+
private val securityProperties: SecurityProperties,
21+
private val tokenProvider: TokenProvider
2622
) : UsernamePasswordAuthenticationFilter() {
2723

2824
@Throws(AuthenticationException::class)
@@ -53,18 +49,9 @@ class JWTAuthenticationFilter(
5349
req: HttpServletRequest,
5450
res: HttpServletResponse,
5551
chain: FilterChain?,
56-
auth: Authentication
52+
authentication: Authentication
5753
) {
58-
val authClaims: MutableList<String> = mutableListOf()
59-
auth.authorities?.let { authorities ->
60-
authorities.forEach { claim -> authClaims.add(claim.toString()) }
61-
}
62-
val token = Jwts.builder()
63-
.setSubject(auth.principal as String)
64-
.claim("auth", authClaims)
65-
.setExpiration(Date().add(Calendar.DAY_OF_MONTH, securityProperties.expirationTime))
66-
.signWith(Keys.hmacShaKeyFor(securityProperties.secret.toByteArray()), SignatureAlgorithm.HS512)
67-
.compact()
54+
val token = tokenProvider.createToken(authentication)
6855
res.addHeader(securityProperties.headerString, securityProperties.tokenPrefix + token)
6956
}
7057
}
Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
package osahner.security
22

3-
import io.jsonwebtoken.Jwts
4-
import io.jsonwebtoken.security.Keys
53
import org.springframework.security.authentication.AuthenticationManager
6-
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
74
import org.springframework.security.core.context.SecurityContextHolder
85
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter
96
import osahner.config.SecurityProperties
10-
import osahner.service.AppUserDetailsService
117
import java.io.IOException
128
import javax.servlet.FilterChain
139
import javax.servlet.ServletException
@@ -16,8 +12,9 @@ import javax.servlet.http.HttpServletResponse
1612

1713
class JWTAuthorizationFilter(
1814
authManager: AuthenticationManager,
19-
private val userDetailsService: AppUserDetailsService,
20-
private val securityProperties: SecurityProperties
15+
private val securityProperties: SecurityProperties,
16+
private val tokenProvider: TokenProvider
17+
2118
) : BasicAuthenticationFilter(authManager) {
2219

2320
@Throws(IOException::class, ServletException::class)
@@ -31,22 +28,9 @@ class JWTAuthorizationFilter(
3128
chain.doFilter(req, res)
3229
return
3330
}
34-
getAuthentication(header)?.also {
35-
SecurityContextHolder.getContext().authentication = it
31+
tokenProvider.getAuthentication(header)?.also { authentication ->
32+
SecurityContextHolder.getContext().authentication = authentication
3633
}
3734
chain.doFilter(req, res)
3835
}
39-
40-
private fun getAuthentication(token: String): UsernamePasswordAuthenticationToken? {
41-
return try {
42-
val claims = Jwts.parserBuilder()
43-
.setSigningKey(Keys.hmacShaKeyFor(securityProperties.secret.toByteArray()))
44-
.build()
45-
.parseClaimsJws(token.replace(securityProperties.tokenPrefix, ""))
46-
val userDetail = userDetailsService.loadUserByUsername(claims.body.subject)
47-
UsernamePasswordAuthenticationToken(claims.body.subject, null, userDetail.authorities)
48-
} catch (e: Exception) {
49-
return null
50-
}
51-
}
5236
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package osahner.security
2+
3+
import io.jsonwebtoken.Jwts
4+
import io.jsonwebtoken.SignatureAlgorithm
5+
import io.jsonwebtoken.security.Keys
6+
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
7+
import org.springframework.security.core.Authentication
8+
import org.springframework.security.core.userdetails.User
9+
import org.springframework.stereotype.Component
10+
import osahner.add
11+
import osahner.config.SecurityProperties
12+
import osahner.service.AppUserDetailsService
13+
import java.security.Key
14+
import java.util.*
15+
import javax.annotation.PostConstruct
16+
17+
@Component
18+
class TokenProvider(
19+
private val securityProperties: SecurityProperties,
20+
private val userDetailsService: AppUserDetailsService,
21+
) {
22+
private var key: Key? = null
23+
private var tokenValidity: Date? = null
24+
25+
@PostConstruct
26+
fun init() {
27+
key = Keys.hmacShaKeyFor(securityProperties.secret.toByteArray())
28+
tokenValidity = Date().add(Calendar.DAY_OF_MONTH, securityProperties.expirationTime)
29+
}
30+
31+
fun createToken(authentication: Authentication): String {
32+
val authClaims: MutableList<String> = mutableListOf()
33+
authentication.authorities?.let { authorities ->
34+
authorities.forEach { claim -> authClaims.add(claim.toString()) }
35+
}
36+
37+
return Jwts.builder()
38+
.setSubject(authentication.name)
39+
.claim("auth", authClaims)
40+
.setExpiration(tokenValidity)
41+
.signWith(key, SignatureAlgorithm.HS512)
42+
.compact()
43+
}
44+
45+
fun getAuthentication(token: String): Authentication? {
46+
return try {
47+
val claims = Jwts.parserBuilder()
48+
.setSigningKey(key)
49+
.build()
50+
.parseClaimsJws(token.replace(securityProperties.tokenPrefix, ""))
51+
val userDetail = userDetailsService.loadUserByUsername(claims.body.subject)
52+
val principal = User(userDetail.username, "", userDetail.authorities)
53+
UsernamePasswordAuthenticationToken(principal, token, userDetail.authorities)
54+
} catch (e: Exception) {
55+
return null
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)