Skip to content
This repository was archived by the owner on Aug 23, 2023. It is now read-only.

Commit cd26e5b

Browse files
committed
Submitting Arjan's updates for authentication, identity store, and security context
1 parent 41f1a35 commit cd26e5b

File tree

3 files changed

+189
-3
lines changed

3 files changed

+189
-3
lines changed

spec/src/main/doc/authenticationMechanism.asciidoc

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,5 +143,55 @@
143143

144144
== Authentication Mechanism
145145

146-
to do
146+
This chapter describes the contract that specifies how a server-side authentication module defined by this specification works.
147+
148+
=== Introduction
149+
150+
A web application consists of resources that can be accessed by any number of callers that are initially unknown to the application. Callers make themselves known to the application via the process of authentication. In this process a caller presents a prove, the credential, which the application validates and if found to be correct responds to by making the data corresponding to this caller available.
151+
152+
For the interaction with the caller (the "authentication dialog between the caller and the system") where a prove is collected, this specification defines a dedicated entity; the authentication mechanism, represented by the _HttpAuthenticationMechanism_ interface.
153+
154+
=== Division of Responsibility
155+
156+
In a Java EE system the _HttpAuthenticationMechanism_ is responsible for starting and engaging in the authentication dialog when a caller attempts to invoke a Servlet resource. A caller can access a Java EE system via other ways, like for example invoking a remote EJB bean, sending a JMS message to a destination hosted by the Java EE system or generally via any type of JCA inflow. The _HttpAuthenticationMechanism_ explicitly has *no* responsibilities when a caller attempts to access any resource other than a Servlet resource.
157+
158+
=== Relationship to other specifications
159+
160+
An _HttpAuthenticationMechanism_ is a CDI bean, as defined by the CDI (JSR 346) specification. The methods defined by the _HttpAuthenticationMechanism_ closely map to the methods and semantics of a _ServerAuthModule_ as defined by the Servlet Container Profile of the JASPIC (JSR 196) specification, but an _HttpAuthenticationMechanism_ is itself not a _ServerAuthModule_.
161+
162+
This specification mandates that when a _ServerAuthModule_ is called by the Servlet container, CDI services (such as the _BeanManager_) are fully available and all scopes that are defined to be active during the _service()_ method of a servlet, or during the _doFilter()_ method of servlet filter are active. Specifically this means that the request scope, session scope and application scope must be active, and that a _ServerAuthModule_ method such as _validateRequest_ must be capable of 1) obtaining a reference to the CDI _BeanManager_ via programmatic means (for example, by doing a JNDI lookup) and 2) can use this reference to obtain a valid request scoped, session scoped or application scoped bean. This specification *does not* mandate that a _ServerAuthModule_ itself is a CDI bean or that a _ServerAuthModule_ is injectable.
163+
164+
An _HttpAuthenticationMechanism_ implementation is logically equivalent to a build-in authentication mechanism as defined by the Servlet spec, being HTTP Basic Authentication, HTTP Digest Authentication, Form Based Authentication and HTTPS Client Authentication, and more specifically is corresponding to an "additional container authentication mechanism" as described in section 13.6.5 of the Servlet spec.
165+
166+
167+
=== Installation
168+
169+
Installation of an _HttpAuthenticationMechanism_ depends on the CDI specification. That is, an _HttpAuthenticationMechanism_ is considered installed and available for usage when it's available to the CDI runtime as an enabled Bean. An _HttpAuthenticationMechanism_ is assumed to be normal scoped.
170+
171+
It *must* be possible for the definition of an _HttpAuthenticationMechanism_ to exist within the application archive. Alternatively such definition may also exists outside the application archive, for example in a jar added to the classpath of an application server.
172+
173+
=== Orchestrating the authentication dialog
174+
175+
The _HttpAuthenticationMechanism_ interface defines three methods that are used by the runtime to allow it to orchestrate an authentication dialog (interacting with a caller to obtain a credential):
176+
177+
* validateRequest
178+
* secureResponse
179+
* cleanSubject
180+
181+
All of these three methods must be called right after a Servlet container calls the similarly named methods on a _ServerAuthModule_ following the Servlet Container Profile of the JASPIC spec.
182+
183+
Summarized this means:
184+
185+
* _validateRequest_ must be invoked before the _doFilter()_ method of any servlet filter or the _service()_ method of any servlet in the application for requests to constrained as well as to unconstrained resources, and in addition in response to application code calling the _authenticate_ method on the _HttpServletRequest_.
186+
187+
* _secureResponse_ must be invoked after the _doFilter()_ method of any servlet filter or the _service()_ method of any servlet in the application for requests to constrained as well as to unconstrained resources, but only if any of these two methods have indeed been invoked.
188+
189+
* _cleanSubject_ must be invoked in response to the application calling the _logout_ method on the _HttpServletRequest_.
190+
191+
The _validateRequest_ method is provided to allow a caller to authenticate. An implementation of this method can inspect the HTTP request to for example extract a credential from an HTTP header, request parameter, post parameter, etc, or write to the HTTP response to for example redirect a caller to another resource such as a login form or an OAuth provider. After a credential has been obtained and validated, the result of this validation can be communicated to the container using the passed in _HttpMessageContext_, which is described in more detail below.
192+
193+
The _secureResponse_ method is provided to allow post processing on the response generated by a servlet and/or servlet filter, such as encrypting it.
194+
195+
The _cleanSubject_ is provided to allow for cleanup after a caller is logged out. For example, an authentication mechanism that stores state within a cookie can remove that cookie here.
196+
147197

