Git Product home page Git Product logo

authentication's Introduction

Jakarta Authentication

This repository contains the code for Jakarta Authentication.

Online JavaDoc

Building

Jakarta Authentication can be built by executing the following from the project root:

mvn clean package

The API jar can then be found in /api/target.

Making Changes

To make changes, fork this repository, make your changes, and submit a pull request.

About Jakarta Authentication

Jakarta Authentication defines a general low-level SPI for authentication mechanisms, which are controllers that interact with a caller and a container's environment to obtain the caller's credentials, validate these, and pass an authenticated identity (such as name and groups) to the container.

Jakarta Authentication consists of several profiles, with each profile telling how a specific container (such as Jakarta Servlet) can integrate with- and adapt to this SPI.

authentication's People

Contributors

alwin-joseph avatar arjantijms avatar authentication-bot avatar bshannon avatar cousjava avatar darranl avatar dblevins avatar dependabot[bot] avatar ggam avatar jeanouii avatar jgauravgupta avatar pzygielo avatar starksm64 avatar teobais avatar yaminikb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

authentication's Issues

Deliver Jakarta Authentication Specification Version update for Jakarta EE 9

Is your feature request related to a problem? Please describe.
Jakarta EE 9 is the next major release, with the main focus of moving from the javax namespace to the jakarta namespace.

Describe the solution you'd like
This issue will be used to track the progress of this work effort via the Jakarta EE 9 Project board.

Additional context
Jakarta EE Specification Process
Eclipse Project Handbook
Eclipse Release Record for Jakarta EE 9

ToDo

  • Create Eclipse Release Record in your respective Jakarta Specification Project.
    Most Component Release Records will just reference the Jakarta EE 9 Platform Release Plan. But, if your Component deviates at all from the Platform Release Plan, then a description of the changes will be required in the Release Record.
  • Initiate a ballot for your Jakarta Release Record/Plan.
    Again, if your component is only doing the required minimum as defined by the Jakarta EE 9 Platform Release Plan, then no separate ballot is required. You are already approved. But, if your component deviates from the Platform Release Plan, then you will need to initiate your own ballot as defined by the Jakarta EE Specification Process.
  • Jakarta-ize your Specification document (if applicable)
    Many of the Jakarta EE components now have the source for their Specification documents. It is strongly recommended that these Specification documents are properly updated to represent Jakarta EE instead of Java EE. Some helpful instructions are documented here.
  • javax -> jakarta Spec updates
    If your component has Specification source, then all javax package references need to be updated to use jakarta package references.
  • javax -> jakarta API updates
    Your component APIs need to move from using the javax namespace to using the jakarta namespace.
  • Release Candidate (RC) of Jakarta API in Maven Central
    A Release Candidate of your component API should be pushed to Maven Central as soon as humanly possible. This will allow other dependent components to utilize your APIs as they are updating their APIs. Multiple revisions of these Release Candidate APIs are allowed (and probably expected) during the development cycle.
  • javax -> jakarta TCK updates
    Your component TCK needs to be updated to use the jakarta namespace.
  • javax -> jakarta Compatible Implementation updates
    Your compatible implementation that will be used to demonstrate completeness of the Specification needs to be updated to use the jakarta namespace.
  • Final Jakarta API available in Staging Repo
    When ready, your final version of the API needs to be staged to get ready for the PR review and approvals.
  • Draft Specification and Apidoc PRs ready for review
    Like we did for Jakarta EE 8, draft PRs need to be created and reviewed in preparation for the final ballots.
  • Release Review Ballot started
    Each Jakarta EE component will need to initiate a separate Release Review ballot after proper reviewing has completed. To be clear, there will not be a blanket Release Review for all of Jakarta EE 9 like we did for the Plan Review. Each component needs a separate Release Review.

Clarify and/or add TCK test for request/response wrapping

According to section Section 3.8.3.4 of the JSR 196 specification, an auth module can wrap a request and response during validateRequest processing. Such a wrapped request and response should then be available "downstream":

When a ServerAuthModule returns a wrapped message in MessageInfo, or unwraps a message in MessageInfo, the message processing runtime must ensure that the HttpServletRequest and HttpServletResponse objects established by the ServerAuthModule are used in downstream processing.

It is perhaps not entirely clear what "downstream" means.

A user might expect that such a wrapped request and response means that all filters and the Servlet that gets invoked for that request get to see these types (e.g. like a Servlet Filter does when it provides wrapped types to the FilterChain.doFilter method). However, this happens in none of the well known and certified JASPIC implementations (GlassFish, JBoss EAP, Geronimi, WebLogic and WebSphere).

For instance consider the following wrapper class:

public class MyTestWrapper extends HttpServletRequestWrapper {
    public MyTestWrapper(HttpServletRequest request) {
        super(request);
    }
}

and the following fragment in a ServerAuthModule.validateRequest implementation:

HttpServletRequest request = (HttpServletRequest) messageInfo.getRequestMessage();

messageInfo.setRequestMessage(new MyTestWrapper(request));

return SUCCESS;

Then the following assert in an HttpServlet that is invoked during the same request in which the auth module wrapped the HttpServletRequest instance fails for every of the above mentioned JASPIC implementations:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {   	
    assert(request instanceof MyTestWrapper);
}

Looking at the source code of various implementations, it looks like GlassFish could indeed provide the wrapped response downstream. In RealmAdapter the following code fragment appears right after the auth module is invoked:

HttpServletRequest newRequest = (HttpServletRequest) messageInfo.getRequestMessage();
if (newRequest != req) {
    request.setNote(Globals.WRAPPED_REQUEST, new HttpRequestWrapper(request, newRequest));
}

