Re: Welcome to the new JSR-375 mailing list


Will Hopkins
 

Arjan,

On 05/16/2017 08:19 AM, Arjan Tijms wrote:
Hi,

On Tue, May 16, 2017 at 11:41 AM, Will Hopkins <will.hopkins@...> wrote:
I agree that the existing mechanisms aren't modern, and that there may be use cases where developers want or need to modify the process. That said, I think the legitimate use cases are probably few and far between. Existing implementations of FORM and BASIC have been refined over the years, such that they are robust and handle most reasonable requirements.

The entire purpose of the JSR was though to modernise security and make it more easy for users to us. Sure everything in the various Java EE servers have been refined over the years and handle most reasonable requirements, but if we take that as our most important principal, JSR 375 might not even have been needed (which I don't think is the case).

OK, good point.

The example you provide above demonstrates the capability, but doesn't demonstrate the need -- in my view, intervening to check username/password length before actually validating the credentials is misguided on separation of duties grounds -- only the identity store can authoritatively say whether the credentials are valid or not -- and is potentially insecure. Best practice when validating credentials is to return "login failed" for all failure cases, regardless of the cause.

I do agree about not giving the user too much information, that's definitely true. But the fact that you have to enter anything at all is not the kind of information you need to withhold. The password length and various constraints can already be learned when you sign up for a new account, so it's also not something you need to withhold in many cases (cases of public websites mostly).

Look at what e.g. Oracle.com does when you login; https://login.oracle.com/mysso/signon.jsp

If you don't enter anything it says:

"Please enter your username and password"

Yes, but there's a difference between the form complaining because you didn't enter *anything*, and complaining about specific issues with with the values a user *did* enter.

But even if you don't like the binding and bean validation, the part where you continue the dialog programmatically and set the single "login failed" message from the backing bean is already very valuable. This too is non-obvious how to do when posting to j_security_check,

Got it.

I have not heard feedback from our customers that they need or want to extend the functionality provided by FORM or BASIC authentication in WebLogic.

When I was working on various projects for various companies this need came up quite often. As said, especially in JSF/CDI applications the existing authentication mechanisms are contrived and arcane. I've seen people either struggling to get it integrated, or even more often, don't use the Servlet mechanisms at all but just use Shiro or roll their own variant.

There was a request for this in the JSF JIRA tracker as well, the issue with the most votes actually. We closed it in JSF because we felt such concern would be better handled by the Security JSR.

OK.

Also -- is it not possible to reference a CDI bean, or perform validation on j_username/j_password in some other way, from a login form using the existing mechanism?

All the existing ways are not so obvious. Sure, it's possible, but that's not the main point of the JSR, which is not only about making things possible, but about making things easier and more aligned with modern Java EE.

I've been thinking in terms of adding new APIs while not necessarily fixing things that aren't broken, but I understand the POV.

My proposal would be specify that the container should use an application-supplied IdentityStore for FORM/BASIC if present, but also that the container is permitted to override an application-provided IdentityStore with one of its own. i spent some time reading the CDI spec, and it appears to me that this would be possible by observing events during bean discovery and replacing the application's bean with a container bean when the appropriate event is fired -- I'm still not sure which event is the most appropriate one, though -- I'd be interested in your thoughts, as you clearly know CDI better than I.

Yes, the latter should indeed be possible via CDI. I would say the container is allowed to override the IdentityStoreHandler even, as that one is the true entry point to the identity stores.

By overriding the handler it would make sure that only the container's version is used of everything.

Additionally, the container could also be allowed to just add one or more identity stores, as the default handler is capable of working with multiple ones. That way it would be relatively easy to have the container provided store be at the highest priority with the app provided one as the fallback, or the other way around.

OK, yhat seems like a good approach, I'll make sure it's spec'd that way. I don't think I'll spec the idea about requiring the container to use an app-supplied IdentityStore -- you've convinced me about the FORM and BASIC annotations, so that's how the app can leverage an IdentityStore for FORM and BASIC.

How do you feel about specifing that HAMs are only required to be enabled when the app is deployed with <auth-method>AUTHMECH</auth-method>, though, to ensure that containers can continue support legacy apps using the existing code paths, and to ensure deterministic behavior when, for example, two implementations of FORM or BASIC are still present in the container. Containers could still choose to provide just one impl, and to implement all functionality via HAM, and apps could ensure they always got HAM by specifying the AUTHMECH, but legacy behavior got be safely preserved if a container vendor chose.

Agreed, and I'm generally a fan of consistency. In this case, the question in my mind is whether consistency alone is a good enough reason to require containers to provide this functionality when it would impose an implementation cost on container vendors and there is no clear functional requirement driving it.

The consistency aspect is already one advantage, while being able to decorate or intercept the mechanism is quite an advantage too. That way you can add a lot of things, from auditing (logging the calls to the mechanism and its response), adding SSO capabilities, and what have you. It basically gives applications (and libraries) more handles to extend Java EE security, where the existing mechanisms don't have any.

And containers using the RI and not wishing to put extra effort in can always use the RI provided ones, which are there to be used as well.

Yep. I see the value. I do think this will add significant additional implementation work for containers, though.

The problem with the TCK only approach is that once it's final, it's final. So you have to predict all cases in advance. But you often can't predict it when you're not actually using it.

True. Hopefully, if the spec is well written and faithfully translated into test cases we can keep issues to a minimum.

I still feel like RememberMe is not well-defined. If it's really a session management facility, then it's under-specified, it shouldn't be delegating to an IdentityStore, and there's no clear rationale for implementing a new session management capability in addition to what the container already provides. Existing container session management is almost certainly more robust and more secure than RememberMe. I would argue that long-lived sessions are a bad idea (as distinct from long-lived authentication tokens), but existing containers allow for configurable session lifetimes.

So the light-bulb went off a little while ago. I had been thinking in terms of bank-level security, general-purpose architecture for token issuance, integration with container session management,etc. -- then I remembered that my bank won't let me stay logged in longer than 20 minutes, but lots of other sites have little "Remember Me" checkboxes, and I understood the use case. It's really not a distinct architectural function, it's more like a feature added onto authentication, so the current implementation makes sense. Sorry for being so dense about it.

That's a detail of the implementation of the remember me identity store. The token has to be sufficiently random and the application should store a hash of it, not the token itself.

Agree it's an implementation detail, but if what you mean is that the client should store only a hash, that doesn't provide any additional security, because the hash will be as good as the "original" token -- it must be possible to use the hash as the authentication token, because that's all the client will have access to. If it's just an identifier, then any unique, random value of sufficient size will do. Hashing algorithms can provide those, but don't really add much value over a good PRNG. If the token carries data, it will have to be encrypted, and the client will have to retain the actual token, not just a hash of it.

Lastly, the RememberMe annotation provides very little configurability -- it only supports cookies (not, e.g., HTTP headers, or form fields), and even for cookies allows configuration only for cookie name and lifetime.

Those can be expanded over time, of course. For a 1.0 release cookies should be fine. They are the most commonly used artefact. See e.g. http://stackoverflow.com/a/244907/472792 and https://paragonie.com/blog/2015/04/secure-authentication-php-with-long-term-persistence#title.2

Annotations, which are the entry point to configurability, are very easily extendable (add attributes to them in a backwards compatible way).

OK.

It may be a good idea though to add a general key/value map, so vendors can extend the configuration (of which the most popular ones can be put up for standardisation later). Then again, a second vendor specific annotation is always an option as well, so we as spec would not have to worry about that.

Let's not add anything else new.  ;)

RememberMe doesn't seem sufficiently well thought out yet.

It really is; a lot of alternatives were considered and rejected, and we looked a lot at existing implementations both in Java and elsewhere.

Yep, I just didn't get the use case right away.

I think a key conceptual difference between what happens in step 2 and what happens in step 3. Step two is the container identifying an authentication token and using it to authenticate the user. The function/behavior of step 3 depends on whether FORM is just an alternative authentication mechanism (because multiple acceptable mechanisms are available), or whether step 3 is really a redirect to a token issuance service. (Not necessarily a literal redirect, but a logical redirect.)


Indeed, step 2 and step 3 are conceptually different. Step 1 and 2, while different have a number of things in common.

I guess I see them all as functionally distinct now. The first analogy that comes to mind is the hierarchy of storage for a CPU -- the CPU operates on data in registers; data is loaded into registers from the L2 cache, when there's an L2 cache miss the data is loaded from core memory, and data that's not in core memory is read from disk. The fallback process from HTTP session to RememberMe to credentials-based authentication seems analagous.

Yes -- thanks for the explanations. I still don't think RememberMe is ready to specify, but I'm more comfortable with the FORM and BASIC annotations. Do you think you could send me a brief write-up of those today?

I could for sure. The core specification of them is in the annotation now, but as appeared in this conversation it certainly wouldn't hurt to provide more clarification about this in the spec document.

Thanks, saw your recent pull request. I don't think every aspect has to be fully documented in the spec -- javadoc is fine as a detail-level reference -- but I do think the spec needs to at least mention the existence of every significant feature, and probably provide some high level discussion of the feature's purpose and function.

So, on to the next topic -- there are a couple other interfaces I think need to be moved, removed, and/or tweaked:
  • There was discussion on the list a while back about EmbeddedIdentityStore, and whether it represented a security risk and/or an anti-pattern. Although there was not complete agreement within the EG, there was support for the idea that it's not a good practice, and that we shouldn't encourage it by including it in the API. It has value for some development use cases, but those use cases could be easily satisfied by including it in the RI, and ultimately it's pretty trivial to write an actual IdentityStore implementation that has hard-coded user data and/or reads from a file, keystore, or other embedded repository.
I agree with the concern, and intend to remove it from the spec (i.e., API javadoc).
  • For ServletContext, I intend to:
    • Remove the newly added methods (getAllDeclaredCallerRoles() and hasAccessToXXX())
    • As previously agreed, remove the "response only" signature for authenticate (authenticate(HttpServletResponse, AuthenticationParameters)).
    • Specify that ServletContext is supported only in EJB and Servlet containers, or possibly a *short* list of additional containers (likely the web-based containers) where it's known that the getCallerPrincipal() and isCallerInRole() methods can be implemented by layering on existing container APIs.
  • AuthenticationStatus -- weren't we going to align that with the JASPIC return codes, so that the correspondence would be completely clear even though we weren't re-using the actual type/constants?
  • AuthenticationContext -- this is a bit of a kitchen sink. I guess we can live with that, but we at least need to provide javadoc for all of the getters/setters. As the author, you're best positioned to do so, I think.
  • Would BaseMessageContext be a better name for MessageContextWrapper? The class doesn't actually wrap anything, it simply implements the MessageContext interface. (Both classes could use some javadoc.)
  • I'll probably add some fields to the LdapIdentityStoreDefinition annotation to allow developers to specify a particular search string (LDAP syntax) and map a particular LDAP attribute to the caller principal name.

Thanks,

Will

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803

Join javaee-security-spec@javaee.groups.io to automatically receive all group messages.