Authorizing native applications
This chapter explains with more details the process of configuring Sphinx server to authenticate/authorize native applications.
First things first, make sure you have followed the Quickstart chapter thoroughly. It describes the common procedures to setup Sphinx. This chapter just extends what's explained there, with more information that targets native applications specifically.
Registering a client application
After the server component is setup and database is created, you need to register the client application in Sphinx configuration.
Client applications should be added to TSphinxConfig component using the TSphinxConfig.Clients property. You can do it at design-time, by double-clicking the Clients
property, or from code, calling Clients.Add
. In either case, a new TSphinxClientApp will be created.
Fill in the properties of the added TSphinxClientApp object to properly configure the client application. Please refer to TSphinxClientApp reference for a full list of available properties.
At the very least, for any type of client application you create, you should set the TSphinxClientApp.ClientId property. It uniquely identifies the client, and it is used from the client applications to identify themselves when invoking Sphinx authorization server.
Other commonly used properties are TSphinxClientApp.DisplayName and TSphinxClientApp.ValidScopes.
The following is an example of how to register a native client application from code. The same properties can be set using the object inspector at design-time.
Client := SphinxConfig1.Clients.Add;
Client.ClientId := 'desktop';
Client.DisplayName := 'My desktop app';
Client.RedirectUris.Add('http://127.0.0.1');
Client.RequireClientSecret := False;
Client.AllowedGrantTypes := [TGrantType.gtAuthorizationCode];
Client.ValidScopes.Add('openid');
Client.ValidScopes.Add('email');
Properties ClientId
and DisplayName
simply identify the client application.
The URL http://127.0.0.1
is added to the RedirectUris
property. This indicates that redirection to the local machine IP using any HTTP port will be performed. This allows the native client application to listen for HTTP request in any TCP port, and receive the redirect request.
A native application is a public application, that's why RequireClientSecret
should be set to false. No client credentials should be available from the native application.
The grant type used should be gtAuthorizationCode
. Another option would be gtImplicit
, but the former is a newer, more secure method that should be preferred over implicit grant type. By default Sphinx uses authorization code with PKCE so it will require PKCE for the authentication.
Finally, OpenID Connect scopes openid
and email
are added to the ValidScopes
property, so information about the logged user is provided back to the native application when the login is finished.
Authenticating from native applications
Now the server is prepared to authenticate native applications, written in any language. With the above client configuration, you can authorize your native application by using the OAuth 2.0 Authorization Code Flow with Proof Key for Code Exchange (PKCE).
The Sphinx server will publish the authorization endpoint at <base_url>/oauth/authorize
URL, and the token endpoint at <base_url>/oauth/token
URL. Send an OAuth 2 authorization request to the authorization endpoint to obtain an authorization code, and then send a token request to the token endpoint to obtain the identity and access tokens upon the provide of the authorization code.
Authenticating from Delphi applications
If your application is built with Delphi, then TMS Sphinx already provides a high level component TSphinxLogin that will abstract all the grant flow for you and make it even easier to authenticate.
Drop the TSphinxLogin component in any form or data module in your application so that it's accessible when the application starts.
You should then configure it setting the following key properties:
- Authority: Should have the base URL of the Sphinx server. For example,
http://localhost:2001/tms/sphinx
. - ClientId: The id of the client you've just previously registered.
- Scope: Spaced-separated list of scope tokens. At the very least, you should include
openid email
. If your application also communicates with a XData server that needs access tokens, then you should also include the needed scopes for the API, if needed.
Once the component is configured with the above properties, you can use some of its methods to implement the login workflow:
- Use the IsLoggedIn method to check if the user is already logged in the application.
- Use the Login method to initiate the login. User default internet browser will be launched and redirected to the Sphinx login page, where he should authenticate. Once the authentication is completed successfully, the browser will be redirected to the
localhost
URL, where an internal HTTP server will be listening at a random TCP port. The server will process the request to redirect URL, finish the authorization process, and the TSphinxLogin.OnUserLoggedIn event will be fired when the login is successful. - Use the Logout method to clean the existing credentials and log out the user from the application.
If the user is logged in, you can check the TSphinxLogin.AuthResult property to retrieve detailed information about the logged user, like e-mail, name, among other information.