Then in StandardPipeline the following code could pass the wrapped request downstream, if chaining were to be true:

Request req = request;
Response resp = response;
if (chaining) {
    req = getRequest(request);
    resp = getResponse(request, response);
}
basic.invoke(req, resp);

The method getRequest would indeed get the wrapped request when it exists:

private Request getRequest(Request request) {
    Request r = (Request) request.getNote(Globals.WRAPPED_REQUEST);
    if (r == null) {
        r = request;
    }
    return r;
}

In practice though, the chaining boolean in the StandardPipeline fragment is always false, causing the original objects to be passed along instead of the wrapped ones. Moreover, similar analysis in the source code of e.g. JBoss EAP reveals that there is no code present whatsoever that could pass the wrapped request downstream.

Since wrapping is an important use case (it's a common technique used to "restore" the original request after a form based authentication), I would like to request:

  • A clarification about what "downstream available" means, perhaps by providing a code sample such as shown above.
  • A TCK test that tests whether a request and response wrapped by an auth module are indeed available in a simple servlet in a way as shown above.

Public Release

Last CTS runs indicate no failures in this component. It's time to make a public release. Before the release make sure that Eclipse Release Review is passed and all dependencies have been released.

Support for events

For several use cases it would be quite convenient if JASPIC would throw events at several important moments of the authentication message exchange.

Such events could be:

  • PreAuthenticate
  • PostAuthenticate
  • PreLogout
  • PostLogout

User code could possibly register for such events in the same way such code can register for events from the Servlet container; annotating the listener class and implementing an interface.

E.g.

@SecurityListener
public class MyListener implements AuthenticationListener  {

    public void preAuthenticate(AuthEvent authEvent) {
        // ...
    }

    public void postAuthenticate(AuthEvent authEvent) {
        // ...
    }
}

Additionally CDI style events can be supported as well.

Use cases for such event listeners are among others:

  • Keeping track of the number of logged-in users
  • Protecting against brute-force attacks by keeping count of failed login attempts for a certain account
  • Creating a new local user after the first successful authentication via a remote authentication provider
  • Loading application specific preferences into the HTTP session after a user logs-in

Specifically for the second use case a PreAutenticate listener should be able to veto the authentication attempt (at which JASPIC could respond by e.g. sending a 403 to the client).

Specification of validateRequest "doing nothing"

JASPIC specifies that for among others the Servlet Profile an auth module (and its context) should be called before every request.

In several situations an auth module's validateRequest method may choose to "do nothing". For instance, the requested resource may not be a protected one and the trigger to do a pre-emptive authentication is not present in the request.

The JASPIC spec is not entirely clear how this situation should be handled. 3.8.3.1 comes close and mentions the following:

Independent of whether the authentication policy is satisfied, the module may return AuthStatus.SUCCESS.

If the module returns AuthStatus.SUCCESS (and the authentication policy was satisfied), the module (or its context) must employ a CallerPrincipalCallback as described above.

If the authentication policy was not satisfied, and yet the module chooses to return AuthStatus.SUCCESS, the module (or its context) must use a CallerPrincipalCallback to establish the container's representation of the unauthenticated caller within the clientSubject.

This text mentions the authentication policy, but does not seem to take the situation into account where authentication is not mandatory for the request (i.e. as explained in 3.8.1.1 and represented by the MessageInfo map key javax.security.auth.message.MessagePolicy.isMandatory).

Studying several available authentication modules it looks like the prevailing opinion is to just return AuthStatus.SUCCESS without employing the CallerPrincipalCallback. E.g. as done by the OpenID4Java SAM:

if (isMandatory) {      
    respondWithLoginForm(request, response);
} else {
    // the request is not protected so simple succeed the
    // request...
    return AuthStatus.SUCCESS;
}

This indeed works on many JASPIC implementations, but not on all (it doesn't work on JBoss AS/EAP).

The possible option of using "CallerPrincipalCallback to establish the container's representation of the unauthenticated caller within the clientSubject." is practically not possible, since there doesn't seem to be any portable way for a SAM to do this. A representation of the unauthenticated caller can not be obtained in a standard way (GlassFish e.g. uses the proprietary SecurityContext.getDefaultCallerPrincipal(). It's also not clear how a CallerPrincipalCallback can be used to communicate that special identity back to the runtime.

I would like to request to specify what should happen if a SAM does not want to do any authentication, but does want the requested resource to be invoked.

A simple solution could be to just specify that validateRequest can always return AuthStatus.SUCCESS without employing the CallerPrincipalCallback in any way, and that it depends on the authorization requirements if the resource is indeed invoked.

Additional it might be worthwhile to introduce a new AuthStatus, perhaps called CONTINUE that explicitly means that the SAM (or its context) did not employ the CallerPrincipalCallback or any other callback and just wishes that the request continues. This additional status may also be convenient for #15.

Change Maven coordinates

All current API libraries shipped must be distributed to Maven Central under a sub-package of the jakarta groupId. Before the first release Maven coordinates of this project must be changed as it's described here.

servlet profile does not profile the use of the spi under HttpServletRequest#authenticate

when jsr 196 is configured for a Servlet application, the jsr 196 configuration
must be applied when HttpServletRequest#authenticate is called.

In that case, a call to HttpServletRequest#login must throw an exception since
the configured authentication mechanism may not be password based.

the servlet profile must also define what happens when
HttpServletRequest#logout is called

Update Eclipse GlassFish

Update Eclipse GlassFish to use the new version of your API (and implementation, if applicable) by submitting a PR to GlassFish.

Although a new version of GlassFish will not be released for Jakarta EE 8, we hope to release an update sometime later.

Harmonize groupId and artifactId

While the groupId of Jakarta Security is jakarta.security.enterprise matching the top level package, this one is "jakarta.security.auth.message". And the artifactId "jakarta.security.auth.message-api".
While "message" is currently the only package, with the module itself called "authentication", wouldn't it be more consistent and less confusing to just call them "jakarta.security.authentication" and "jakarta.security.authentication-api"?

Servlet profile specific types to increase ease of use

JASPIC as it's currently defined has an exceptionally flexible and abstract API. It can handle authentication for different kinds of environments, which are defined in profiles. Profiles demand certain behavior and specific keys to be present in otherwise generic maps that are used throughout the API.

While this indeed makes the API flexible, it comes at the cost of a reduced ease-of-use. Developers wishing to program for e.g. the Servlet Profile have to read through documentation to see in what way they need to fulfill the contract of the profile and which keys can be inserted or retrieved from the mentioned maps. A certain amount of casting from type Object is also required to work with the profile.

This required effort can likely be significantly reduced by the introduction of specific Java types for a profile. The Servlet spec uses something similar to this. There is a GenericServlet which is protocol independent and an HtppServlet that's provided as a convenience for HTTP usage (which is overwhelmingly the common usage).

In practice those specific types are already created by JASPIC users, e.g. JBoss uses WebServerAuthModule as a Servlet Profile specific base class for a ServerAuthModule, and in OmniSecurity we're prototyping a base class as well with HttpServerAuthModule.

A standardized convenience ServerAuthModule base class for the Servlet Profile could have the following properties:

  • Default implementation of getSupportedMessageTypes returning the two mandated classes.
  • Default initialize that just stores the incoming parameters for later retrieval
  • Default secureResponse just returning a success status
  • Default cleanSubject that just removes the Principals from the given Subject
  • A new validateRequest method that has HttpServletRequest and HttpServletResponse as parameters and perhaps a context object of some kind (e.g. called HttpMsgContext or something similar (just like ServletContext, FacesContext, etc).

The context object mentioned above can contain a number of convenience methods for working with the Servlet Profile, e.g.

  • an isProtected method corresponding to the javax.security.auth.message.MessagePolicy.isMandatory key.
  • a registerWithContainer(String, List) method as a convenience shortcut for working directly with the CallerPrincipalCallback and GroupPrincipalCallback
  • a setRegisterSession and isRegisterSession corresponding to the javax.servlet.http.registerSession key.
  • getters for the (raw) MessageInfo, Subject parameters of the super validateRequest method and the CallbackHandler that was passed into the initialize method.

The above mentioned types, names, and semantics are just examples to kickoff a discussion about this matter. Note that the proposed convenience types and methods are just conveniences and should never be the only way to work with the API.

AppContextID of Servlet profile includes name of virtual host; for which Servlet provides no portable api

During programmatic AuthConfigProvider registration - especially
self-registration via

AuthConfigFactory.registerConfigProvider(AuthConfigProvider provider,
String layer,
String appContextID,
String description);

the AuthConfigProvider has no portable way to determine the name of the virtual
host, and thus to register using the same virtual host name that will be used
by the runtime in its call to

AuthConfigFactory.getConfigProvider(String layer, String appContextID,
RegistrationListener listener);

Servlet 3.1 does not intend to provide a portable api by which the name of the
virtual host can be obtained.

this problem was first reported by Arjan Tijms

Update JASPIC to take advantage of new Java language features

As one of the very last specs in Java EE, JASPIC still uses the Java 1.4 syntax. In the API are a couple of raw Maps that could really benefit from at least the Java 5 syntax (generics in this case).

I would like to request to update JASPIC to take advantage of newer Java language features.

Leverage SAML Web SSO from Nobis in JASPIC TCK

The Nobis project is the RI for JSR-351. It also contains the SAML Web SSO implementation that will be leveraged within the JASPIC TCK in order to do two things:

  1. Ensure that an actual and useful SAM can be configured for use within an application server implementation using standard mechanisms. To date the TCK has only tested spec compliance with a special set of implementation classes that ensure that the correct APIs are being called at the correct times

  2. Ensure that Java EE 6+ environments are capable of participating in three party authentication exchanges and enterprise SSO products
    the current implementation encompasses the resource first usecase wherein the resource is requested first and the user is redirected to the configured IDP for authentication

The TCK will need to acquire the appropriate implementation from Nobis, make it available in the system classpath for the appserver being tested
and configure it for use within the system and for a particular application.

Status code for processing handler but not invoking resource

In the Servlet Container Profile of JASPIC the ServerAuthModule.validateRequest method can return the SUCCESS} status code, which means the given handler should be processed by the JASPIC runtime and the requested resource should be invoked. This same method can also return {{SEND_CONTINUE which means the handler should not be processed and the resource should not be invoked.

Neither of those status codes address the use case where a SAM wishes authentication to happen first (and ask the container to remember this) and then immediately redirect to a new resource.

This happens for instance when the user tries to access protected resource /A after which the SAM redirects the user to an external authentication provider at http://example.com which then redirects the user back to a general resource at /return which the SAM is monitoring. The SAM could redirect to /A first and then do authentication, but this slightly complicates the logic that needs to be coded.

Fragment of code from an actual SAM demonstrating a similar case:

if (...) {
    // [...]

    if (authenticated) {

        String savedURL = getSavedURL(request);
        // [...]

        // Note: JASPIC doesn't really support authenticating AND redirecting during the same request, 
        // so we need to redirect first and then finally do the authentication with the container on 
        // the request we redirected to.
        redirect(response, savedURL);
        return SEND_CONTINUE;
    } else {
        // [...]
    }

} else if (isOnOriginalURLAfterAuthenticate(request)) {

    Authenticator authenticator = getSavedAuthenticator(request);

Source

For completeness and to make some flows easier to code, I'd like to suggest the introduction of a new status code, something like SUCCESS_SEND_CONTINUE, meaning:

  • Process the handler and any directives put into the MessageInfo map (such as asking the container to remember the auth session)
  • Don't invoke the resource

Add some documentation of JASPIC in Oracle's Java EE 7 tutorial

Although JASPIC has been part of Java EE since Java EE 6, it's still a relatively unknown technology. One of the reasons might be that not a lot of tutorials or books mention it.

As Oracle is the spec lead for JASPIC I wonder if it's possible to include some documentation of JASPIC in Oracle's upcoming Java EE 7 tutorial. In the Java EE 6 tutorial, the section Specifying Authentication Mechanisms would probably have been a good location.

Compatibility certification request for EE4J implementation of Jakarta Authentication 2.0

  • Organization Name ("Organization") and, if applicable, URL
    Eclipse Foundation
  • Product Name, Version and download URL (if applicable)
    Eclipse Glassfish 6.0.0-M3-2020-10-04
  • Specification Name, Version and download URL
    Jakarta Authentication 2.0
  • TCK Version, digital SHA-256 fingerprint and download URL
    Promoted: Jakarta Authentication TCK 2.0.0
    Final: Jakarta Authentication TCK 2.0.0, SHA-256: 4fff0e3984cec6937db1e5b2e1894534f695fe72ad3aeb076a8423fa5845ad07
  • Public URL of TCK Results Summary
    TCK results summary
  • Any Additional Specification Certification Requirements
    None
  • Java runtime used to run the implementation
    Oracle JDK 1.8.0_202
  • Summary of the information for the certification environment, operating system, cloud, ...
    Linux
  • By checking this box I acknowledge that the Organization I represent accepts the terms of the EFTL.
  • By checking this box I attest that all TCK requirements have been met, including any compatibility rules.

Support CDI and other container services in SAM

In JASPIC 1.0 it has not been specified whether under the Servlet profile container services like CDI should be available at the time that a SAM is called at the start of a request.

In some implementations (e.g. JBoss EAP 6.0.1) those services are indeed fully available, while in other implementations (e.g. GlassFish 3.1.2.2) the services are partially available. In yet other implementations (e.g. WebLogic 12c 12.1.1) those services are not available at all.

For a number of use cases having this support is important, e.g.

  • Fetching users via EJB/JPA for a database based auth module
  • Generating and persisting tokens for "remember me" functionality
  • Creating a user locally after a first time authentication with an external provider (e.g. OpenId)

Ideally the support would be at the same level as that of a Servlet Filter, meaning the CDI request and session scopes are available, the "java:comp", "java:module", "java:app", etc JNDI namespaces have been set up, injection is possible, etc.

In order to support injection as well, the Factory API might need to have variants of its methods that take a Class type instead of an object instance, like e.g. addFilter(String, Filter) vs addFilter(String, Class). There might also need to be methods like createSam(Class) in analogy to createFilter and similar methods.

Modification of authenticated identity without re-authentication

A common use case in web applications is that users log-in with their email address, which then becomes the user/caller principal once authenticated.

A user should be allowed to change her email address, but this is not easily supported by JASPIC, since this also requires a re-authentication, which on its turn likely needs the original credentials used for authentication (which a secure application of course does not store, so can not use for this case).

This means that a user either needs to provide these credentials together with the action of changing the email, which is not entirely user friendly in the first place. Those provided credentials may possibly not even be useable for programmatic re-authentication if the SAM that's used only supports asking them directly from the user.

Another option is to immediately log the user out after changing the email, which again is not really user friendly.

Something similar holds for roles; a user may obtain new roles during a session (for example by making a payment, or obtaining a reward for some online action, etc). Requiring the user to log-out and log-in again for the new role to take effect is not always desirable.

See also: http://stackoverflow.com/questions/2487224/how-to-handle-dynamic-role-or-username-changes-in-jsf

In order to support such use cases I'd like to propose that the possibility to handle changes to the authenticated identity without the need for a manual logout and login (re-authenticate) be added to JASPIC.

One possibility could be for a variant on HttpServletRequest#authenticate that takes one or more Callbacks, and the definition of several new Callbacks, e.g.

  • AddGroupPrincipalCallback - Adds a new group/role to the authenticated identity
  • RemoveGroupPrincipalCallback - Removed an existing group/role from the authenticated identity
  • UpdateCallerPrincipalCallback - Updates the caller principal in the authenticated identity

Clarify and/or add TCK test for validateRequest/invoke service/secureResponse ordering

Section 3.8.2.2 of the JASPIC spec discusses the invocation of validateRequest after a service invocation for the Servlet Container Profile.

It does however not give any details under which circumstances the runtime should call this method after a service invocation, and neither does it give any details about how an implementation of this method should distinguish between being called before service invocation (in which its job is to do authentication) and after service invocation (in which its job is to secure a response). For the SOAP profile, footnote 6 in 4.9.5.3 does give an explanation.

Section 3.8.3.3 says that the semantics of secureResponse are as defined in Section 3.8.2.2, which thus means that secureResponse should be called after a service invocation. Figure 1.1 in Section 1.1 shows this as well, and the general flow as described is Section 3.8 also mentions this.

Unfortunately, not all JASPIC implementations indeed call secureResponse after a service invocation. GlassFish 3.1.2.2, Geronimo V3.0 and WebSphere 8.5 do make the call afterwards, but the certified implementations of JBoss EAP 6.0.1 (and AS 7.1.1) as well as WebLogic 12.1.1 call secureResponse before a service invocation. In fact, both those implementations call secureResponse nearly immediately after validateRequest is called. In case of WebLogic 12.1.1 this can be deduced from the call stack in debug mode, while in case of JBoss EAP 6.0.1 it can be seen directly in its source code.

E.g. consider the following abbreviated excerpt from JBoss EAP's WebJASPIAuthenticator:

GenericMessageInfo messageInfo = new GenericMessageInfo();
messageInfo.setRequestMessage(request);
messageInfo.setResponseMessage(request.getResponse());

// [...] 
ServerAuthenticationManager sam = getServerAuthenticationManager();

if (sam != null) {
    // Calls through to validateRequest on SAM
    result = sam.isValid(messageInfo, clientSubject, messageLayer, appContext, cbh);
}

if (result) {

    // [Jboss specific login] 
    if (this.secureResponse)
        // Calls through to secureResponse on SAM
        sam.secureResponse(messageInfo, new Subject(), messageLayer, appContext, cbh);
    }
 }

return result; // Service invocation will happen after this if result == true

In case of JBoss EAP, secureResponse is not only seemingly called at the wrong time, it's also an optional operation (default false) but the spec does not mention this operation to be optional.

I would like to request a TCK test to be added that tests that secureResponse is indeed called after a service invocation, and clarification of the following items:

  • 3.8.2.2 - Why or when would validateRequest be called after a service invocation
  • Perhaps in 3.8.3.3 an explicit statement that secureResponse is to be called after a service invocation and not before.

Update EFSL for Specifications and Javadoc

Per the discussions on the Spec Committee and Platform Dev mailing lists, it's been discovered that many of the Javadoc and Spec references to the EFSL need updating. Please reference the following required updates and keep them in mind as your Spec Project is updating the files for Jakarta EE 9.

Note: Some Spec Projects have already started or even completed these updates. If so, just kindly return/close this Issue. Thanks!

Required EFSL updates for Javadoc

For javadoc, the EFSL.html located in src/main/javadoc/doc-files should be modified as follows:

  • the <<url to this license>> needs to be replaced with efsl.php link[1]
  • the [title and URI of the Eclipse Foundation specification document] needs to be replaced with the Specification Name and URL (Reference [2] for an example.)
  • The javadoc footer copyright year needs to be updated to 2018, 2020 as defined in the pom.xml

Required EFSL updates for Specifications

For specification, the license-efsl.adoc located in src/main/asciidoc should be modified as follows:

  • Update copyright year to 2018, 2020 from 2019. Add link to EFSL.
  • the <<url to this license>> needs to be replaced with efsl.php link[1]
  • the [title and URI of the Eclipse Foundation specification document] needs to be replaced with the Specification Name and URL (Reference [2] for an example.)

[1] https://www.eclipse.org/legal/efsl.php
[2] https://jakarta.ee/specifications/enterprise-beans/4.0/

Support for HttpServletRequest#logout

Servlet 3.0 introduced the HttpServletRequest#logout method.

Invoking this method does not seem to cause any method on a configured auth module to be invoked. This makes it impossible for an auth module to fully manage the authentication session. A specific use case is the implementation of a "remember me" functionality. For this the auth module can e.g. insert a cookie into the response after a successful initial authentication. This cookie should then live beyond a session expiration, but has to be removed when a user explicitly log outs.

Without the auth module being notified of such an explicit logout invocation, there is no opportunity to remove said cookie.

Portable way to distinguish between invocation at start of request and invocation following authenticate() call

The validateRequest method of an auth module can be called at the "start" of an HTTP request (before the target resource or any servlet filters are invoked), or it can be called following a call to the Servlet 3.0 HttpServletRequest.authenticate() method.

In some cases it may be necessary for the auth module to distinguish between these cases. One use case is that following a call to HttpServletRequest.authenticate(), the auth module fully runs within the context of the calling code. E.g. if the calling code is a CDI bean backing a JSF view, then both the CDI contexts as well as the Faces context are available to the auth module. An auth module that is created specifically for CDI/JSF may take advantage of this.

It might thus be convenient to have a portable way for the auth module to find out at which of those two different points it's invoked.

Note that WebSphere 8.5 solves this issue by putting a key com.ibm.websphere.jaspi.request in the MessageInfo map, with authenticate as value (see http://pic.dhe.ibm.com/infocenter/wasinfo/v8r5/index.jsp?topic=%2Fcom.ibm.websphere.nd.doc%2Fae%2Ftsec_jaspi_create.html step 4).

Add missing generics to API

Generics are missing in the Authentication API.

Ignoring the javax to jakarta change this addition of these generics is a binary compatible one so it will not cause breakage for existing applications using this API.

We will need to update the signature files in the TCK to account for this change.

Planned behaviour of CallbackHandler is not clearly defined

I'm currently writing several JASPIC authentication modules for Tomcat and have encountered some uncertainties in the specs about the CallbackHandler and the planned behaviour of the required callbacks:

  • PasswordValidationCallback

    • It is not clear if the callback must only yield a result in it's getResult method or also set the current users principal in the client subject.
    • It is not clear if the groups must also be set for the identified user by the CallbackHandler.
    • The spec allows the password field to be empty but gives no instructions on the way to handle this case. Shall the user principal be established without checking the password or shall it only return true if the user is a password-less user?
  • CallerPrincipalCallback

    • Is it intended that the goups of the user are set, if the user has been found in the identity store?
  • GroupPrincipalCallback

    • How shall the callback be handled in case any of the aforementioned callbacks already set the groups.

These uncertainties have led to some interesting interpretation in the open source community as you can see here:
Elytron_and_Java_Authentication_SPI_for_Containers-JASPI
In this case an integrated and non-integrated mode have been invented to solve the ambiguities.

There clearly is no "best" way to handle this, so it probably should be parametrized.

Example usage:

  • Bearer Auth - identity of the user is established by the token, groups should be set from identity store: needs a CallerPrincipalCallback that "automatically" sets the groups (1st case)
  • Bearer Auth - identity and groups should be established from the token (2nd case): no groups set by CallerPrincipalCallback as the auth module would want to use GroupPrincipalCallback for that
  • Basic Auth - needs a PasswordValidationCallback that sets identity and groups automatically or use a CallerPrincipalCallback that sets the groups after checking the getResult return value of the PasswordValidationCallback

Many more cases come to mind if you add client cert auth.

correct AuthConfigFactory.getConfigProvider inconistency in whether layer and appContextID may be null

the version of the javadoc embedded in the 1.0 spec is out of sync with the javadoc
generated from the api src. The javadoc in the spi src is correct and allows these
parameters to be null in the general case. Note that profiles (e.g. the Servlet profile)
establish specific values (and may not allow null values) to be used when implementing
the profile.

Reported to me by Yi Wang.

will be fixed in 1.1, when mifdoclet is re-run to convert javadoc into the mif files that are
included in the framemaker spec document

Support "auto apply session" for authentication mechanisms

The proposed authentication mechanism (JAVAEE_SECURITY_SPEC-32) is naturally stateless and only authenticates a user for the current request.

However, an automatic connection to the http session associated with a request is often desired. See also #20

I'd like to propose introducing a facility that automatically remembers an authenticated identity set by an authentication mechanism and as long as the session is valid automatic applies this identity for every request in the context of the http session and does not call the authentication mechanism again.

It should be possible to combine this facility with the remember me function. (see [JAVAEE_SECURITY_SPEC-33](https://java.net/jira/browse/JAVAEE_SECURITY_SPEC-33 "Support for a "remember me" functionality"))

Convert "Eclipse Project for JASPIC" into a Specification Project

In order to prepare this project to engage in specification work, we need to convert it into a specification project as defined by the Eclipse Foundation Specification Process (EFSP). As part of this work, we will change the project name and the scope.

We'll use this issue to capture the work that needs to be done as part of this effort.

  • Resolve #46
  • Resolve #45
  • Successful complete a restructuring review
  • Designate the project as a specification project of the Jakarta EE Working Group
  • Change project name

Update CONTRIBUTING.md for Specification Project's repositories

Create/Update CONTRIBUTING files

Per input from the Eclipse EMO, each Specification Project needs to ensure that a CONTRIBUTING.md or CONTRIBUTING.adoc file exists in each specification-related repository maintained by Specification Projects.
In addition, the CONTRIBUTING.md or CONTRIBUTING.adoc file needs to include the following text:

## Eclipse Development Process

This Eclipse Foundation open project is governed by the Eclipse Foundation
Development Process and operates under the terms of the Eclipse IP Policy.

The Jakarta EE Specification Committee has adopted the Jakarta EE Specification
Process (JESP) in accordance with the Eclipse Foundation Specification Process
v1.2 (EFSP) to ensure that the specification process is complied with by all
Jakarta EE specification projects.

* https://eclipse.org/projects/dev_process
* https://www.eclipse.org/org/documents/Eclipse_IP_Policy.pdf
* https://jakarta.ee/about/jesp/
* https://www.eclipse.org/legal/efsp_non_assert.php

Please do this at your earliest convenience.
Thank you!

-- EE4J PMC ([email protected])

Portable way for auth module to ask container to automatically apply auth session

Per #3 an authentication module can ask the container to create an authentication session, meaning the container "remembers" the established authenticated identity. This is a major step forward for authentication modules that don't have a requirement to maintain such a session in a custom way.

However, even when the SAM has asked the container to create this session, the SAM is called at every request (as per the Servlet Container profile requirements) and the SAM has to tell the container it (still) wants to continue with the previously established authenticated identity by executing code like the following:

public AuthStatus doValidateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject) throws AuthException {

    HttpServletRequest request = (HttpServletRequest) messageInfo.getRequestMessage();
    Principal userPrincipal = request.getUserPrincipal();

    try {
        if (userPrincipal != null) {   
            handler.handle(new Callback[] { 
new CallerPrincipalCallback(clientSubject, userPrincipal) }
            );

            return SUCCESS;   
        }

        // Rest of auth code here 
    } catch (ServletException | IOException e) {
        throw (AuthException) new AuthException().initCause(e);
    }
}

In order to make a common case easier, where the SAM simply always wants to continue with the previously established authenticated identity until the authentication session is ended (by whatever means), I'ld like to propose to add a way for the SAM to ask the container to automatically apply the identity stored in the authentication session to the current request.

After the SAM has asked for this AND an authenticated identity has been established, the SAM would indeed not be called anymore as long as the authentication session is valid (exists).

This might be implemented by defining another key to be put in the MessageInfo map that works alongside the existing key for asking a session, as follows:

  • javax.servlet.http.registerSession - Container registers a session, but SAM still called every request and SAM decides to use this or not.
  • javax.servlet.http.autoApplySession - If container has a session, it uses this and does not call the SAM.

Spec. Doc Review: Incorrect internal-doc links in final Spec document

There are a few links that weren't updated properly in the spec. These appear to have the form: "link:jaspic.html#aXXX". These should be converted to the form <> or more generally <<aXXX, text to render as the link reference>>
One example is near the end of section 1.1.10: "See what the Runtime Must Do". This should be changed per the pattern previous. I think there were others.

Some references in the change log don't have any reference text. This reads poorly.

It is unfortunate that changes section wasn't updated for this revision. Perhaps next time the document is revised, this could be included.

Ability for application to choose authentication method at runtime

In Java EE and specifically in JASPIC there is somewhat of the assumption that a single authentication method is configured (in many cases even mostly outside the application).

While for some classes of applications this has clear benefits, it doesn't particularly play nice with the increasingly popular practice that web applications offer their users a choice for their login method.

For instance, stackoverflow.com currently displays the following login choices:

  • Log in with StackExchange
  • Log in with Google
  • Log in with facebook
  • Log in with Yahoo!

See http://stackoverflow.com/users/login

To make it to implement this use case I would like to request that JASPIC adds some level of support for this.

One way to do this could be via the existing authentication context and perhaps via the concept of having different "authentication stacks". (Note that #15 is related to this, but instead asks how auth modules in a single stack interact)

With this concept, each such stack (possibly consisting of only a single SAM) is named and corresponds with an authentication mechanism (e.g. "native form", or "OpenId-Wordpress", etc).

For the Web Profile the application can then programmatically set an authentication mechanism for the current session by calling a variant on the request#authenticate method, e.g. request#authenticateWith(String, Request, Response), where the provided String parameter is a name that corresponds with one of the pre-configured stacks. Such a new method would require coordination with the Servlet spec of course.

No portable way for auth module to ask the container to create a container authentication session

The spi is optimized for the case where the auth module is responsible for
creating and managing authentication sessions internally and separate from
Servlet's HttpSession machinery.

Still there are repeated requests for this enhancement. The RI provides this
functionality via an undocumented messageInfo flag; which when set by an auth
module, instructs the Glassfish container to "register" and authentication
session.

The enhancement request is to standardize a portable means for an auth module
to cause the encompassing container to create an authentication and to bind it
to the response. This might be done by a flag, or by a new Callback handler, or
perhaps by another mechanism.

Support for RequestDispatcher#forward in auth module

In the Servlet Container Profile of JASPIC, a RequestDispatcher can be obtained from the request message in the ServerAuthModule.validateRequest method, and subsequently used to forward to a specific resource.

The fact that this can be done is not described in the JASPIC specification, and in practice not all currently certified JASPIC implementations are capable of handling this.

E.g. consider the following fragment in a ServerAuthModule.validateRequest implementation:

HttpServletRequest request = (HttpServletRequest) messageInfo.getRequestMessage();
HttpServletResponse response = (HttpServletResponse) messageInfo.getResponseMessage();

RequestDispatcher requestDispatcher = request.getRequestDispatcher("/index.xhtml");
requestDispatcher.forward(request, response);

return AuthStatus.SEND_CONTINUE;

(index.xhtml is a JSF Facelets page backing by a CDI backing bean)

This works is GlassFish 3.1.2.2 and Geronimo V3.0, but fails in some way or the other on JBoss AS 7.1.3/EAP 6.0.1, WebLogic 12.1.1 and WebSphere 8.5.

On JBoss EAP 6.0.1 the following exception is immediately thrown when invoking the forward() method:

An exception or error occurred in the container during the request processing: 
java.lang.ClassCastException: org.apache.catalina.connector.Request cannot be cast to javax.servlet.ServletRequestWrapper
	at org.apache.catalina.core.ApplicationFilterFactory.createFilterChain(ApplicationFilterFactory.java:164) [jbossweb-7.0.17.Final-redhat-1.jar:]
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:827) [jbossweb-7.0.17.Final-redhat-1.jar:]
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:622) [jbossweb-7.0.17.Final-redhat-1.jar:]
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:560) [jbossweb-7.0.17.Final-redhat-1.jar:]
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:488) [jbossweb-7.0.17.Final-redhat-1.jar:]
	at jaspic.TestServerAuthModule.validateRequest(TestServerAuthModule.java:120) [classes:]

On WebLogic 12.1.1. the following exception is immediately thrown:

javax.servlet.ServletException: Must call associate() before calling activate()
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)
	at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:242)
	at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:216)
	at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:132)
	at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:338)
	at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:221)
	at weblogic.servlet.internal.RequestDispatcherImpl.invokeServlet(RequestDispatcherImpl.java:564)
	at weblogic.servlet.internal.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:263)
	at jaspic.TestServerAuthModule.validateRequest(TestServerAuthModule.java:120)

