users@javaee-security-spec.java.net

[javaee-security-spec users] [jsr375-experts] Re: Working example app demonstrating identity store usage

From: arjan tijms <arjan.tijms_at_gmail.com>
Date: Mon, 7 Dec 2015 17:35:02 +0100

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