Resending as plain text, since my earlier HTML formatted email
didn't display well in the java.net archive.
Experts:
First of all, many thanks to Arjan for putting together the first
draft of our spec -- it's an excellent start.
I've had a look at it, and have some comments/questions for
discussion. I think the biggest issues to resolve are probably:
* The interaction (or lack thereof) between
HttpAuthenticationMechanism and JASPIC.
* On a similar note, what is the behavior if
HttpAuthenticationMechanism is called both by the container and by
application code?
* How is SecurityContext integrated with containers such that
authenticate() can know what authentication mechanisms are
configured and getXYZ() can report the correct information?
* Is CallerPrincipal a sufficient credential for
IdentityStore.getGroupsByCallerPrincipal()? Can it be safely used
when there are multiple ID stores configured (since the wrong groups
could potentially be returned)?
* Related: should we define CallerAttributes in addition to
CallerGroups?
Any and all comments welcome.
Thanks,
Will
0.0 General
Use of CDI vs. other mechanisms for accessing the interfaces -- I
think it's reasonable to say that containers must use/support CDI in
the ways described by the spec. (Am I correct that all EE Profiles
that include servlet would also include CDI?) Is it worthwhile
specifying that EE implementations can optionally choose to make the
interfaces available in some other way (factory method, etc.)?
Should we specify such a mechanism?
2.4 Installation
Container should be able to override ID store contained within app.
2.6 Validation and obtaining caller data
Should the API support other types of user attributes beyond
groups? A generic attribute type?
What if the information in a caller principal is insufficient to
distinguish the caller's identity (if, for example, the credential
provided when authenticating included a full DN, or a duplicate
username was disambiguated by virtue of the fact that the password
matched)? In that case, the correct groups could not be determined.
Should we limit the use of this to validate, and require the caller
to make use of the returned groups when creating a subject, or
retain the CredentialValidationResult?
Would overloading actually work in this case, or would the runtime
always call validate(Credential) even if a Credential sub-class type
is passed? Might need generics for this.
Last paragraph -- what if it can't, because it can't distinguish
between two foos, or because name is insufficient to identify the
user. Can (or should) an ID store support
getGroupsByCallerPrincipal() for a CallerPrincipal not originally
validated by that ID store?
2.7 Build-in Identity Store Beans
Embedded -- annotation only? No support for deploying a file or
other mechanism? Safety of embedding passwords in file or in code
(annotation)?
LDAP -- is annotation rich enough to support real-life deployment
requirements?
2.8. Handling multiple identity stores
When validation fails, would it not be better to remember if any of
the identity stores accepted the credential, and return INVALID
instead of NOT_VALIDATED if any of them did?
If we have a VALID result, won't we already have the groups
associated with the validate() that succeeded? Do we want to
aggregate groups from all stores, that return them, or return only
groups from the store that validated the user? I would argue for
the latter. This issue also complicates the provision of a separate
group lookup method when more than one id store is present -- what
if store A has a user foo, but validation fails. Store B also has a
user foo, which is validated with the supplied credential. A
subsequent call to get groups would succeed for store A, but return
groups for the wrong user (i.e, the "foo" whose credential was not
validated).
3.3 Relationship to other specs
3.4 Installation
It must be possible to package an HttpAuthenticationMechanism in an
app, but can it be possible for server to override app-provided
mechanism?
Should we define a web.xml token for indicating that an
HttpAuthenticationMechanism is in use, similar to BASIC, FORM, CERT?
(since the analogy is presented in section 3.3).
3.5 Orchestrating the authentication dialog
Does validateRequest() get called twice, then, if called by the
container and again when the application calls authenticate()? Must
it therefore be idempotent?
Should the ServerAuthModule's secureResponse() method be called if
the HttpAuthenticationMechanism's is?
What happens if there is also a ServerAuthModule
installed/configured for the app? Are both mechanisms invoked (it
seems likely they'd interfere with each other)? How does, e.g., an
error returned from a ServerAuthModule affect the subsequent
invokation of the HttpAuthenticationMechanism?
The JASPIC spec goes into some detail about exit codes from
validateRequest() and the subsequent behavior of the container in
terms of returning errors vs. proceeding to invoke the servlet,
codes that indicate success but a requirement to continue dialog
with the client before invoking the servlet, etc. What should HAMs
do? Should we specify behavior that matches SAMs? Different
behavior?
4.0 General
How does SecurityContext determine the caller principal and query
the roles? Is it the responsibility of containers to ensure the
SecurityContext is populated with the correct information? Does it
get the current Subject of the stack and use that to get the
CallerPrincipal and test roles? Etc.
4.2 Relationship to other specs
This spec declares that the new security context supercedes all
these other mechanisms. Should we say something about what the
legacy behavior is, for older apps, and the extent to which the old
and new mechanisms must return the same values? I.e., we could
declare that the older mechanisms remain, for legacy support, but
must be implemented by delegating to the new SecurityContext, or, at
minimum, behave at all times as if they delegated to
SecurityContext. (This also implies that the new SecurityContext
must return values consistent with the older APIs.)
4.3 Testing for Caller Data
Downcasting -- to be clear, this section does not assume that HAM
and SAM are the only possible sources of Caller Principals,
correct? I.e., a container might choose to implement BASIC, FORM,
and CERT using proprietary interfaces. Or are we suggesting that all
containers should provide BASIC/FORM/CERT via HAM or SAM?
isCallerInRole() -- this should not be defined to map explicitly to
a group principal in the subject; rather, it should map to a role in
a security constraint, which may be mapped arbitrarily by the
container. See, e.g., the javadoc for isCallerInRole/isUserInRole
for EJBContext/HttpServletRequest.
--
Will Hopkins | Platform Security Architect | +1.781.442.0310
Oracle Cloud Application Foundation
35 Network Drive, Burlington, MA 01803