On WebSpere 8.5 the following exception is thrown after the auth module returns:

0000006c WebCollaborat A   
SECJ0056E: Authentication failed for reason Jaspi authentication failed, unexpected HttpServletResponse status: 200
0000006c webapp E com.ibm.ws.webcontainer.webapp.WebApp logServletError 
SRVE0293E: [Servlet Error]-[servlet.TestServlet]: 
java.lang.IllegalStateException: Response already committed.
	at com.ibm.ws.webcontainer.webapp.WebAppDispatcherContext.sendError(WebAppDispatcherContext.java:599)
	at com.ibm.ws.webcontainer.webapp.WebAppDispatcherContext.sendError(WebAppDispatcherContext.java:656)
	at com.ibm.ws.webcontainer.srt.SRTServletResponse.sendError(SRTServletResponse.java:1255)
	at com.ibm.ws.security.web.WebReply.sendError(WebReply.java:61)
	at com.ibm.ws.security.web.DenyReply.writeResponse(DenyReply.java:35)
	at com.ibm.ws.security.web.EJSWebCollaborator.handleException(EJSWebCollaborator.java:735)
	at com.ibm.ws.webcontainer.collaborator.WebAppSecurityCollaboratorImpl.handleException(WebAppSecurityCollaboratorImpl.java:267)
	at com.ibm.wsspi.webcontainer.collaborator.CollaboratorHelper.processSecurityPreInvokeException(CollaboratorHelper.java:153)