spec/src/main/doc/identityStore.asciidoc

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,104 @@
143143

144144
== Identity Store
145145

146-
To do
146+
This chapter describes the contract that specifies how a server-side authentication module (that is, an implementation of the HttpAuthenticationMechanism interface as defined by this specification) may delegate some of its security processing responsibilities to an identity store.
147+
148+
149+
=== Introduction
150+
151+
A web application consists of resources that can be accessed by any number of callers that are initially unknown to the application. Callers make themselves known to the application via the process of authentication. In this process a caller presents a prove, the credential, which the application validates and if found to be correct responds to by making the data corresponding to this caller available.
152+
153+
For the transformation of a credential to caller data this specification defines a dedicated entity; the identity store, represented by the _IdentityStore_ interface.
154+
155+
=== Division of Responsibility
156+
157+
An _HttpAuthenticationMechanism_ is not mandated to delegate to an _IdentityStore_, and is free to perform a _{credentials in, caller data out}_ function itself or by delegating to any kind of proprietary entity. When an _HttpAuthenticationMechanism_ does delegate to an _IdentityStore_ it must do so by adhering to the constraints and semantics as described in this chapter.
158+
159+
An _HttpAuthenticationMechanism_ must not interact with an _IdentityStore_ directly but instead has to use the _IdentityStoreHandler_ and must do so in a caller environment independent fashion. This means specifically that an HttpAuthenticationMechanism is the only entity in this relation that may access the HTTP environment (for example, getting a request parameter or cookie from the (Http)ServletRequest). An _IdentityStore_ must only perform environment independent security processing (for example, verifying a username/password that was passed in to it as a String/char array and returning the caller data). In other words, the _IdentityStore_ must not directly interact with the caller and should perform a pure _{credentials in, caller data out}_ function.
160+
161+
162+
=== State
163+
164+
An _IdentityStore_ is logically stateless. An _HttpAuthenticationMechanism_ using an _IdentityStore_ should not make any assumptions about the state of such _IdentityStore_ following one or more calls to it. Specifically, the _IdentityStore_ store must not be aware of the point the caller has reached in the authentication process and even more specifically the _IdentityStore_ should not keep track of whether a caller is authenticated or not at any given moment in time.
165+
166+
An _IdentityStore_ instance is allowed to make use of instance variables, for example to store configuration data like a URL to an LDAP server, to store actual caller data for in-memory lookup, use instance variables for the purpose of caching, etc.
167+
168+
=== Installation
169+
170+
Installation of an _IdentityStore_ depends on the CDI specification. That is, an _IdentityStore_ is considered installed and available for usage when it's available to the CDI runtime as an enabled Bean. An _IdentityStore_ is assumed to be normal scoped.
171+
172+
It *must* be possible for the definition of an _IdentityStore_ to exist within the application archive. Alternatively such definition may also exists outside the application archive, for example in a jar added to the classpath of an application server.
173+
174+
=== Configuration
175+
176+
The _IdentityStore_ interface defines two methods that are used by the runtime to read configuration:
177+
178+
* int priority()
179+
* ValidationType validationType()
180+
181+
The _priority_ method allows an _IdentityStore_ to be configured with an ordinal number that indicates in which order an _IdentityStore_ is consulted in case multiple ones are present, or more exactly when multiple enabled CDI Beans with type _IdentityStore_ are available. A lower value returned here means that _IdentityStore_ is called before an _IdentityStore_ returning a higher value. The order of being called is undefined when two _IdentityStore_ implementations return the same value.
182+
183+
The _validationType_ method returns an enum constant of type _ValidationType_, that indicates if an _IdentityStore_ is to be used for authentication only (meaning any group data it returns must be ignored), for authorization only (meaning it's not used for authentication, but only to obtain the group data from if the caller is authenticated via other means), or both (meaning it's used for authentication and any group data it returns is used).
184+
185+
186+
=== Validation and obtaining caller data
187+
188+
The _IdentityStore_ interface defines two methods that are used by the runtime to validate a _Credential_ and/or to obtain caller data:
189+
190+
* CredentialValidationResult validate(Credential credential)
191+
* List<String> getGroupsByCallerPrincipal(CallerPrincipal callerPrincipal)
192+
193+
The _validate_ method is provided to allow the runtime to validate that a _Credential_ is valid, and if so to obtain the caller data associated with the _Credential_. A _Credential_ passed in to this method is deemed to be valid if and only if the _getStatus_ method called on the result of type _CredentialValidationResult_ returns the enum constant _VALID_. In that case calling _getCallerPrincipal_ on this same result will yield a _Principal_ representing the name of the authenticated caller, and calling _getCallerGroups_ on this same result will yield a list of zero or more groups that the authenticated caller is in.
194+
195+
An _IdentityStore_ implementation is allowed to support multiple types of concrete _Credentials_, where a concrete _Credential_ is an implementation of the _Credential_ interface. It can do so by either implementing the _CredentialValidationResult validate(Credential credential)_ method and testing the type of the _Credential_ that's passed in, or by overriding the _validate(Credential credential)_ method by one or more methods where the method parameter of each of these methods is the exact type of the _Credential_ implementation that the _IdentityStore_ is capable of handling.
196+
197+
The following shows an example of such overloaded method definition:
198+
199+
```
200+
public class ExampleIdentityStore implements IdentityStore {
201+
202+
public CredentialValidationResult validate(UsernamePasswordCredential usernamePasswordCredential) {
203+
// Implementation ...
204+
return new CredentialValidationResult(...);
205+
}
206+
}
207+
```
208+
209+
If an implementation of the _validate_ method finds out it's not capable of handling the actual type of the _Credential_ that is passed in, it *must* return a _CredentialValidationResult_ on which calling the _getStatus_ method returns the enum constant _NOT_VALIDATED_.
210+
211+
If validation of the _Credential_ fails, for example when it consists of an unknown or expired token or a username/pasword combination that does not match, the _validate_ method *must* return a _CredentialValidationResult_ on which calling the _getStatus_ method returns the enum constant _INVALID_.
212+
213+
The _getGroupsByCallerPrincipal_ method is provided to allow the runtime to obtain the list of groups associated with the _CallerPrincipal_ that is passed in. This in an optional method and an _IdentityStore_ implementation is not mandated to support this. If an _IdentityStore_ implementation does support this method it must be consistent with the _validate_ method, meaning that if the _validate_ method returns a _VALID_ result with _CallerPrincipal_ "foo" and groups _{bar, kaz, zak}_, then passing this _CallerPrincipal_ "foo" into the _getGroupsByCallerPrincipal_ method should yield the same list of groups _{bar, kaz, zak}_.
214+
215+
=== Build-in IdentityStore beans
216+
217+
A Java EE container must allow build-in beans for the following _IdentityStore_ types to be made available via configuration:
218+
219+
* Embedded - allowing caller data to be stored directly in an annotation. This bean is activated and configured via the @EmbeddedIdentityStoreDefinition annotation.
220+
* LDAP - allowing caller data to be stored in an external LDAP server. This bean is activated and configured via the @LdapIdentityStoreDefinition annotation.
221+
* Database - allowing caller data to be stored in an external database accessible via a DataSource bound to JNDI. This bean is activated and configured via the @DataBaseIdentityStoreDefinition annotation.
222+
223+
All of all these beans must have the qualifier @Default and the scope @ApplicationScoped, as defined by the CDI specification.
224+
225+
=== Handling multiple identity stores
226+
227+
Access to the _IdentityStore_ is abstracted by the _IdentityStoreHandler_, which is an interface providing a single method:
228+
229+
* CredentialValidationResult validate(Credential credential)
230+
231+
For the caller, which is for this specification the _HttpAuthenticationMechanism_, the semantics of the _validate_ method are as described for the _IdentityStore_ method with the same signature.
232+
233+
The purpose of the _IdentityStoreHandler_ is to allow for the presence of multiple identity stores to logically act as a single _IdentityStore_ to the _HttpAuthenticationMechanism_. A compliant implementation of this specification must provide a default implementation of the _IdentityStoreHandler_ that is:
234+
235+
* an enabled CDI bean
236+
* with qualier @Default and scope @ApplicationScoped, as defined by the CDI specification
237+
238+
The _validate_ method of the default implementation has to take the following actions:
239+
240+
* Call the _validate(Credential credential)_ method on all available _IdentityStore_ beans that declared to be capable of doing authentication in the order induced by the return value of the _getPriority_ method of each _IdentityStore_ (lower values returned by _getPriority_ means a lower order, and hence the _validate(Credential credential)_ method will be called sooner)
241+
* For the first such call to the _validate(Credential credential)_ method that returns a result on which calling _getStatus()_ returns _VALID_, stop calling the _IdentityStore_ beans and remember this result.
242+
* If all _IdentityStore_ beans have been called, and for none of those the _validate(Credential credential)_ method return a result on which calling _getStatus()_ returned a _VALID_ result, return the result of the last _IdentityStore_ that was consulted.
243+
* If we have a _VALID_ result, call the _getGroupsByCallerPrincipal(CallerPrincipal callerPrincipal)_ method on all available _IdentityStore_ beans that declared to be capable of doing only authorization in the order induced by the return value of the _getPriority_ method of each _IdentityStore_ (lower values returned by _getPriority_ means a lower order, and hence the _validate(Credential credential)_ method will be called sooner). The _CallerPrincipal_ passed in to this method is the _CallerPrincipal_ obtained from the result of calling _validate(Credential credential)_ before.
244+
* Return a new _CredentialValidationResult_ with status _VALID_, the _CallerPrincipal_ that was used in each call to the _getGroupsByCallerPrincipal_ method, and the collection of groups that is the combination of the groups returned by the result of the _validate(Credential credential)_ call for which _getStatus()_ returned _VALID_ and all of the groups returned by each call to the _getGroupsByCallerPrincipal_ method.
245+
246+

