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

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

From: Werner Keil <werner.keil_at_gmail.com>
Date: Mon, 7 Dec 2015 17:44:03 +0100

Well the Renewal Ballot passed about 2 weeks ago:
https://jcp.org/en/jsr/results?id=5832
Not sure, if Twitter was eligable or not to vote (they also recently got a
new EC rep) but everyone else voted in favor.

https://jcp.org/en/procedures/jcp2#1.3 does not say anything other than
"another Renewal Ballot cannot be held within 1 year" but I would assume,
also based on that constraint, a JSR that passed a Renewal Ballot ideally
should not take more than the initially granted 9 months from that point to
produce an EDR 1. There can be multiple EDRs, so better create one as soon
as enough stable features are gathered than wait for another Renewal
Ballot, otherwise a JSR like this would at least be at great risk to miss
the Java EE 8 train (at least the Process JSRs some have the 3rd Renewal
Ballot now;-)

Regards,
Werner

On Mon, Dec 7, 2015 at 5:35 PM, arjan tijms <arjan.tijms_at_gmail.com> wrote:

> Hi,
>
> On Mon, Dec 7, 2015 at 5:31 PM, Werner Keil <werner.keil_at_gmail.com> wrote:
>
>> I guess whatever I present next week as a live demo, I'll highlight, that
>> it's still very much "in motion"
>>
>
> Sounds like a good idea.
>
>
>> but as soon (if I recall it right, there's up to another 6 maybe 9 months
>> to produce an EDR after the Renewal Ballot passed;-) as EDR 1 is out, those
>> structures should probably take a more stable shape, even if some packages
>> could well be added later.
>>
>
> Any word about the renewal ballot or EDR?
>
> Is there a template for the EDR spec document btw? I could perhaps try to
> write a draft EDR, so that we at least have something. Or is there a draft
> EDR document already?
>
> Kind regards,
> Arjan Tijms
>
>
>
>
>
>
>
>
>>
>> Kind Regards,
>> Werner
>>
>>
>>
>> On Mon, Dec 7, 2015 at 5:27 PM, arjan tijms <arjan.tijms_at_gmail.com>
>> wrote:
>>
>>> True, so that's likely the step after the mechanism.
>>>
>>> The package for whatever authorization things we do could be
>>> javax.security.authorization, but then -the- authorization API sits a
>>> package below that.
>>>
>>> JACC is an issue by itself too. There is some immense power lurking
>>> inside it, but just as with the JASPIC situation a few years back has many
>>> implementation and TCK issues.
>>>
>>> The biggest problem of JACC (IMHO) is that the only way to code against
>>> it is by installing a jar in a very obscure server specific way. There are
>>> two environment parameters specified for this where you put 2 classes that
>>> are somehow on the classpath of the server. But, in modern servers there's
>>> hardly a notion of -the- classpath.
>>>
>>> In practice, it's nearly impossible to use JACC with some servers. I
>>> asked e.g. JBoss what the proprietary method is to install a JACC provider
>>> on their server, and it doesn't seem anyone readily knows this.
>>>
>>> If an MR for JACC could only introduce a factory API like JASPIC has, to
>>> programmatically install a JACC provider from within a war, then this EG
>>> could put some higher level functionality on top of it.
>>>
>>> Kind regards,
>>> Arjan Tijms
>>>
>>>
>>>
>>>
>>>
>>>
>>> On Mon, Dec 7, 2015 at 5:16 PM, Werner Keil <werner.keil_at_gmail.com>
>>> wrote:
>>>
>>>> Yep, and at the moment most "authorization" elements are under the
>>>> somewhat cryptical
>>>> javax.security.jacc
>>>>
>>>> "Java Authorization Contract for Containers API"
>>>>
>>>> Werner
>>>>
>>>> On Mon, Dec 7, 2015 at 5:03 PM, arjan tijms <arjan.tijms_at_gmail.com>
>>>> wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> On Mon, Dec 7, 2015 at 4:42 PM, Werner Keil <werner.keil_at_gmail.com>
>>>>> wrote:
>>>>>
>>>>>> P.s.: I'm not sure, if the API would stick to a rather lengthy
>>>>>> package name like: javax.security.authenticationmechanism ?;-)
>>>>>>
>>>>>> Werner
>>>>>>
>>>>>
>>>>> I hear you, this package name and specifically the classes inside it,
>>>>> have not been given much thought yet, but since they were needed to get the
>>>>> sample to work I had to put them somewhere.
>>>>>
>>>>> In general when we are going to discuss this, there are some issues.
>>>>>
>>>>> There is already an existing package javax.security.auth.message,
>>>>> which is owned by JASPIC, so we won't touch it. But I was wondering about
>>>>> just javax.security.auth, which is the prefix package. I guess we could
>>>>> touch that (create new sub-packages of that), but this is a bit of an issue
>>>>> too since we more or less agreed here that just "auth" is not desirable. It
>>>>> can mean either "authentication" or "authorization".
>>>>>
>>>>> But if we create a package javax.security.authentication next to the
>>>>> existing javax.security.auth, where both mean "authentication", it kinda
>>>>> looks messy as well.
>>>>>
>>>>> Nevertheless, with a javax.security.authentication, we could put the
>>>>> mechanism classes in javax.security.authentication.mechanism (but in total
>>>>> this is actually 1 char longer). The alternative could be
>>>>> javax.security.auth.mechanism, but yeah, troublesome...
>>>>>
>>>>> Kind regards,
>>>>> Arjan Tijms
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>
>>>>>> On Mon, Dec 7, 2015 at 10:45 AM, Werner Keil <werner.keil_at_gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>>> Thanks, I hope to have a closer look at it during the week or
>>>>>>> weekend. Would be nice to show something like it in Tel Aviv in 10 days ;-)
>>>>>>>
>>>>>>> Kind Regards,
>>>>>>>
>>>>>>> Werner Keil | JCP Executive Committee Member, JSR 363 Co Spec Lead
>>>>>>> | Eclipse UOMo Lead, Babel Language Champion | Apache Committer
>>>>>>>
>>>>>>> Twitter @wernerkeil | @UnitAPI | @JSR354 | @AgoravaProj | @DeviceMap
>>>>>>> | #DevOps | #EclipseUOMo
>>>>>>> Skype werner.keil | Google+ gplus.to/wernerkeil
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Werner Keil
>>>>>>> [image: https://]about.me/wernerkeil
>>>>>>> <https://about.me/wernerkeil?promo=email_sig>
>>>>>>>
>>>>>>>
>>>>>>> On Mon, Dec 7, 2015 at 10:37 AM, arjan tijms <arjan.tijms_at_gmail.com>
>>>>>>> wrote:
>>>>>>>
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> I have extended the example a little. To keep the original example
>>>>>>>> as-is and as small/simple as possible, I did the extended work in a new
>>>>>>>> repo here: https://github.com/arjantijms/mechanism-to-store-x
>>>>>>>>
>>>>>>>> This adds:
>>>>>>>>
>>>>>>>> * Working implementation and example of
>>>>>>>> @DataBaseIdentityStoreDefinition
>>>>>>>> * Example of custom (app provided) identity store.
>>>>>>>>
>>>>>>>> See:
>>>>>>>>
>>>>>>>> *
>>>>>>>> https://github.com/arjantijms/mechanism-to-store-x/blob/master/app-db/src/main/java/test/Servlet.java
>>>>>>>> *
>>>>>>>> https://github.com/arjantijms/mechanism-to-store-x/blob/master/app-custom/src/main/java/test/TestIdentityStore.java
>>>>>>>>
>>>>>>>> I also fixed the "mechanism-to-store-app-1.0-SNAPSHOT" name. The
>>>>>>>> example now uses simple names for the war and therefor the URL:
>>>>>>>> localhost:8080/app-db, localhost:8080/app-mem, localhost:8080/app-custom.
>>>>>>>>
>>>>>>>> The examples were tested on GlassFish (4.1.1) and JBoss (WildFly
>>>>>>>> 10rc4). Note that JBoss needs the proprietary JASPIC activation before this
>>>>>>>> works (still hoping Darran can do something here to lift this).
>>>>>>>>
>>>>>>>> In order to work around a GlassFish bug (see
>>>>>>>> https://java.net/jira/browse/GLASSFISH-21447) I had to put the
>>>>>>>> data source in java:global. Due to another GlassFish bug where GF doesn't
>>>>>>>> unbind the data source when the application is undeployed you actually have
>>>>>>>> to stop and start GlassFish before the deploying the app again.
>>>>>>>>
>>>>>>>> Kind regards,
>>>>>>>> Arjan Tijms
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Sun, Oct 25, 2015 at 5:55 AM, Alex Kosowski <
>>>>>>>> alex.kosowski_at_oracle.com> wrote:
>>>>>>>>
>>>>>>>>> Hi Arjan,
>>>>>>>>>
>>>>>>>>> That example app is terrific! I would like to demonstrate it
>>>>>>>>> during the JavaOne JSR 375 BOF. The app does not look like much, but when
>>>>>>>>> you realize the caller was authenticated using data from an annotation, you
>>>>>>>>> realize how these simple standardizations will make a BIG impact.
>>>>>>>>>
>>>>>>>>> The only issue I ran into when deploying on GlassFish 4.1 was the
>>>>>>>>> default app name was " mechanism-to-store-app-1.0-SNAPSHOT", which made the
>>>>>>>>> context root " /mechanism-to-store-app-1.0-SNAPSHOT". But I changed the
>>>>>>>>> context root to "/mechanism-to-store-app" in the GF admin console and the
>>>>>>>>> example works as you described.
>>>>>>>>>
>>>>>>>>> Thanks again!
>>>>>>>>> Alex
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 10/24/15 6:19 PM, Alex Kosowski wrote:
>>>>>>>>>
>>>>>>>>> Thanks Arjan,
>>>>>>>>>
>>>>>>>>> Perhaps you would provide an example of using the
>>>>>>>>> @CredentialCapable(UsernamePasswordCredential.class) qualifier? Also,
>>>>>>>>> perhaps you would have an example of extending a standard identity store
>>>>>>>>> with a custom defined one to support a custom defined credential?
>>>>>>>>>
>>>>>>>>> Just some suggestions.
>>>>>>>>>
>>>>>>>>> With regards,
>>>>>>>>> Alex
>>>>>>>>>
>>>>>>>>> On 10/19/15 2:53 PM, arjan tijms wrote:
>>>>>>>>>
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> On Mon, Oct 19, 2015 at 7:46 PM, Alex Kosowski <
>>>>>>>>> alex.kosowski_at_oracle.com> wrote:
>>>>>>>>>
>>>>>>>>>> Thanks Arjan! I cannot wait to try it!
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Looking forward to hearing feedback, thanks.
>>>>>>>>>
>>>>>>>>> I'll try later this week to create another project that implements
>>>>>>>>> some more identity stores and also has an example for a user defined one.
>>>>>>>>>
>>>>>>>>> Kind regards,
>>>>>>>>> Arjan Tijms
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On 10/19/15 1:27 PM, arjan tijms wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi,
>>>>>>>>>>>
>>>>>>>>>>> I've created a working zero config demo application that shows
>>>>>>>>>>> how an authentication mechanism can use an identity store.
>>>>>>>>>>>
>>>>>>>>>>> It's located here:
>>>>>>>>>>> https://github.com/arjantijms/mechanism-to-store
>>>>>>>>>>>
>>>>>>>>>>> It uses a selection of the types Alex proposed, with the
>>>>>>>>>>> adjustments as discussed. This demo app uses one of the two ways to set an
>>>>>>>>>>> Identity Store; "declaratively for a standard provided store" as proposed
>>>>>>>>>>> by Reza in issue
>>>>>>>>>>> https://java.net/jira/browse/JAVAEE_SECURITY_SPEC-9 (the other
>>>>>>>>>>> option which is not demoed here is a store fully defined by the
>>>>>>>>>>> application).
>>>>>>>>>>>
>>>>>>>>>>> The store is declared using an annotation corresponding to
>>>>>>>>>>> option 3 in the list presented earlier. I put this annotation on a test
>>>>>>>>>>> Servlet (but it can be put anywhere):
>>>>>>>>>>>
>>>>>>>>>>> @EmbeddedIdentityStoreDefinition({
>>>>>>>>>>> @Credentials(callerName = "reza", password = "secret1",
>>>>>>>>>>> groups = { "foo", "bar" }),
>>>>>>>>>>> @Credentials(callerName = "alex", password = "secret2",
>>>>>>>>>>> groups = { "foo", "kaz" }),
>>>>>>>>>>> @Credentials(callerName = "arjan", password = "secret3",
>>>>>>>>>>> groups = { "foo" }) })
>>>>>>>>>>> @DeclareRoles({ "foo", "bar", "kaz" })
>>>>>>>>>>> @WebServlet("/servlet")
>>>>>>>>>>> public class Servlet extends HttpServlet
>>>>>>>>>>>
>>>>>>>>>>> See:
>>>>>>>>>>> https://github.com/arjantijms/mechanism-to-store/blob/master/app/src/main/java/test/Servlet.java
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> This annotation is picked up by a CDI extension and a Bean<T> is
>>>>>>>>>>> created for it:
>>>>>>>>>>>
>>>>>>>>>>> public <T> void processBean(@Observes ProcessBean<T>
>>>>>>>>>>> eventIn, BeanManager beanManager) {
>>>>>>>>>>>
>>>>>>>>>>> ProcessBean<T> event = eventIn; // JDK8 u60 workaround
>>>>>>>>>>>
>>>>>>>>>>> Optional<EmbeddedIdentityStoreDefinition> result =
>>>>>>>>>>> getAnnotation(beanManager, event.getAnnotated(),
>>>>>>>>>>> EmbeddedIdentityStoreDefinition.class);
>>>>>>>>>>> if (result.isPresent()) {
>>>>>>>>>>> identityStoreBean = new CdiProducer<IdentityStore>()
>>>>>>>>>>> .scope(ApplicationScoped.class)
>>>>>>>>>>> .types(IdentityStore.class)
>>>>>>>>>>> .create(e -> new
>>>>>>>>>>> EmbeddedIdentityStore(result.get().value()));
>>>>>>>>>>>
>>>>>>>>>>> }
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> This Bean<T> is subsequently registered with the container:
>>>>>>>>>>>
>>>>>>>>>>> public void afterBean(final @Observes AfterBeanDiscovery
>>>>>>>>>>> afterBeanDiscovery) {
>>>>>>>>>>> if (identityStoreBean != null) {
>>>>>>>>>>> afterBeanDiscovery.addBean(identityStoreBean);
>>>>>>>>>>> }
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> See:
>>>>>>>>>>> https://github.com/arjantijms/mechanism-to-store/blob/master/jsr375/src/main/java/org/glassfish/jsr375/cdi/CdiExtension.java
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> The Identity Store implementation is vendor specific. It's not
>>>>>>>>>>> in the javax.security API package. This way vendors can optimise the
>>>>>>>>>>> implementation and/or map it to their existing artefacts.
>>>>>>>>>>>
>>>>>>>>>>> The sample implementation maps the data in the annotation to a
>>>>>>>>>>> Map:
>>>>>>>>>>>
>>>>>>>>>>> private Map<String, Credentials> callerToCredentials;
>>>>>>>>>>>
>>>>>>>>>>> public EmbeddedIdentityStore(Credentials[] credentials) {
>>>>>>>>>>> callerToCredentials = stream(credentials).collect(toMap(
>>>>>>>>>>> e -> e.callerName(),
>>>>>>>>>>> e -> e)
>>>>>>>>>>> );
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> And in the validate() method it simply checks if the credentials
>>>>>>>>>>> for the requested caller name are present:
>>>>>>>>>>>
>>>>>>>>>>> public CredentialValidationResult
>>>>>>>>>>> validate(UsernamePasswordCredential usernamePasswordCredential) {
>>>>>>>>>>> Credentials credentials =
>>>>>>>>>>> callerToCredentials.get(usernamePasswordCredential.getCaller());
>>>>>>>>>>>
>>>>>>>>>>> if (credentials != null &&
>>>>>>>>>>> usernamePasswordCredential.getPassword().compareTo(credentials.password()))
>>>>>>>>>>> {
>>>>>>>>>>> return new CredentialValidationResult(
>>>>>>>>>>> VALID,
>>>>>>>>>>> credentials.callerName(),
>>>>>>>>>>> asList(credentials.groups())
>>>>>>>>>>> );
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> return INVALID_RESULT;
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> See:
>>>>>>>>>>> https://github.com/arjantijms/mechanism-to-store/blob/master/jsr375/src/main/java/org/glassfish/jsr375/identitystores/EmbeddedIdentityStore.java
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> The application uses a very basic SAM. This one uses the plain
>>>>>>>>>>> non-simplified JASPIC API. The SAM obtains the identity store via CDI and
>>>>>>>>>>> then utilises it to perform the "credential to identity data" function:
>>>>>>>>>>>
>>>>>>>>>>> String name = request.getParameter("name");
>>>>>>>>>>> Password password = new
>>>>>>>>>>> Password(request.getParameter("password"));
>>>>>>>>>>>
>>>>>>>>>>> // Obtain a reference to the Identity Store
>>>>>>>>>>> IdentityStore identityStore =
>>>>>>>>>>> CDI.current().select(IdentityStore.class).get();
>>>>>>>>>>>
>>>>>>>>>>> // Delegate the {credentials in -> identity data out}
>>>>>>>>>>> function to
>>>>>>>>>>> // the Identity Store
>>>>>>>>>>> CredentialValidationResult result =
>>>>>>>>>>> identityStore.validate(new UsernamePasswordCredential(name, password));
>>>>>>>>>>>
>>>>>>>>>>> if (result.getStatus() == VALID) {
>>>>>>>>>>> callbacks = new Callback[] {
>>>>>>>>>>> // The name of the authenticated caller
>>>>>>>>>>> new CallerPrincipalCallback(clientSubject,
>>>>>>>>>>> result.getCallerName()),
>>>>>>>>>>> // the groups of the authenticated caller (for test
>>>>>>>>>>> // assume non-null, non-empty)
>>>>>>>>>>> new GroupPrincipalCallback(clientSubject,
>>>>>>>>>>> result.getCallerGroups().toArray(new String[0])) };
>>>>>>>>>>> } else {
>>>>>>>>>>> throw new AuthException("Login failed");
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> See:
>>>>>>>>>>> https://github.com/arjantijms/mechanism-to-store/blob/master/app/src/main/java/test/TestServerAuthModule.java
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Finally the demo app uses a simple (non-protected) Servlet (the
>>>>>>>>>>> one shown above) that prints out the details of the authenticated user. If
>>>>>>>>>>> the application is deployed to a stock GlassFish without any configuration
>>>>>>>>>>> whatsoever being done it can be requested via:
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> http://localhost:8080/mechanism-to-store-app/servlet?name=reza&password=secret1
>>>>>>>>>>> <
>>>>>>>>>>> http://localhost:8080/mechanism-to-store-app/servlet?name=reza&password=secret1
>>>>>>>>>>> >
>>>>>>>>>>>
>>>>>>>>>>> If all went well this prints out the following:
>>>>>>>>>>>
>>>>>>>>>>> This is a servlet
>>>>>>>>>>> web username: reza
>>>>>>>>>>> web user has role "foo": true
>>>>>>>>>>> web user has role "bar": true
>>>>>>>>>>> web user has role "kaz": false
>>>>>>>>>>>
>>>>>>>>>>> Needless to say here that this is just for demo'ing one of the
>>>>>>>>>>> smallest possible SAMs that interact with the caller. Putting the password
>>>>>>>>>>> in the URL is of course not suited for any real live usage.
>>>>>>>>>>>
>>>>>>>>>>> Note that this particular demo only demonstrates a few of the
>>>>>>>>>>> discussed options. I also made a few practical choices here and there to be
>>>>>>>>>>> able to implement the application which can of course be discussed further.
>>>>>>>>>>>
>>>>>>>>>>> Thoughts?
>>>>>>>>>>>
>>>>>>>>>>> Kind regards,
>>>>>>>>>>> Arjan Tijms
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>