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:31:28 +0100

I guess whatever I present next week as a live demo, I'll highlight, that
it's still very much "in motion", 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.

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
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>