jsr375-experts@javaee-security-spec.java.net

[jsr375-experts] Re: Working example app demonstrating identity store usage

From: arjan tijms <arjan.tijms_at_gmail.com>
Date: Thu, 17 Dec 2015 21:25:24 +0100

Hi,

On Thu, Dec 17, 2015 at 7:01 PM, Werner Keil <werner.keil_at_gmail.com> wrote:

> Dear All,
>
> A little follow-up. I'll also plan to upload the slides either today or
> over the weekend.
> The app-db example feels like something gets stuck, either the data source
> is no longer accessible or similar. Even adding and removing the app to
> GlassFish 4 did not help..
>

Unfortunately data sources seem to be a little buggy on GlassFish, at least
embedded ones. java:app doesn't work at all, I encountered some issues with
XA connection pooling, and indeed, data sources stick around and you need
to restart GlassFish :(

Payara recently fixed this last bug though, see
https://github.com/payara/Payara/pull/565

A couple of other data source problems are in the associated issue:
https://github.com/payara/Payara/issues/510

In general, bugs in various servers is part of what causes some seemingly
simple example applications to take up quite a lot of time.




> One question I'm not entirely sure, if it's applicable was, if vendors of
> JCE implementations were to adopt JSR 375. Maybe it's simply the
> "java.security" package name that created such impression. The only area
> which I brushed answering someone else's question was, that at least in
> production where passwords aren't masked using aliasing the actual password
> store should always be encrypted, too.
>

Indeed, so password aliasing is as you know on the schedule of this JSR and
I assume this may use JCE, but this is a topic Alex likely knows more about.

Btw, the provided examples are all aimed at demonstrating the API
interactions, and the current implementations are as simple as can be. The
data in the various stores is now all unencrypted. Naturally this should
never be done in production.



> Not from Tel Aviv, but the host of Hackergarten Zürich, Oliver Nautsch
> asked based on actual needs we help the current client meet on Java EE 6
> with proprietary extensions to CDI and other frameworks built in-house.
> Taking the "Movie" DB test case
> https://github.com/javaee-security-spec/javaee-security-examples/tree/master/roles-allowed-and-runas
> he hinted, whether it was possible to add a "content aspect" to the
> SecurityContext / RunAs. Say "Manager1" could only manipulate or see movies
> by "Quentin Tarantino" while "Manager2" could only do so for "Joel Coen".
>

It sounds interesting and a bit like the entity equivalent of row level
security in a SQL DB. I have to leave it to Alex to answer anything
definite here about this being in scope of this JSR.

As mentioned by Alex, an important goal of the JSR is to grab the really
low hanging fruit; the obvious things that for some reason or the other
never have been standardised before. It's an open question if we'll be able
to get to the more advanced things.


>
> Actually looking at the large PDF Alex presented at least in Paris (and
> probably also London or JavaOne?) this sounds like involving "Dynamic Role
> Mapping" with roles like "EDIT_ACCOUNTS", "CLOSE_ACCOUNT", etc. If this was
> done on a fine grained level like "EDIT_TARANTINO_FILMS" vs.
> "EDIT_COEN_FILMS" just to give an example (or say "VIEW_ADULT_FILMS" based
> on a person's age;-) it might go in the direction of what the client uses
> here and Oliver suggested.
>

In case of the row level security equivalent, my guess would be that (JPA)
entities have to support some notion of security constraints; a kind of
cross between bean validation and @RolesAllowed. I.e. a roles allowed
placed on a "value", and the entity manager checking this for various
operations.

Fine grained roles could be done by simply giving user "Manager1" the role
"EDIT_TARANTINO_FILMS", etc, right?

Or is "Manager1" a role name here, and do you mean that someone with role
"Manager1" should also get role "EDIT_TARANTINO_FILMS"? If that's the case
it would more be a matter of (standardised) group to role mapping perhaps.

Dynamic role mapping, where for every authorization decision roles are
dynamically evaluated is in fact today possible via JACC. A (custom) JACC
provider is called every time @RolesAllowed and access to a URL is
evaluated and can do things like taking time into account.

JEUS has a native authorization system that is very JACC like. They have
some interested added concepts, like that in a role mapping you have the
tuple {role name, action, class name}.

See
https://translate.google.com/translate?&u=http%3A%2F%2Ftechnet.tmaxsoft.com%2Fupload%2Fdownload%2Fonline%2Fjeus%2Fpver-20150722-000001%2Fsecurity%2Fchapter_security_system_API_programming.html

Taking age into account is more difficult, since the authorisation system
has to know where it can find the age of the caller. For the proposed new
annotation that takes an EL expression this should be quite doable (you
pass the age in), but for web.xml security constraints this is more
difficult.

But these are all good points for the authorization epic of this JSR ;)





>
> Kind Regards,
> Werner
>
> On Thu, Dec 17, 2015 at 5:24 AM, Werner Keil <werner.keil_at_gmail.com>
> wrote:
>
>> All,
>>
>> Had a great talk yesterday. At least 50-70 people (guess DevoXX Be
>> probably had more, not sure about FR or Uk?) in a cinema very similar to
>> Antwerp ;-)
>>
>> I invited those interested to join the mailing list or Github. Right
>> before my Session was one on the value of Open Source which was a good
>> introduction. Will Post slides on Slideshare. Thanks everyone especially
>> Arjan.
>>
>> Regards,
>> Werner
>> Am 15.12.2015 18:48 schrieb "arjan tijms" <arjan.tijms_at_gmail.com>:
>>
>>> Hi,
>>>
>>> Another update: I finally came around to implementing an experimental
>>> version of the simplified SAM.
>>>
>>> This version is based on the HttpServerAuthModule that was used in
>>> several examples before, and which in turn was based on the one from
>>> OmniSecurity.
>>>
>>> The difference is that instead of a base class, it's now an interface
>>> (as previously discussed). It closely follows the methods of a SAM, but the
>>> type implementing it is no longer a SAM itself.
>>>
>>> For now I've defined the interface as follows:
>>>
>>> public interface HttpAuthenticationMechanism {
>>>
>>> AuthStatus validateRequest(HttpServletRequest request,
>>> HttpServletResponse response, HttpMsgContext httpMessageContext) throws
>>> AuthException;
>>>
>>> default AuthStatus secureResponse(HttpServletRequest request,
>>> HttpServletResponse response, HttpMsgContext httpMessageContext) throws
>>> AuthException {
>>> return SEND_SUCCESS;
>>> }
>>>
>>> default void cleanSubject(HttpServletRequest request,
>>> HttpServletResponse response, HttpMsgContext httpMessageContext) {
>>> httpMessageContext.cleanClientSubject();
>>> }
>>>
>>> }
>>>
>>> See
>>> https://github.com/arjantijms/mechanism-to-store-x/blob/master/jsr375/src/main/java/javax/security/authenticationmechanism/http/HttpAuthenticationMechanism.java
>>>
>>>
>>> The JSR 375 CDI extension scans for the one and only implementation of
>>> HttpAuthenticationMechanism, and if found installs a bridge SAM for it that
>>> calls this implementation for each method: E.g. for validateRequest it
>>> looks like this:
>>>
>>> public AuthStatus validateRequest(MessageInfo messageInfo, Subject
>>> clientSubject, Subject serviceSubject) throws AuthException {
>>> HttpMsgContext msgContext = new HttpMsgContext(handler, options,
>>> messageInfo, clientSubject);
>>> return CDI.current()
>>> .select(HttpAuthenticationMechanism.class).get()
>>> .validateRequest(msgContext.getRequest(),
>>> msgContext.getResponse(), msgContext);
>>> }
>>>
>>> Just like the identity store, applications can now use a "sam" by only
>>> having an implementation of HttpAuthenticationMechanism on their classpath.
>>> The code now looks much simpler too. E.g. the example SAM used before is
>>> simplified into this:
>>>
>>> @RequestScoped
>>> public class TestAuthenticationMechanism implements
>>> HttpAuthenticationMechanism {
>>>
>>> @Inject
>>> private IdentityStore identityStore;
>>>
>>> @Override
>>> public AuthStatus validateRequest(HttpServletRequest request,
>>> HttpServletResponse response, HttpMsgContext httpMessageContext) throws
>>> AuthException {
>>>
>>> if (request.getParameter("name") != null &&
>>> request.getParameter("password") != null) {
>>>
>>> // Get the (caller) name and password from the request
>>> // NOTE: This is for the smallest possible example only. In
>>> practice
>>> // putting the password in a request query parameter is
>>> highly
>>> // insecure
>>> String name = request.getParameter("name");
>>> Password password = new
>>> Password(request.getParameter("password"));
>>>
>>> // Delegate the {credentials in -> identity data out}
>>> function to
>>> // the Identity Store
>>> CredentialValidationResult result = identityStore.validate(
>>> new UsernamePasswordCredential(name, password));
>>>
>>> if (result.getStatus() == VALID) {
>>> // Communicate the details of the authenticated user to
>>> the
>>> // container. In many cases the underlying handler will
>>> just store the details
>>> // and the container will actually handle the login
>>> after we return from
>>> // this method.
>>> return httpMessageContext.notifyContainerAboutLogin(
>>> result.getCallerName(), result.getCallerGroups());
>>> } else {
>>> throw new AuthException("Login failed");
>>> }
>>> }
>>>
>>> return httpMessageContext.doNothing();
>>> }
>>>
>>> }
>>>
>>> See:
>>> https://github.com/arjantijms/mechanism-to-store-x/blob/master/app-db/src/main/java/test/TestAuthenticationMechanism.java
>>>
>>> One partially unsolved problem, which I happen to have discussed with
>>> Ron Monzillo some time ago, is how module options should neatly arrive in
>>> this CDI enabled SAM. Currently they can be obtained from the
>>> HttpMsgContext. Ideally though, you may want to inject them and do
>>> something in the @PostConstruct method.
>>>
>>> But as those module options are per SAM, and there can be multiple SAMs,
>>> even of the same class type, I was struggling a little on how to support
>>> that.
>>>
>>> CDI itself has something like this with their Bean<T>, and they use a
>>> unique ID for that that is typically set to just the classname, but can be
>>> more eloborate if needed. Typically the values of constructor parameters
>>> are included if the Bean<T> has one. See e.g.
>>> https://github.com/javaserverfaces/mojarra/blob/master/jsf-ri/src/main/java/com/sun/faces/cdi/CdiProducer.java#L97
>>>
>>> Kind regards,
>>> Arjan Tijms
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> On Mon, Dec 14, 2015 at 11:43 AM, Werner Keil <werner.keil_at_gmail.com>
>>> wrote:
>>>
>>>> Hi,
>>>>
>>>> Thanks for the update. I will try it in WildFly at some point, but
>>>> especially the current client and environment (where especially some ideas
>>>> in the JSR like "roles allowed" found here
>>>> https://github.com/javaee-security-spec/javaee-security-examples would
>>>> be of interest in theory) are not even able to use WildFly or Java EE 7 and
>>>> probably won't be for another decade, so it is not so urgent before
>>>> codemotion.
>>>>
>>>> Kind Regards,
>>>>
>>>> Werner Keil
>>>>
>>>> On Mon, Dec 14, 2015 at 11:21 AM, arjan tijms <arjan.tijms_at_gmail.com>
>>>> wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> On Mon, Dec 14, 2015 at 12:25 AM, Werner Keil <werner.keil_at_gmail.com>
>>>>> wrote:
>>>>>
>>>>>> It works well in Glassfish 4, Wildfly 10 did not,
>>>>>
>>>>> [...]
>>>>>
>>>>> Yes, I did not modify it
>>>>>>
>>>>>
>>>>> Again a life "proof" of how important it is that WildFly does not
>>>>> require the modification ;)
>>>>>
>>>>> You're not the first one to fall into this. Quite a few people think
>>>>> it doesn't work on JBoss, since this modification is so non-obvious.
>>>>>
>>>>> Or the modification is done once, and then later a new install of
>>>>> JBoss (WildFly) is done and the modification is forgotten again (this
>>>>> happens all the time over at the Java EE 7 samples project for the CI).
>>>>>
>>>>> Kind regards,
>>>>> Arjan Tijms
>>>>>
>>>>>
>>>>>
>>>>
>>>
>