|
|
|
Authentication
Project Zero 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 sections of this article provide information about the types of authentication available:
Basic authentication
Basic authentication is defined in RFC 2617.
Basic authentication security flow
When a request comes in for a protected resource, the following events take place:
- 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, the client is sent a 401 status header along with a request for credentials.
- Successful, a token is generated for subsequent requests and an authorization check is performed.
- If authorization is:
- Unsuccessful, a 403 unauthorized status header is returned to the client.
- Successful, the protected resource is served.
Form-based authentication
To enable form-based authentication, you need to 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 ${zero.core}/config/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. All authenticated users are allowed access as the following example shows:
[@include ${zero.core}/config/security/rule.config]
uri=/formauth/customers(/.*)?
authType=Form
groups=[ALL_AUTHENTICATED_USERS]
Additionally, if you want to make use of 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 matches /logout]
Creating a login form
Form-based login requires the creation of a login form at the location specified by formLoginPage. There are several requirements for this form:
- The method must be
POST.
- The action must result in the request going to the login page,
formLoginPage, upon submit. If a user navigates to the login page as a result of directory indexing (for example, requests to the root of the application without a resource explicitly listed), the action needs to be formLoginPage. For all other types of requests, the action can be left blank.
- The
username field must be named zeroUserName.
- The
password field 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, as described in the following sections.
Requesting a protected resource
When a request comes in for a protected resource, the following events take place:
- 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
formLoginPage entry).
- 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 upon submit.
- A login is attempted with the incoming credentials.
- If the login is:
- Unsuccessful, the login page is returned again with a 200 status code.
- Successful, 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 was stored in the
postLoginTargetURI query parameter).
- 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.
- Successful, the protected resource is served.
Requesting an unprotected form login page
When a request comes in for the form login page, the following events take place:
- A login is attempted with the incoming credentials.
- If the login is:
- Unsuccessful, the login page is returned again with a 200 status code.
- Successful, 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 was stored in the hidden
postLoginTargetURI form field parameter).
- 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.
- Successful, the protected resource is served.
Note If the FormBasedLoginHandler does not receive the parameter postLoginTargetURI, the assumption is that the user should be redirected to the context root of the application where the application developer can define a default file resource to handle the request.
Single sign-on authentication
Project Zero single sign-on is scoped to the Zero application. To enable Project Zero single sign-on based authentication, specify two configuration stanzas.
Advanced Topic For information about single sign-on scoped at the server level, see the LTPAToken2 support section of the Token support article.
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:
[@include ${zero.core}/config/security/sso.config]
ssoURL=/sso/login
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. Only users who are defined as part of the CUSTOMERS group, as shown in the following example, are allowed access.
[@include ${zero.core}/config/security/rule.config]
uri=/sso/customers.groovy
authType=SSO
groups=[CUSTOMERS]
You can configure an optional realm to be used by single sign-on as shown in the following example:
[/config/security]
realm=Secret Area
If no realm is set, the default realm is Secure Area.
If you want 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/POST[]]
handler=zero.core.security.LogoutHandler.class
conditions=[/request/path matches /logout]
Creating a login form
Project Zero single sign-on can be implemented in a variety of ways. One example would be to start with the Creating a login form example and convert to a login widget. The main difference is the form action needs to be the ssoURL. The following requirements must also be met:
- The action must be the location specified in the
ssoURL field in the zero.config file.
- The
username field must be named zeroUserName.
- The
password field must be named zeroPassword.
The following code snippet 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="callLogin(); return false;"/>
</form>
<script type="text/javascript">
function callLogin(){
dojo.io.bind({
formNode: document.getElementById( "loginForm" ),
method: 'POST'
});
}
</script>
Advanced Topic For scenarios in which using a form is not ideal, SSO also supports JSON encoded parameters. The names of the parameters are the same (zeroUserName and zeroPassword) with the target URL (ssoURL defined in the zero.config file) also remaining unchanged from the login form example.
Single sign-on security flow
By default, Project Zero single sign-on can be viewed in two types of requests. The first type of request is the login with the second step being requests to protected resources that can occur multiple times.
Advanced Topic For cross Web application scoped single sign on, see the LTPA 2 section of this document.
Type 1 request
When a request is made to the single sign-on resource the following events take place:
- 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, the client is sent a 401 status header along with a request for credentials.
- Successful, a token is generated for subsequent requests.
Type 2 request
When a request comes in for a protected resource, the following events take place:
- 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 described in the Type 1 request section.
- 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.
- Successful, the protected resource is served.
Programmatic login authentication
To enable programmatic login, the only requirement is to 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 of the Core Developer's Guide 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 Project Zero.
/*login.groovy script*/
package programmatic;
import zero.core.security.LoginService;
String userName = _gc.get("/request/params/userName");
String password = _gc.get("/request/params/password");
boolean success = LoginService.login(userName, password);
When authentication is successful and the login returns true, you can then retrieve user information as described in the
Retrieving user information section of the Security considerations article.
Programmatic login authentication security flow
When a request comes in for an unprotected resource, the following events take place:
- An application developer calls
LoginService.login with username and password as arguments.
- If the login is:
- Unsuccessful, the API returns false indicating the user was not authenticated.
- Successful, the token is generated and user credentials are populated in the
GlobalContext and are accessible by the application.
Programmatic logout code sample
The following sample uses the LoginService function to log a user out programmatically.
/*logout.groovy script*/
package programmatic;
import zero.core.security.LoginService;
boolean success = LoginService.logout();
Upon successful logout, the user's token is discarded and is considered not authenticated for the current request or for subsequent requests until the authentication process is started again.
Programmatic logout authentication security flow
When a request comes in for a protected resource, the following events take place:
- An application developer calls the
LoginService.logout function with zero arguments.
- If the logout is:
- Unsuccessful, the API returns false indicating the user was not logged out.
- Successful, the token is removed and user credentials are removed from the
GlobalContext and are not accessible by the application.
PHP See the Functions for using Project Zero active content filtering programmatically section of the Additional PHP functions article for more information on leveraging programmatic login and logout using PHP.
|