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

feat: dev 로그인 #188

Merged
merged 8 commits into from
Feb 24, 2024
Merged
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
@@ -1,6 +1,7 @@
package com.wafflestudio.csereal.common.aop

import com.wafflestudio.csereal.common.CserealException
import com.wafflestudio.csereal.common.mockauth.CustomPrincipal
import com.wafflestudio.csereal.core.user.database.Role
import com.wafflestudio.csereal.core.user.database.UserEntity
import com.wafflestudio.csereal.core.user.database.UserRepository
Expand Down Expand Up @@ -38,6 +39,11 @@ class SecurityAspect(private val userRepository: UserRepository) {
val authentication = SecurityContextHolder.getContext().authentication
val principal = authentication.principal

// for dev Mock User
if (principal is CustomPrincipal) {
return principal.userEntity
}

if (principal !is OidcUser) {
throw CserealException.Csereal401("로그인이 필요합니다.")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.wafflestudio.csereal.common.mockauth

import com.wafflestudio.csereal.core.user.database.UserEntity
import java.security.Principal

data class CustomPrincipal(val userEntity: UserEntity) : Principal {
override fun getName(): String {
return userEntity.username
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.wafflestudio.csereal.common.mockauth

import com.wafflestudio.csereal.core.user.database.Role
import com.wafflestudio.csereal.core.user.database.UserEntity
import com.wafflestudio.csereal.core.user.database.UserRepository
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import org.springframework.http.ResponseEntity
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.security.web.context.SecurityContextRepository
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

//TODO: 정식 릴리즈 후에는 dev 서버에서만 가능하게
@RestController
@RequestMapping("/api")
class DevAuthController(
private val authenticationManager: AuthenticationManager,
private val userRepository: UserRepository,
private val securityContextRepository: SecurityContextRepository
) {

@GetMapping("/mock-login")
fun mockLogin(request: HttpServletRequest, response: HttpServletResponse): ResponseEntity<Any> {
val mockUser = userRepository.findByUsername("devUser")
?: userRepository.save(UserEntity("devUser", "Mock", "mock@abc.com", "0000-00000", Role.ROLE_STAFF))
val customPrincipal = CustomPrincipal(mockUser)
val authenticationToken = UsernamePasswordAuthenticationToken(
customPrincipal,
null,
listOf(
SimpleGrantedAuthority("ROLE_STAFF")
)
)

val authentication = authenticationManager.authenticate(authenticationToken)
SecurityContextHolder.getContext().authentication = authentication

securityContextRepository.saveContext(SecurityContextHolder.getContext(), request, response)

request.getSession(true)

return ResponseEntity.ok().body("Mock user authenticated")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.wafflestudio.csereal.common.mockauth

import com.wafflestudio.csereal.common.CserealException
import com.wafflestudio.csereal.core.user.database.UserRepository
import org.springframework.security.authentication.AuthenticationProvider
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.Authentication
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.stereotype.Component

@Component
class DevAuthenticationProvider(private val userRepository: UserRepository) : AuthenticationProvider {

override fun authenticate(authentication: Authentication): Authentication? {
val username = authentication.name
val userEntity =
userRepository.findByUsername(username) ?: throw CserealException.Csereal404("Mock User not found")

val customPrincipal = CustomPrincipal(userEntity)
return UsernamePasswordAuthenticationToken(customPrincipal, null, listOf(SimpleGrantedAuthority("ROLE_STAFF")))
}

override fun supports(authentication: Class<*>): Boolean {
return UsernamePasswordAuthenticationToken::class.java.isAssignableFrom(authentication)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.wafflestudio.csereal.common.mockauth

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.web.context.HttpSessionSecurityContextRepository
import org.springframework.security.web.context.SecurityContextRepository

@Configuration
class MockAuthConfig(
private val devAuthenticationProvider: DevAuthenticationProvider
) {
@Bean
fun authenticationManager(http: HttpSecurity): AuthenticationManager {
http.authenticationProvider(devAuthenticationProvider)
return http.getSharedObject(AuthenticationManagerBuilder::class.java).build()
}

@Bean
fun securityContextRepository(): SecurityContextRepository {
return HttpSessionSecurityContextRepository()
}
}
Loading