Basic Auth
DevKit is compatible only with Studio 6 and Mule 3. To build Mule 4 connectors, see the Mule SDK documentation. |
Basic Auth refers to the classic authentication method, where in order to authenticate with your API users simply provide the Anypoint™ Connector their username and password. This is also the scheme you want to use if your API relies on Basic Auth, using atypical values for the username and password. For instance, an API that uses a security token on top of the username and password would still use Basic Auth for its connecting applications.
The Anypoint DevKit Basic Auth framework provides multi-tenancy capabilities for a connector (managing multiple simultaneous connections with different credentials for a given connector within your application), as well as connection pooling and instance pooling. These benefits are available for most authentication schemes other than OAuth, and for APIs that do not require authentication.
This document describes the benefits of using the Basic Auth framework, the Java annotations through which it is exposed, and how to implement Basic Auth support in your own connector to authenticate with your API. Examples in this discussion show the use of Basic Authentication with basic username/password authentication, but they can easily be generalized to other non-OAuth protocols.
Assumptions
This document assumes you are familiar with the Anypoint Connector DevKit, have already created a connector project, and are ready to implement authentication on your connector. Further, it assumes you are familiar with the various authentication methods, have compared the different authentication support options in Devkit, and chosen Basic Authentication to connect to your API.
About Basic Authentication
Anypoint DevKit’s Basic Auth framework provides the following benefits with minimal effort on the part of the connector developer:
-
Transparent multitenancy – a Mule application can open many connections to a single target, using different credentials to connect on behalf of many users simultaneously
-
Connection pooling – automated management of a pool of instances of the connector class, to manage connection resources effectively
-
The ability to automatically invalidate connections on exceptions, and to reconnect as needed
Anypoint DevKit makes it easy to add Basic Authentication functionality to connectors by applying annotations at the @Connector class level.
Connection Management Framework and Authentication Protocols The Basic Auth framework can be used in conjunction with most authentication protocols, such as basic username/password authentication (most common), SAML, Kerberos, LDAP and NTLM. However, you cannot use the Basic Authentication framework with connectors that use OAuth authentication; the framework does not support the "OAuth dance" or the management of OAuth tokens. |
Basic Auth Annotations in DevKit
To use Basic Authentication in a connector, define and annotate the following methods in the @Connector class:
-
@Connect method
- Creates a connection -
@Disconnect method
- Explicitly closes a connection -
@ValidateConnection method
- Returns true if a connection is still valid,false
otherwise -
@ConnectionIdentifier method
- Returns a prefix used in generating unique identifies for connector instances in the connection pool
Also available is an @InvalidateConnectionOn
method for when an API operation encounters an exception due to a lost connection.
The specific implementation of these methods depends on the target.
Because Basic Authentication is such a useful and fundamental feature, the generated code skeleton includes placeholder methods with the Basic Authentication annotations already applied:
Skeleton Connector with Connection Management Annotated Methods |
---|
|
When developing your connector, make sure to incorporate connection logic that pertains to your connector. |
The methods are called automatically as needed by the Anypoint DevKit framework; you never call them directly from your code.
@Connect Method
This method designates which method inside an @Connector
class is responsible for creating a connection to the target. The @Connect
method is called automatically by Mule when the connector starts up, or if the connection to the API has been lost and must be reestablished. When this method finishes, if authentication is successful, the connector instance is ready to make requests to the API.
A method annotated with @Connect
must:
-
Be
public
-
Throw
org.mule.api.ConnectionException
(and no other exceptions) -
Have a
void
return type -
If automatic Basic Authentication is used, have exactly one method annotated
@Connect
; otherwise compilation fails
The specific code that implements the actual connection depends on the API. Here is an example implementation of a @Connect
method:
Connect method for salesforce connector |
---|
|
The parameters required by this method are the credentials needed for authentication, in this case username and password. Since this method is annotated with @Connect
, Anypoint DevKit makes these parameters available both in the configuration element for this connector (as occurs with @Configurable
fields), as well as in the message processor whenever it is dragged into a flow. Specified credentials override those that are set in the configuration element.
@ConnectionKey and Connection Pooling
The username parameter is annotated with @ConnectionKey
. If pools are enabled (see Connection Pooling below), Mule keeps a pool of simultaneous connections which are used as needed to make calls. The @ConnectionKey
annotation marks that this field is used as the key for this particular connection within the connection pool, so once a connection for this username has been created and added to the pool, it will be reused rather than recreated for each request.
Choosing a Connection Key For username and password authentication, the username is the obvious choice for |
In the example above, the @Connect
method first creates a ConnectorConfig
object (a Salesforce type that holds connection configuration information), then loads the username and password values into the object. This object is used as the argument to the static newConnection()
call, which returns a PartnerConnection
if successful. If the authentication fails (for example because of invalid login information) the code catches the Salesforce typed exception and throws a new exception containing the same information but labeled as the correct Mule exception type.
Note the use of the fully qualified name for the Salesforce Connector class (on which you call newConnection(config) ) rather than importing the class. This is because DevKit also imports a class called Connector , which causes an import conflict.
|
For clients where no authentication is used, you must still supply a @ConnectionKey field. An invented username is one possibility; see Creating a Connector for a SOAP Service Via CXF Client for such an implementation.
|
@Disconnect Method
This annotation indicates the method inside a @Connector
class that is responsible for disposal of a connection. This method is called when the connector is shut down or the connection is explicitly terminated.
A method annotated with @Disconnect
must:
-
Be
public
-
Take no input parameters
-
Have a
void
return type
If Basic Authentication is used, the @Connector
class must have exactly one annotated @Disconnect
method; otherwise compilation fails.
@Disconnect
public void disconnect()
{
if (connection != null)
{
try
{
connection.logout();
}
catch (ConnectionException e)
{
e.printStackTrace();
}
finally
{
connection = null;
}
}
}
If the connector currently has a connection open, this code calls connection.logout()
, a client method that explicitly de-authenticates and closes the connection. The finally
block ensures that, if the logout fails for any reason, the connection is still set to null, so the connector does not again try to reference that connector instance.
@ValidateConnection Method
This method is called by Mule to check whether the connection is actually open or not.
A method annotated with @ValidateConnection
must:
-
Be
public
-
Take no input parameters
-
Return
boolean
orjava.lang.Boolean
Only one method on a @Connector
class can be annotated with @ValidateConnection
.
@ValidateConnection
public boolean isConnected()
{
return connection != null;
}
In this example, in order to determine whether the connection is active the code simply checks if the connection parameter is null. A different implementation may be required for other connectors, depending on the protocol.
@ConnectionIdentifier Method
This annotation identifies a method inside a @Connector
class that returns a unique identifier for the connection, used for logging and debugging.
A method annotated with @ConnectionIdentifier
must:
-
Be
public
-
Not be
static
-
Not take arguments
-
Return
java.lang.String
A @Connector class that uses Basic Authentication must have exactly one method annotated @ConnectionIdentifier
; otherwise compilation will fail.
This code returns the connection SessionId as an identifier (if available). The SessionHeader object in this case contains header information about the current connection to the API, including the session ID.
@ConnectionIdentifier
public String connectionId() {
if (connection != null){
return connection.getSessionHeader().getSessionId();
} else {
return null;
}
}
@ReconnectOn Annotation
This annotation deprecates @InvalidateConnectionOn annotation. It now receives a list of exceptions instead of just a single exception, and can be used at both the class and processor levels.
|
This annotation is used for exception handling related to connections. It can be used at a class level (annotated with the @Connector
annotation) or at a method level (annotated with @Processor
annotation). If the Connector or Processor throws an exception of this class, @ReconnectOn
automatically invalidates the connection. @ReconnectOn
receives a list containing the classes of the exceptions to be caught (see below for an example). When an exception occurs, `@ReconnectOn’s behavior is based on the configured reconnection strategy. See Configuring Reconnection Strategies for more details.
@Processor
@ReconnectOn(exceptions = {InvalidSessionFault.class, PasswordChangedException.class})
public void myOperation(@Optional String source,
@Optional Object destination) throws InvalidSessionFault, PasswordChangedException, InvalidParameterException
{
/**
* CODE FOR MY OPERATION
*/
}
Connection Pooling
You can allow users of your connector to use a pool of simultaneous connections instead of sharing a single instance to process messages.
Connectors that implement pools are each assigned a pool component, which contains multiple instances of the connector to handle simultaneous requests. A connector’s configuration pooling profile configures its component pool.
If you set the poolable
annotation parameter to true
, the generated schema will include additional configuration elements.
Example
Connector |
---|
|
In the corresponding XML, the pooling-config
element is nested inside the config
element. Notice that there is no need to provide any custom Java code to handle the pool, all that is needed is to provide a few parameters:
XML |
---|
|
The following table lists pooling-profile
parameters:
Attribute | Description |
---|---|
maxActive |
Required. Controls the maximum number of Mule components that can be borrowed from a session at once. A negative value means no limit. When |
maxIdle |
Required. Controls the maximum number of Mule components that can sit idle in the pool at once. A negative value means no limit. |
initialisationPolicy |
Optional. Determines how components in a pool should be initialized. Possible values:
The default value is |
exhaustedAction |
Optional. Specifies the behavior of the Mule component pool when the pool is exhausted. Its possible values are:
If a positive maxWait value is supplied, it blocks for at most that many milliseconds, after which a The default value is |
maxWait |
Required. Specifies the number of milliseconds to wait for a pooled component to become available when the pool is exhausted and the exhaustedAction is set to |
See Also
-
NEXT: Continue to Defining Attributes Operations and Data Model for your connector.
-
See the Creating a Connector for a SOAP Service Via CXF Client example to see the Basic Authentication annotations in a fully working example.