【发布时间】:2021-05-27 14:28:29
【问题描述】:
我尝试通过 Keycloak 在 Ktor Web 服务器中设置有效的 Oauth2 授权。预期的流程是从 Web 服务器向 keycloak 发送请求并登录给定的 UI,然后 Keycloak 发送回可用于接收令牌的代码。赞here
首先我是根据 Ktor 文档中的示例进行的。 Oauth 它运行良好,直到它到达我必须接收令牌的地步,然后它只给了我 HTTP 状态 401。即使 curl 命令正常工作。然后我尝试了一个在 GitHub 上找到的示例项目,我设法通过构建自己的 HTTP 请求并将其发送到 Keycloak 服务器以接收令牌来使其工作,但它应该像这样工作吗?
我对此有多个问题。
-
这个函数是否应该同时处理授权和获取令牌?
authenticate(keycloakOAuth) { get("/oauth") { val principal = call.authentication.principal<OAuthAccessTokenResponse.OAuth2>() call.respondText("Access Token = ${principal?.accessToken}") } } -
我认为我的配置是正确的,因为我可以收到授权,而不是令牌。
const val KEYCLOAK_ADDRESS = "**" val keycloakProvider = OAuthServerSettings.OAuth2ServerSettings( name = "keycloak", authorizeUrl = "$KEYCLOAK_ADDRESS/auth/realms/production/protocol/openid-connect/auth", accessTokenUrl = "$KEYCLOAK_ADDRESS/auth/realms/production/protocol/openid-connect/token", clientId = "**", clientSecret = "**", accessTokenRequiresBasicAuth = false, requestMethod = HttpMethod.Post, // must POST to token endpoint defaultScopes = listOf("roles") ) const val keycloakOAuth = "keycloakOAuth" install(Authentication) { oauth(keycloakOAuth) { client = HttpClient(Apache) providerLookup = { keycloakProvider } urlProvider = { "http://localhost:8080/token" } } } -
我使用构建的 HTTP 请求创建了这个 /token 路由,这个路由设法获取了令牌,但感觉就像是 hack。
get("/token"){ var grantType = "authorization_code" val code = call.request.queryParameters["code"] val requestBody = "grant_type=${grantType}&" + "client_id=${keycloakProvider.clientId}&" + "client_secret=${keycloakProvider.clientSecret}&" + "code=${code.toString()}&" + "redirect_uri=http://localhost:8080/token" val tokenResponse = httpClient.post<HttpResponse>(keycloakProvider.accessTokenUrl) { headers { append("Content-Type","application/x-www-form-urlencoded") } body = requestBody } call.respondText("Access Token = ${tokenResponse.readText()}") }
TL;DR:我可以通过 Keycloak 登录,但尝试获取 access_token 时会出现 401。ktor 中的身份验证函数是否也应该处理这个问题?
【问题讨论】:
标签: kotlin authentication oauth-2.0 keycloak ktor