Authentication
IBM® WebSphere® sMash authentication is based on the Java Authentication and Authorization Service (JAAS), which allows various types of login modules to be added to the programming model without changing the authentication model.
The following list contains the types of authentication that are available:
- Basic authentication
- Form-based authentication
- Single sign-on authentication
- Programmatic login authentication
Basic authentication
Basic authentication is defined in RFC 2617.
Basic authentication security flow
When a request is received for a protected resource:
- The incoming request is checked for a valid token.
- If no token is found, the incoming request is checked for user credentials and a login is attempted.
- If the login is unsuccessful, then the client is sent a 401 status header along with a request for credentials. If the login is successful, then a token is generated for subsequent requests and an authorization check is performed.
- If authorization is unsuccessful, then a 403 unauthorized status header is returned to the client. If authorization is successful, the protected resource is served.
Form-based authentication
To enable form-based authentication, specify two configuration stanzas.
The first stanza is responsible for configuration associated with the form. The property for this configuration setting is formLoginPage, which specifies the location of the form login page.
@include "security/form.config"{
"formLoginPage" : "/login/index.html"
}
The second stanza is responsible for rules associated with the resource that is being secured. This rule protects all resources that match the URI pattern /formauth/customers(/.*)? with form-based authentication. As an authenticated user, you can access as the following example shows:
@include "security/rule.config"{
"conditions": "/request/path =~ /formauth/customers(/.*)?",
"authType" : "Form",
"groups" : ["ALL_AUTHENTICATED_USERS"]
}
Additionally, to use the logout function, you must configure the logout handler at a given location, as shown in the following example, and send the request for logout as a POST:
/config/handlers += [{
"events" : "POST",
"handler" : "zero.core.security.LogoutHandler.class",
"conditions" : "/request/path =~ /logout"
}]
Creating a login form
Form-based login requires the creation of a login form at the location specified by formLoginPage. The following list contains the requirements for this form:
- The method must be
POST. - The action must result in the request going to the login page,
formLoginPage, when it is submitted. If you navigate to the login page as a result of directory indexing, such as requests to the root of the application without a resource explicitly listed, the action needs to beformLoginPage. For all other types of requests, the action can be left blank. - The
usernamefield must be named zeroUserName. - The
passwordfield must be named zeroPassword.
The following example is a sample form:
<html>
<form method="POST" action="">
<input type="text" name="zeroUserName">Username</input><BR>
<input type="password" name="zeroPassword">Password<BR>
<!-- optional hidden value used in requesting unprotected form login page scenario -->
<input type="hidden" name="postLoginTargetURI" value="secure/index.gt">
<input type="submit" value="Submit"/>
</form>
</html>
Form-based security flow
You can request a protected resource or an unprotected form login page.
Requesting a protected resource
When a request comes in for a protected resource, the following events occur:
- The incoming request is checked for a valid token.
- If a token is not found, then a 302 is sent to the client to redirect it to the login page, as defined in the configuration file under the
formLoginPageentry. - If a token is found, then the URI for the protected resource is added as a query parameter to the login page URL. The form should post back to itself with an empty action when it is submitted.
- If a token is not found, then a 302 is sent to the client to redirect it to the login page, as defined in the configuration file under the
- A login is attempted with the incoming credentials.
- If the login is unsuccessful, then the login page is returned again with a 200 status code.
- If the login is successful, then a token is generated for subsequent requests, and a 302 status code is sent to the client to redirect it back to the original protected resource, which is stored in the
postLoginTargetURIquery parameter.
- The incoming request for the protected resource contains a valid token and an authorization check is performed.
- If authorization is unsuccessful, then a 403 unauthorized status header is returned to the client.
- If authorization is successful, then the protected resource is served.
Requesting an unprotected form login page
When a request comes in for the form login page, the following events occur:
- A login is attempted with the incoming credentials.
- If the login is unsuccessful, then a login page is returned again with a 200 status code.
- If the login is successful, then a token is generated for subsequent requests, and a 302 status code is sent to the client to redirect it back to the a protected resource, which is stored in the hidden
postLoginTargetURIform field parameter.
- The incoming request for the protected resource contains a valid token and an authorization check is performed.
- If authorization is unsuccessful, then a 403 unauthorized status header is returned to the client.
- If authorization is successful, the protected resource is served.
If the FormBasedLoginHandler does not receive the parameter postLoginTargetURI, you are redirected to the context root of the application where you can define a default file resource to handle the request.
Single sign-on authentication
WebSphere sMash single sign-on is scoped to the WebSphere sMash application. To enable WebSphere sMash single sign-on based authentication, specify two configuration stanzas.
For information about single sign-on scoped at the server level, see the LTPAToken2 support section of the Security Tokens topic.
The first stanza contains configuration information for the single sign-on. The property for this configuration setting, as shown in the following example, is ssoURL which specifies the location of single sign-on service. You can also configure an optional realm to be used by single sign-on.
@include "security/sso.config"{
"realm":"Secure Area",
"ssoURL":"/sso/login"
}
If no realm is set, the default realm is Secure Area.
The second stanza is responsible for rules associated with the resource that is being secured. This rule protects all resources that match the URI pattern /sso/customers/groovy with single sign-on authentication. To access, you must be defined as part of the CUSTOMERS group, as shown in the following example.
@include "security/rule.config"{
"conditions": "/request/path =~ /sso/customers.groovy",
"authType" : "SSO",
"groups" : ["CUSTOMERS"]
}
To make use of the logout function, configure the logout handler at a given location, as shown in the following example, and send the request for logout as a POST.
/config/handlers += [{
"events" : "POST",
"handler" : "zero.core.security.LogoutHandler.class",
"conditions" : "/request/path =~ /logout"
}]
Creating a login form
You can implement WebSphere sMash single sign-on in a variety of ways. Start with the preceding Creating a login form example and convert to a login widget. The main difference is the form action must be the ssoURL. The following requirements must also be met:
- The action must be the location specified in the
ssoURLfield in thezero.configfile. - The
usernamefield must be named zeroUserName. - The
passwordfield must be named zeroPassword.
The following code sample is an example login form leveraging Dojo:
<form id="loginForm" action="/sso/login" >
<input type="text" value="UserName" name="zeroUserName"/>
<input type="password" name="zeroPassword" />
<input type="button" value="login" onClick="loginUser(); return
false;"/>
</form>
<script type="text/javascript">
function loginUser(){
var form = dojo.byId('loginForm');
var username = form['zeroUserName'].value;
var password = form['zeroPassword'].value;
var jsonString = dojo.toJson({zeroUserName: username,zeroPassword: password });
var request = {
url: '/sso/login',
postData: jsonString,
sync: false,
handleAs: 'text',
contentType: 'text/json',
handle: function(response, ioArgs){
form.reset();
},
load: function (response, ioArgs){
// do something
return response;
},
error: function (data, ioArgs){
// do something
return data;
}
var deferred = dojo.rawXhrPost(request);
}
</script>
For scenarios in which using a form is not preferred, SSO also supports JSON encoded parameters. The names of the parameters, zeroUserName and zeroPassword, are the same. The target URL, ssoURL defined in the zero.config file, also remains the same as the login form example.
Single sign-on security flow
By default, WebSphere sMash single sign-on can be viewed in two types of requests. The first type of request is the login, and the second type is requests sent to protected resources that can occur multiple times.
For cross Web application scoped single sign on, see the LTPAToken2 support section of the Security Tokens topic.
Type 1 request
When a request is made to the single sign-on resource the following events occur:
- The incoming request is checked for a valid token.
- If no token is found, the incoming request is checked for user credentials and a login is attempted.
- If the login is unsuccessful, then the client is sent a 401 status header, along with a request for credentials.
- If the login is successful, then a token is generated for subsequent requests.
Type 2 request
When a request comes in for a protected resource, the following events occur:
- The incoming request is checked for a valid token.
- If a token is not found, then the client is sent a 401 status header indicating that it is not authenticated. This requires the client to authenticate using the SSO authentication resource as described in the Type 1 request section.
- If a token is found, then the incoming request for the protected resource contains a valid token and an authorization check is performed.
- If authorization is unsuccessful, a 403 unauthorized status header is returned to the client. If authorization is successful, the protected resource is served.
Programmatic login authentication
To enable programmatic login, configure the user registry for either LDAP or file based repositories. The default user registry is file-based
and only requires the zero.users file. See the User service section
for information about the various configuration options.
Programmatic login authentication code sample
The following sample leverages http request parameters to obtain the username and password values for the client. Programmatic login provides a flexible way to obtain userid and password information while still allowing access to the user registry provided by WebSphere sMash.
/*login.groovy script*/
package programmatic;
import zero.core.security.LoginService;
String userName = zget("/request/params/userName");
String password = zget("/request/params/password");
boolean success = LoginService.login(userName, password);
When authentication is successful and the login returns true, you can then retrieve user information.
Programmatic login authentication security flow
When a request comes in for an unprotected resource, the following events occur:
- You call the
LoginService.loginfunction withusernameandpasswordas arguments.- If the login is unsuccessful, then the API returns false indicating that you are not authenticated.
- If the login is successful, then the token is generated, and your credentials are populated in the
GlobalContextand are accessible by the application.
Programmatic logout code sample
The following sample uses the LoginService function to log off programmatically.
/*logout.groovy script*/ package programmatic; import zero.core.security.LoginService; boolean success = LoginService.logout();
After you log off successfully, your token is discarded and is considered not authenticated for the current request, or for subsequent requests, until you start the authentication process again.
Programmatic logout authentication security flow
When a request comes in for a protected resource, the following events occur:
- You call the
LoginService.logoutfunction with zero arguments.- If the logoff is unsuccessful, then the API returns false indicating you are not logged out.
- If the logoff is successful, then the token is removed, and your credentials are removed from the
GlobalContextand are not accessible by the application.