On WebSphere 8.5 the forwarded resource is processed correctly. After some experimentation, it seems WebSphere 8.5 only allows http status codes 302, 303, 307 and 401 after an auth module returns SEND_CONTINUE. On WebLogic, the forward does work when the application hasn't activated CDI (e.g. when no beans.xml is present in WEB-INF). On JBoss EAP, forwarding works if the request is casted to a proprietary type and the result of a getRequest() call is provided to the dispatcher.

Since all the mentioned implementations are Java EE 6 certified, the JASPIC spec probably has to be clarified here and if possible a TCK test for this should be added.

Since forwarding can be an important use case, e.g. for displaying a login form as response to the original request, I would like to request that forwarding is being covered by the JASPIC spec. Specifically:

  • Specify that forwarding is a supported operation
  • Specify which status the auth module should return when forwarding
  • Specify which HTTP response codes are legal following a SEND_CONTINUE return value (perhaps there should be no limitation?)
  • Add a TCK test in which an auth module does a forward (if possible for a TCK: forward to a complex resource like a JSF page, with CDI being enabled, and where the JSF page uses a CDI backing bean)

Jakarta EE 8 TCK job

To test Jakarta EE 8 compatibility we need to create a Jenkins job on project's Cloud Jenkins instance formally testing the API against the relevant TCK and as needed, relevant CTS subset tests.

