All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cloud.hedou.abp.auth.AbpAuthArgumentResolver.kt Maven / Gradle / Ivy

Go to download

When the functions of ABP cannot meet service requirements, the Spring Boot framework can be used to expand its own services to make use of abundant Java frameworks on the market.

There is a newer version: 1.0.1
Show newest version
package cloud.hedou.abp.auth

import cloud.hedou.abp.identity.AbpUser
import cloud.hedou.abp.identity.RemoteIdentityService
import org.springframework.core.MethodParameter
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.security.oauth2.jwt.Jwt
import org.springframework.security.oauth2.jwt.JwtDecoder
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken
import org.springframework.web.bind.support.WebDataBinderFactory
import org.springframework.web.context.request.NativeWebRequest
import org.springframework.web.context.request.ServletWebRequest
import org.springframework.web.method.support.HandlerMethodArgumentResolver
import org.springframework.web.method.support.ModelAndViewContainer

/** 从请求中解析用户信息的解析器,可解析类型为[AbpUser]及名称为`userId`和`tenantId`的String类型的参数。*/
class AbpAuthArgumentResolver(
    private val abpJwtDecoder: JwtDecoder,
    private val remoteIdentityService: RemoteIdentityService
) : HandlerMethodArgumentResolver {

    //private val annotationClass = Class.forName("springfox.documentation.annotations.ApiIgnore").asSubclass(Annotation::class.java)

    override fun supportsParameter(parameter: MethodParameter): Boolean {
        val parameterName = parameter.parameterName
        val parameterType = parameter.parameterType
        val hasAnnotation = parameter.parameterAnnotations.any {
            it.annotationClass.qualifiedName == "springfox.documentation.annotations.ApiIgnore"
        }
        //val hasAnnotation = parameter.hasParameterAnnotation(annotationClass)
        return hasAnnotation && (parameterType == AbpUser::class.java || parameterType == String::class.java && parameterName in cloud.hedou.abp.auth.AbpAuthArgumentResolver.Companion.analysableParameterNames)
    }

    override fun resolveArgument(
        parameter: MethodParameter,
        mavContainer: ModelAndViewContainer?,
        webRequest: NativeWebRequest,
        binderFactory: WebDataBinderFactory?
    ): Any? {
        if (webRequest is ServletWebRequest) {
            return when {
                cloud.hedou.abp.auth.AbpAuthArgumentResolver.Companion.USER_ID == parameter.parameterName -> resolveUserId(webRequest)
                cloud.hedou.abp.auth.AbpAuthArgumentResolver.Companion.TENANT_ID == parameter.parameterName -> resolveTenantId(webRequest)
                AbpUser::class.java == parameter.parameterType -> resolveUser(webRequest)
                else -> null
            }
        }
        return null
    }

    /** 从token中获取用户ID,并从远程服务器上获取该用户的信息 */
    private fun resolveUser(request: ServletWebRequest): AbpUser? {
        // 从token中获取userId
        val userId = resolveUserId(request) ?: return null
        // 从远程服务器上获取该用户的信息
        return remoteIdentityService.getUserById(userId)
    }

    /** 从token中获取用户ID */
    private fun resolveUserId(request: ServletWebRequest): String? {
        val authentication = SecurityContextHolder.getContext().authentication
        return authentication?.name ?: resolveToken(request)?.subject
    }

    /** 从token中获取租户信息 */
    private fun resolveTenantId(request: ServletWebRequest): String? {
        val jwtAuthenticationToken = SecurityContextHolder.getContext().authentication as? JwtAuthenticationToken
        val jwt = jwtAuthenticationToken?.token ?: resolveToken(request) ?: return null
        return jwt.getClaimAsString("tenantid")
    }

    /** 将token处理成jwt对象 */
    private fun resolveToken(request: ServletWebRequest): Jwt? {
        try {
            val token = request.getHeader(cloud.hedou.abp.auth.AbpAuthArgumentResolver.Companion.AUTHORIZATION)?.removePrefix("Bearer ") ?: return null
            return abpJwtDecoder.decode(token)
        } catch (throwable: Throwable) {
            return null
        }
    }

    private companion object {

        private const val USER_ID = "userId"
        private const val TENANT_ID = "tenantId"
        private const val AUTHORIZATION = "Authorization"
        private val analysableParameterNames = arrayOf(
            cloud.hedou.abp.auth.AbpAuthArgumentResolver.Companion.USER_ID,
            cloud.hedou.abp.auth.AbpAuthArgumentResolver.Companion.TENANT_ID
        )

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy