Library for using OpenID Connect in iOS Projects. Build with kotlin multiplatform, published for iOS as Swift Package. This project aims to be a lightweight implementation without sophisticated validation on client side. This iOS Framework is generated from the kotlin-multiplatform-oidc project, where you can find the source code.
- Currently, it only supports the Authorization Code Grant Flow.
- Support for discovery via .well-known/openid-configuration.
- Support for PKCE
- Uses
ASWebAuthenticationSession - Simple JWT parsing
Add the swift package from https://github.com/kalinjul/OpenIdConnectClient. If you're using a swift module, add this line:
dependencies:[.package(url:"https://github.com/kalinjul/OpenIdConnectClient.git", exact:"<version>")],Create OpenID config and client:
import OpenIdConnectClient
letclient=OpenIdConnectClient(
config:OpenIdConnectClientConfig(
discoveryUri:"<discovery url>",
endpoints:Endpoints(
tokenEndpoint:"<tokenEndpoint>",
authorizationEndpoint:"<authorizationEndpoint>",
userInfoEndpoint:nil,
endSessionEndpoint:"<endSessionEndpoint>",
revocationEndpoint:"<revocationEndpoint>"),
clientId:"<clientId>",
clientSecret:"<clientSecret>",
scope:"openid profile",
codeChallengeMethod:.s256,
redirectUri:"<redirectUri>",
postLogoutRedirectUri:"<postLogoutRedirectUri>",
disableNonce:false))If you provide a Discovery URI, you may skip the endpoint configuration and set endpoints to nil. If required, you can also configure the http client with custom headers etc:
letclient=OpenIdConnectClient(
httpClient:OpenIdConnectClient.companion.DefaultHttpClient.config(block:{ config in
config.installClientPlugin(
name:"customheader",
onRequest:{ requestBuilder, content in
requestBuilder.headers.append(name:"User-Agent", value:"oidcclient")},
onResponse:{_ in},
onClose:{})}),
config:...)Request access token using code auth flow:
letfactory=CodeAuthFlowFactory_(ephemeralBrowserSession:false)letflow= factory.createAuthFlow(client: client)do{lettokens=tryawait flow.getAccessToken()}catch{print(error)}Perform refresh or endSession:
tryawait client.refreshToken(refreshToken: tokens.refresh_token!)tryawait client.endSession(idToken: tokens.id_token!)For most calls (getAccessToken(), refreshToken(), endSession()), you may provide
additional configuration for the http call, like headers or parameters using the configure closure parameter:
tryawait client.endSession(idToken: idToken){ requestBuilder in
requestBuilder.headers.append(name:"X-CUSTOM-HEADER", value:"value")
requestBuilder.url.parameters.append(name:"custom_parameter", value:"value")}
// endSession with Web flow (opens browser and handles post_logout_redirect_uri redirect)
letfactory=CodeAuthFlowFactory_(ephemeralBrowserSession:false)letflow= factory.createAuthFlow(client: client)tryawait flow.endSession(idToken:"<idToken>", configureEndSessionUrl:{ urlBuilder in})tryawait flow.getAccessToken(
configureAuthUrl:{ urlBuilder in
urlBuilder.parameters.append(name:"prompt", value:"login")},
configureTokenExchange:{ requestBuilder in
requestBuilder.headers.append(name:"additionalHeaderField", value:"value")})We provide simple JWT parsing:
letjwt= tokens.id_token.map{try!JwtParser.shared.parse(from: $0)}print(jwt?.payload.aud) // print audience
print(jwt?.payload.iss) // print issuer
print(jwt?.payload.additionalClaims["email"]) // get claimSince persisting tokens is a common task in OpenID Connect Authentication, we provide a
TokenStore that uses a Multiplatform Settings Library
to persist tokens in Keystore.
lettokenstore=KeychainTokenStore()tryawait tokenstore.saveTokens(tokens: tokens)