For projects that do not already have automated testing, there is provided parameterized Jenkins job that can be invoked to perform these tests. User provides a link to an Eclipse GlassFish test build and sets the test sub-set parameters:

Additional instructions and guidance for using and directly running TCKs is available on this wiki. Also in the jakartaee-tck project repository.

Define a standardized way to stack auth modules

According to JASPIC 1.1.2 an authentication context can manage multiple auth modules:

An authentication context is responsible for constructing, initializing, and coordinating the invocation of one or more encapsulated authentication modules.

If the context implementation supports the configuration of multiple authentication modules within a context (for example, as sufficient alternatives), the context coordinates the invocation of the authentication modules on behalf of both the message processing runtime and the authentication modules.

JASPIC 2.1.5.1 gives some more details:

If a context encapsulates multiple authentication modules, the context must embody the control logic to determine which modules of the context are to be invoked and in what order.

Contexts which encapsulate alternative sufficient modules must ensure that the same message values are passed to each invoked alternative of the context. If a context invokes multiple authentication modules, the context must combine the AuthStatus values returned by the invoked authentication modules to establish the AuthStatus value returned by the context to the messaging runtime.

The context implementation must define the logic for combining the returned AuthStatus values.

This gives a framework to work with, but it does not specify the exact semantics of how the handling of multiple modules (stacking) should take place. Each implementation is free to do this largely in an implementation specific way. This makes it hard to cary over a configuration of modules from one server to the other.

