Authentication
You need to:
Token Endpoint
URI | Credentials |
---|---|
https://id.wgtwo.com/oauth2/token |
basic auth |
We only support the client credential flow for obtaining an access token. That is, the access token will authenticate the product itself and not a specific user.
Reach out if your application only supports passing client ID and client in the request body.
As given by RFC 6749, it is recommended to use the HTTP Basic authentication scheme for client ID and client secret. By default, that is the only method we support for authenticating the client.
Create OAuth 2.0 Client
In order to authenticate our APIs, you will need to create an OAuth 2.0 client. This client is tied to a product in Developer Portal.
Create Client
- Sign up at developer.mobility.cisco.com. Use your work email.
- Create an organization
- Create a product
- Go to the "Technical integration" tab, and click "ADD OAUTH CLIENT":
Field | Value |
---|---|
Client description | This description is for your own benefit, choose whatever you want |
The generated credentials will be displayed only once, so make sure to save them.
You Can Now Authenticate Towards Our APIs
You can now start playing with our APIs.
In order to get your product displayed in our storefront, you will need to fill in additional details, but these details are not required for the technical integration (using APIs).
Get Client Access Token
Prerequisites
- An OAuth 2.0 client.
Use a Library
We do not recommend implementing this flow manually. There are good OAuth 2.0 libraries for all common languages.
You are expected to reuse the obtained token until it expires. It can be kept in memory, and you are not required to keep a shared cache between your servers.
Supplying an up-to-date token with automatic refreshing is handled automatically for some libraries. See:
- Go: clientcredentials
TokenSource
function- Java/Kotlin: github.com/working-group-two/wgtwo-auth (maintained by Mobility Services team).
Example Code Dependency
<dependency>
<groupId>com.wgtwo.api</groupId>
<artifactId>auth</artifactId>
<version>0.0.5</version>
</dependency>
Example Get Access Token
Get client credentials for sms.text:send_from_subscriber
and sms.text:send_to_subscriber
.
#!/usr/bin/env bash
curl \
--user "$CLIENT_ID":"$CLIENT_SECRET" \
--data grant_type="client_credentials" \
--data scope="sms.text:send_from_subscriber sms.text:send_to_subscriber" \
https://id.wgtwo.com/oauth2/token
package com.example.oauth2
import com.wgtwo.auth.WgtwoAuth
import io.grpc.CallCredentials
fun main() {
val clientId = System.getenv("CLIENT_ID")
val clientSecret = System.getenv("CLIENT_SECRET")
val wgtwoAuth = WgtwoAuth.builder(clientId, clientSecret).build()
val scope = "subscription.read subscription.write"
// Recommended: Get token source (cache with automatic refresh)
val tokenSource = wgtwoAuth.clientCredentials.newTokenSource(scope)
println("Got access token ${tokenSource.fetchToken().accessToken}")
// This token source can be used to create call credentials for use with gRPC
val callCredentials: CallCredentials = tokenSource.callCredentials()
// Alternative: Explicit fetch of single token
val token = wgtwoAuth.clientCredentials.fetchToken(scope)
println("Got access token ${token.accessToken} which expires at ${token.expiry}")
}
package main
import (
"context"
"fmt"
"golang.org/x/oauth2/clientcredentials"
"os"
)
func main() {
scopes := []string{"sms.text:send_from_subscriber", "sms.text:send_to_subscriber"}
clientCredentialsConfig := &clientcredentials.Config{
ClientID: os.Getenv("CLIENT_ID"),
ClientSecret: os.Getenv("CLIENT_SECRET"),
Scopes: scopes,
TokenURL: "https://id.wgtwo.com/oauth2/token",
}
tokenSource := clientCredentialsConfig.TokenSource(context.Background())
token, err := tokenSource.Token()
if err != nil {
panic(err)
}
fmt.Printf("Got access token %v which expires at %v
", token.AccessToken, token.Expiry)
}
Example Use Access Token
#!/usr/bin/env bash
grpcurl \
-d '
{
"content": "My text message",
"fromSubscriber": "+47xxxxxxxx",
"toAddress": "+47yyyyyyyy"
}
' \
sandbox.api.shamrock.wgtwo.com:443 \
wgtwo.sms.v1.SmsService/SendTextFromSubscriber
package com.example.oauth2
import com.wgtwo.api.v1.sms.SmsProto
import com.wgtwo.api.v1.sms.SmsServiceGrpc
import com.wgtwo.auth.WgtwoAuth
import io.grpc.ManagedChannelBuilder
fun main() {
val clientId = System.getenv("CLIENT_ID")
val clientSecret = System.getenv("CLIENT_SECRET")
val wgtwoAuth = WgtwoAuth.builder(clientId, clientSecret).build()
// Get token source (cache with automatic refresh)
val tokenSource = wgtwoAuth.clientCredentials.newTokenSource("sms.text:send_from_subscriber")
val channel = ManagedChannelBuilder.forTarget("sandbox.api.shamrock.wgtwo.com:443").build()
val stub = SmsServiceGrpc.newBlockingStub(channel)
.withCallCredentials(tokenSource.callCredentials())
val request = SmsProto.SendTextFromSubscriberRequest.newBuilder().apply {
fromSubscriber = "+4799000000"
toAddress = "+4799990000"
content = "Testing 1, 2, 3"
}.build()
val response = stub.sendTextFromSubscriber(request)
println("response:
$response")
}
package main
import (
"context"
"fmt"
wgtwoSipBreakout "github.com/working-group-two/wgtwoapis/wgtwo/sipbreakout/v1"
"golang.org/x/oauth2"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/oauth"
)
// Token source from above example
var tokenSource oauth2.TokenSource
func main() {
conn, err := grpc.Dial(
"sandbox.api.shamrock.wgtwo.com:443",
grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")),
grpc.WithPerRPCCredentials(oauth.TokenSource{TokenSource: tokenSource}),
)
if err != nil {
panic(err)
}
defer conn.Close()
client := wgtwoSipBreakout.NewSipBreakoutServiceClient(conn)
request := &wgtwoSipBreakout.UpsertRegistrationRequest{
Registration: &wgtwoSipBreakout.Registration{
MobileOriginatingPrefix: "11",
MobileTerminatingPrefix: "22",
SipUri: "sips:example.com:8888",
RouteType: wgtwoSipBreakout.RouteType_ROUTE_TYPE_LOOP,
},
}
response, err := client.UpsertRegistration(context.Background(), request)
if err != nil {
panic(err)
}
fmt.Printf("Got status: %v", response.StatusCode)
}
Resources
- Auth0 description of how the client credential flow works: auth0.com/docs/flows/client-credentials-flow
- Go's clientcredentials
JSON Web Key Set
JWKS endpoint: https://id.wgtwo.com/.well-known/jwks.json
All issued JWTs are signed using the RS256 signing algorithm.
The JWT is signed using one of these keys, but the endpoint may contain multiple keys to allow key rotation.
It is recommended to use a library that fetches the keys dynamically as they may be rotated without notice.