流程: 用户打开应用程序。 点击登录。 重定向到登录页面。 用户输入凭据。 重定向回应用程序。 收到 authState nil 和错误“无效客户端”。
let authorizationEndpoint = URL(string: ConfigRouter.AuthorizationEndpoint)!
let tokenEndpoint = URL(string: ConfigRouter.TokenEndpoint)!
let configuration = OIDServiceConfiguration(authorizationEndpoint: authorizationEndpoint,
tokenEndpoint: tokenEndpoint)
var parameters = ConfigRouter.AdditionalParameters
let request = OIDAuthorizationRequest(configuration: configuration,
clientId: ClientId,
clientSecret: ConfigRouter.OktaClientSecret,
scopes: Scope,
redirectURL: URL(string: RedirectURL)!,
responseType: ResponseType,
additionalParameters: parameters)
}
self.currentAuthorizationFlow = OIDAuthState.authState(byPresenting: request, presenting: UIApplication.getTopMostViewController()!, prefersEphemeralSession: true, callback: { authState, error in
if let authState = authState {
let response = AuthHelper.shared.createResponse(authState: authState)
AuthHelper.shared.saveAuthState(state: authState)
completionHandler(.success(response))
} else {
if error != nil {
completionHandler(.failure(error!))
}
}
})
身份提供商是 GlUU。在 Android 中,使用相同的配置可以正常工作。
OIDAuthState.authState() 尝试代表我们执行某些操作。例如,显示 AuthorizationRequest、从服务器获取身份验证代码以及从该身份验证代码请求令牌。因此,authState 将直接返回访问令牌、ID 令牌和刷新令牌等令牌。它适用于 OKTA,但不适用于 GLUU。
OKTA 和 GLUU 之间遵循的流程可能有所不同,或者在 GLUU 服务器中设置客户端可能需要手动令牌调用。
以下步骤帮助我解决了问题:
使用 OIDAuthorizationService.present() 方法显示授权请求
OIDAuthorizationService.present(请求,呈现:UIApplication.getTopMostViewController()!)
如果给出了正确的凭据,此方法将返回 authResponse。 authReponse 将具有 authCode,我们将根据它再次调用用户令牌。
基于authCode的Token调用:
var request = URLRequest(url: tokenEndpointURL) request.httpMethod = gluuhttpMethodTypeKey request.setValue(gluuhRequestContentType , forHTTPHeaderField: gluuhRequestContentTypeKey)
var bodyParameters = [
gluuRefreshTokenGrantTypeKey : OIDGrantTypeAuthorizationCode,
ConfigRouter.OktaResponseType : authorizationCode,
gluuRedirectURIKey : redirectURI,
gluuclientIdKey : clientId,
gluuclientSecretKey : clientSecret,
gluucodeVerifierKey : codeVerifier,
oktaRefreshTokenScopesKey : scope
]
bodyParameters.merge(ConfigRouter.OktaAdditionalParameters) { (_, new) in new }
let bodyString = bodyParameters
.map { "\($0)=\($1)" }
.joined(separator: "&")
request.httpBody = bodyString.data(using: .utf8)
print("request\(request)")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
谢谢