In order to improve portability and as a possible precursor to a standardized declarative way to configure auth modules, I would like to request to standardize a specific way of handling multiple auth modules and demanding the runtime to make an authentication context available that implements this.

Possibly the JAAS/PAM semantics of Required, Requisite, Sufficient and Optional could be formally specified for use with JASPIC. (the existing specification already hints to supporting the Sufficient semantics)

Unavailable

This issue was unavailable for migration from original issue tracker.

Compatibility certification request for EE4J implementation of Jakarta Authentication

  • Organization Name ("Organization") and, if applicable, URL
    Eclipse Foundation
  • Product Name, Version and download URL (if applicable)
    Eclipse GlassFish 5.1
  • Specification Name, Version and download URL
    Jakarta Authentication 1.1
  • TCK Version, digital SHA-256 fingerprint and download URL
    Jakarta Authentication TCK 1.1.0, SHA-256: 3bd5919a95ad4e6a9e610a585448f90b8b4475a52cc9ebad429b412b949c0a89
  • Public URL of TCK Results Summary
    TCK results summary
  • Any Additional Specification Certification Requirements
    None
  • Java runtime used to run the implementation
    Oracle JDK 1.8.0_202
  • Summary of the information for the certification environment, operating system, cloud, ...
    Linux
  • By checking this box I acknowledge that the Organization I represent accepts the terms of the EFTL.
  • By checking this box I attest that all TCK requirements have been met, including any compatibility rules.

AuthConfigFactory javadoc indicates methods throw AuthException but method signatures do not

avadoc of four AuthConfigFactory methods indicate that they throw
AuthException (which is a checked exception) but method signatures do not
declare that they throw AuthException, and thus the exception cannot be thrown.
Moreover, the inability to throw this exception, makes it unclear how errors
are to be signaled by these methods.

public static AuthConfigFactory getFactory();

public abstract java.lang.StringregisterConfigProvider(
java.lang.String className,
java.util.Map properties,
java.lang.String layer,
java.lang.String appContext,
java.lang.String description);

public abstract java.lang.String registerConfigProvider(
AuthConfigProvider provider,
java.lang.String layer,
java.lang.String appContext,
java.lang.String description)

public abstract void refresh()

javadoc if refresh method of AuthConfig interface also indicates that it throws
AuthException although method signature does not declare that it does.

javadoc if refresh method of AuthConfigProvider interface also indicates that
it throws AuthException although method signature does not declare that it
does.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.