spec/src/main/doc/securityContext.asciidoc

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,5 +143,41 @@
143143

144144
== Security Context
145145

146-
to do
146+
This chapter describes the contract that specifies how a security aware application can take advantage of programmatic security.
147+
148+
149+
=== Introduction
150+
151+
The Java EE platform defines a declarative security model via which resources can be constrained. These constraints are then enforced by the container. In some cases the declarative model is not sufficient, for example when more complex combinations of constraints and tests are needed than the declarative model allows. Programmatic security allows an application to perform tests and grant or reject access to resources itself.
152+
153+
This specification provides an access point for programmatic security; the security context, represented by the _SecurityContect_ interface.
154+
155+
=== Relationship to other specifications
156+
157+
The _SecurityContect_ implementation is a CDI bean, as defined by the CDI (JSR 346) specification.
158+
159+
Various specifications in Java EE provide similar or even identical methods to those provided be the _SecurityContect_. It is the intention of this specification to supersede all of those and provide a cross-spec, platform alternative. The following gives an overview:
160+
161+
* Servlet spec - _HttpServletRequest#getUserPrincipal_, _HttpServletRequest#isUserInRole_
162+
* EJB spec - _EJBContect#getCallerPrincipal_, _EJBContext#isCallerInRole_
163+
* JAX-WS spec - _WebServiceContext#getUserPrincipal_, _WebServiceContext#isUserInRole_
164+
* JAX-RS spec - _SecurityContext#getUserPrincipal_, _SecurityContext#isUserInRole_
165+
* JSF spec - _ExternalContext#getUserPrincipal_, _ExternalContext#isUserInRole_
166+
* CDI - _@Inject Principal_
167+
* WebSockets - _Session#getUserPrincipal_
168+
169+
=== Testing for caller data
170+
171+
The _SecurityContect_ interface defines two methods that allow the application to test aspects of the caller data:
172+
173+
The _getCallerPrincipal_ method is provided to retrieve the _Principal_ that represents the caller's name. It *must* be possible for the application to downcast this _Principal_ to the exact _Principal_ type that was set by the _HttpAuthenticationMechanism_ (possibly via an _IdentityStore_) or a JASPIC _ServerAuthModule_.
174+
175+
The _isCallerInRole_ method takes a string argument that represents the application role that is to be tested for. The application role is defined as the group name as set by the _HttpAuthenticationMechanism_ (possibly via an _IdentityStore_) or a JASPIC _ServerAuthModule_ after group to role mapping has taken place.
176+
177+
=== Triggering the authentication process
178+
179+
The _SecurityContect_ interface defines two overloaded methods that allow the application to programmatically trigger the authentication process. Programmatically triggering means that the container responds as-if the caller had attempted to access a constrained resource and responds with invoking a configured authentication mechanism (such as the _HttpAuthenticationMechanism_).
180+
181+
The _authenticate_ method allows an application to signal to the container that it should start the authentication process with the caller. This method requires an _HttpServletResponse_ argument to be passed in, and can therefore only be used in a valid Servlet context.
182+
147183

0 commit comments

Comments
 (0)