javaee-security-spec
  1. javaee-security-spec
  2. JAVAEE_SECURITY_SPEC-18

Portable way to deploy identity stores in application

    Details

    • Type: New Feature New Feature
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Component/s: None
    • Labels:
      None

      Description

      Currently there is no portable way of deploying identity stores with the application. This is a potential usability issue, especially in cloud environments.

      It may be very helpful to have portable annotations or XML for this, just like we now have for data sources and JMS resources. As part of this effort, it would also be great if the programming model around identity stores (for which currently JAAS login modules are a semi-standard) could also be modernized using annotations.

      I think in the bare minimum we need to have something as simple as this:

      @IdentityStore
      public class MyIdentityStore {
      
        @Inject UserService userService;
      
        @OnAuthentication
        // The parameters could suit the credentials mechanism being used.
        public Principal getPrincipal(String username, String password) {
          // Construct the principal using the user service.
        }
      
        @OnAuthorization
        public String[] getRoles (Principal principal) {
          // Construct an array of roles using the principal and user service.
        }
      }
      

      Do let me know if anything needs to be explained further - I am happy to help.

      Please note that these are purely my personal views and certainly not of Oracle's as a company.

        Activity

        Hide
        arjan tijms added a comment -

        Reza, don't you mean JASPIC artifacts?

        JAAS by itself is not really standardized to interoperate with Java EE. Several vendors make use of JAAS based login modules as a proprietary (vendor specific) solution. Raymond K. Ng wrote two very good articles about this a while ago:

        JASPIC was added to Java EE 6 specifically for this. I blogged about this at Implementing container authentication in Java EE with JASPIC

        Deploying JASPIC auth modules via portable annotations and XML came up several times already. I mentioned the issue in JAVAEE_SPEC-9 as well. I didn't create an issue at https://java.net/jira/browse/JASPIC_SPEC for this yet, since maybe JASPIC_SPEC-15 should be solved first. Stacking of modules is a feature that most vendor specific solutions have in their declarative descriptors.

        Modernizing the programming model is definitely a big issue as well. Especially being able to use CDI and being able to listen to (CDI) events would be a big plus. I created JASPIC_SPEC-14 for this.

        Also note that programmatic deployment of JASPIC auth modules was already supported in Java EE 6, and this has been made fully portable in Java EE 7 (see What's new in Java EE 7's authentication support?).

        Hope this helped

        Show
        arjan tijms added a comment - Reza, don't you mean JASPIC artifacts? JAAS by itself is not really standardized to interoperate with Java EE. Several vendors make use of JAAS based login modules as a proprietary (vendor specific) solution. Raymond K. Ng wrote two very good articles about this a while ago: Whatever Happened to JAAS? JAAS in the Enterprise JASPIC was added to Java EE 6 specifically for this. I blogged about this at Implementing container authentication in Java EE with JASPIC Deploying JASPIC auth modules via portable annotations and XML came up several times already. I mentioned the issue in JAVAEE_SPEC-9 as well. I didn't create an issue at https://java.net/jira/browse/JASPIC_SPEC for this yet, since maybe JASPIC_SPEC-15 should be solved first. Stacking of modules is a feature that most vendor specific solutions have in their declarative descriptors. Modernizing the programming model is definitely a big issue as well. Especially being able to use CDI and being able to listen to (CDI) events would be a big plus. I created JASPIC_SPEC-14 for this. Also note that programmatic deployment of JASPIC auth modules was already supported in Java EE 6, and this has been made fully portable in Java EE 7 (see What's new in Java EE 7's authentication support? ). Hope this helped
        Hide
        reza_rahman added a comment - - edited

        My bad - I should have kept the terminology generic and simply said security artifacts. The only reason I even mentioned JAAS is because I am drawing initial inspiration heavily from the very simple way Resin integrates JAAS modules (http://www.caucho.com/resin-4.0/admin/security-authenticators.xtp#resinJaasAuthenticator) either in resin.xml (server-wide configuration) or in resin-web.xml (configuration specific to an application).

        I think in the bare minimum we need to have something as simple as this:

        @IdentityStore
        public class MyIdentityStore {
        
          @Inject UserService userService;
        
          @OnAuthentication
          // The parameters could suit the credentials mechanism being used.
          public Principal getPrincipal(String username, String password) {
            // Construct the principal using the user service.
          }
        
          @OnAuthorization
          public String[] getRoles (Principal principal) {
            // Construct an array of roles using the principal and user service.
          }
        }
        

        The exact sematics here is not important, just the general concept. I would hope this could be sorted out in the relevant expert group/groups. I know this is easier said than done. However, if Resin can do it (kind of), it can't be that hard either.

        An interesting question of course is how this fits into JAAS, JASPIC, etc. Maybe the right approach is that this is a much simpler approach geared towards developers whereas JAAS, JASPIC, etc are geared towards vendors where a more complex programming model is useful.

        As an aside, Scott Ferguson (Resin Chief Architect) was resistant to JASPIC since he belived there is not likely to be a large number of security vendors that would be that interested in plugging into application servers and JAAS itself would only be used by developers that need very customized security. I think there is merit to that view.

        Please note that these are purely my personal views and certainly not of Oracle's as a company.

        Show
        reza_rahman added a comment - - edited My bad - I should have kept the terminology generic and simply said security artifacts. The only reason I even mentioned JAAS is because I am drawing initial inspiration heavily from the very simple way Resin integrates JAAS modules ( http://www.caucho.com/resin-4.0/admin/security-authenticators.xtp#resinJaasAuthenticator ) either in resin.xml (server-wide configuration) or in resin-web.xml (configuration specific to an application). I think in the bare minimum we need to have something as simple as this: @IdentityStore public class MyIdentityStore { @Inject UserService userService; @OnAuthentication // The parameters could suit the credentials mechanism being used. public Principal getPrincipal( String username, String password) { // Construct the principal using the user service. } @OnAuthorization public String [] getRoles (Principal principal) { // Construct an array of roles using the principal and user service. } } The exact sematics here is not important, just the general concept. I would hope this could be sorted out in the relevant expert group/groups. I know this is easier said than done. However, if Resin can do it (kind of), it can't be that hard either. An interesting question of course is how this fits into JAAS, JASPIC, etc. Maybe the right approach is that this is a much simpler approach geared towards developers whereas JAAS, JASPIC, etc are geared towards vendors where a more complex programming model is useful. As an aside, Scott Ferguson (Resin Chief Architect) was resistant to JASPIC since he belived there is not likely to be a large number of security vendors that would be that interested in plugging into application servers and JAAS itself would only be used by developers that need very customized security. I think there is merit to that view. Please note that these are purely my personal views and certainly not of Oracle's as a company.
        Hide
        arjan tijms added a comment - - edited

        I think in the bare minimum we need to have something as simple as this:

        @IdentityStore
        public class MyIdentityStore {
        
          @Inject UserService userService;
        
          @OnAuthentication
          // The parameters could suit the credentials mechanism being used.
          public Principal getPrincipal(String username, String password) {
            // Construct the principal using the user service.
          }
        
          @OnAuthorization
          public String[] getRoles (Principal principal) {
            // Construct an array of roles using the principal and user service.
          }
        }
        

        I fully agree with this, even so much that I earlier proposed a largely identical thing in JAVAEE_SPEC-9

        @IdentityStore
        public class MyIdentityStore implements PasswordIdentityStore {
        
            private User user;
        
            @Inject
            private UserService userService;
        
            public void authenticate(String name, String password) {    }
        
            public String getUserName() {  }
        
            public List<String> getApplicationRoles() {  }
        }
        

        I know this is easier said than done.

        Implementing this appeared to be more or less doable using a JASPIC SAM that delegates to a CDI bean. I prototyped this in the OmniSecurity project, e.g. with this SAM. The emphasis is on more or less, since JASPIC doesn't natively support CDI. If it did, such a simplified identity store would really not be that difficult.

        Of course the point is that such an @IdentityStore should become a standard part of Java EE.

        Maybe the right approach is that this is a much simpler approach geared towards developers whereas JAAS, JASPIC, etc are geared towards vendors where a more complex programming model is useful.

        That's an interesting discussion. I personally think JASPIC doesn't equate a complex programming model at all. It's understandable that one might think it is complex after reading through the JASPIC spec, which is written in a rather formal writing style. However, when actually trying some code examples, it becomes clear that there's not that much to it.

        The main concept is basically a single method called validateRequest that functions pretty much like the doFilter method in a Servlet Filter, from there you pass a username and optionally one or more roles into a callback handler. E.g.

        public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject) throws AuthException {
        
            CallerPrincipalCallback callerPrincipalCallback = new CallerPrincipalCallback(clientSubject, "test");
            GroupPrincipalCallback groupPrincipalCallback = new GroupPrincipalCallback(clientSubject, new String[] { "architect" });
        
            handler.handle(new Callback[] { callerPrincipalCallback, groupPrincipalCallback });
        }
        

        If anything, I think the perceived complexity comes from JASPIC simply being rather low-level and still at Java 1.4. It's a bit like GenericServlet vs HttpServlet. It's not that the Servlet model is complex, but GenericServlet is well, very generic. If you'd only had that you would need to do a lot of casting and create a lot of boilerplate code. A rather simple base class specific for Servlet Profile SAMs would go a long way (I proposed this in JASPIC_SPEC-17).

        I created an example of a SAM based on such base class here: TwoFactorServerAuthModule.

        With just a tiny bit of helper code, registering a username and roles with the container from within a SAM then looks like this, which IMHO is much easier to use:

        httpMsgContext.registerWithContainer(
            authenticator.getUsername(), 
            authenticator.getRoles()
        );
        

        As an aside, Scott Ferguson (Resin Chief Architect) was resistant to JASPIC since he belived there is not likely to be a large number of security vendors that would be that interested in plugging into application servers and JAAS itself would only be used by developers that need very customized security.

        Well, for the projects I'm involved with we're using JASPIC authentication modules for anything from a form based login module that integrates better with JSF than the build-in Servlet version, to auth modules for logging in with Facebook, Twitter, LinkedIn and such.

        I don't think any of those use cases would really qualify as being very customized security. If it weren't for JASPIC, we most likely would have been required to completely ignore Java EE security and implement the security requirements using e.g. Filters and interceptors and such.

        I do think there's a lot to be improved in JASPIC (and even more for Java EE security in general). But specifically for JASPIC I think that's for a large part just modernizing it, just like was recently done for JMS 1.1.

        Another issue of concern is the documentation of JASPIC. The spec document isn't very suited for most application programmers to learn how to use it, but other than the spec there's not much out there. Even Oracle's own Java EE tutorial doesn't explain JASPIC. Because of that many people simply don't know about JASPIC and how it can be used.

        Show
        arjan tijms added a comment - - edited I think in the bare minimum we need to have something as simple as this: @IdentityStore public class MyIdentityStore { @Inject UserService userService; @OnAuthentication // The parameters could suit the credentials mechanism being used. public Principal getPrincipal( String username, String password) { // Construct the principal using the user service. } @OnAuthorization public String [] getRoles (Principal principal) { // Construct an array of roles using the principal and user service. } } I fully agree with this, even so much that I earlier proposed a largely identical thing in JAVAEE_SPEC-9 @IdentityStore public class MyIdentityStore implements PasswordIdentityStore { private User user; @Inject private UserService userService; public void authenticate( String name, String password) { } public String getUserName() { } public List< String > getApplicationRoles() { } } I know this is easier said than done. Implementing this appeared to be more or less doable using a JASPIC SAM that delegates to a CDI bean. I prototyped this in the OmniSecurity project, e.g. with this SAM . The emphasis is on more or less, since JASPIC doesn't natively support CDI. If it did, such a simplified identity store would really not be that difficult. Of course the point is that such an @IdentityStore should become a standard part of Java EE. Maybe the right approach is that this is a much simpler approach geared towards developers whereas JAAS, JASPIC, etc are geared towards vendors where a more complex programming model is useful. That's an interesting discussion. I personally think JASPIC doesn't equate a complex programming model at all. It's understandable that one might think it is complex after reading through the JASPIC spec, which is written in a rather formal writing style. However, when actually trying some code examples, it becomes clear that there's not that much to it. The main concept is basically a single method called validateRequest that functions pretty much like the doFilter method in a Servlet Filter, from there you pass a username and optionally one or more roles into a callback handler. E.g. public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject) throws AuthException { CallerPrincipalCallback callerPrincipalCallback = new CallerPrincipalCallback(clientSubject, "test" ); GroupPrincipalCallback groupPrincipalCallback = new GroupPrincipalCallback(clientSubject, new String [] { "architect" }); handler.handle( new Callback[] { callerPrincipalCallback, groupPrincipalCallback }); } If anything, I think the perceived complexity comes from JASPIC simply being rather low-level and still at Java 1.4. It's a bit like GenericServlet vs HttpServlet. It's not that the Servlet model is complex, but GenericServlet is well, very generic. If you'd only had that you would need to do a lot of casting and create a lot of boilerplate code. A rather simple base class specific for Servlet Profile SAMs would go a long way (I proposed this in JASPIC_SPEC-17 ). I created an example of a SAM based on such base class here: TwoFactorServerAuthModule . With just a tiny bit of helper code, registering a username and roles with the container from within a SAM then looks like this, which IMHO is much easier to use: httpMsgContext.registerWithContainer( authenticator.getUsername(), authenticator.getRoles() ); As an aside, Scott Ferguson (Resin Chief Architect) was resistant to JASPIC since he belived there is not likely to be a large number of security vendors that would be that interested in plugging into application servers and JAAS itself would only be used by developers that need very customized security. Well, for the projects I'm involved with we're using JASPIC authentication modules for anything from a form based login module that integrates better with JSF than the build-in Servlet version, to auth modules for logging in with Facebook, Twitter, LinkedIn and such. I don't think any of those use cases would really qualify as being very customized security. If it weren't for JASPIC, we most likely would have been required to completely ignore Java EE security and implement the security requirements using e.g. Filters and interceptors and such. I do think there's a lot to be improved in JASPIC (and even more for Java EE security in general). But specifically for JASPIC I think that's for a large part just modernizing it, just like was recently done for JMS 1.1. Another issue of concern is the documentation of JASPIC. The spec document isn't very suited for most application programmers to learn how to use it, but other than the spec there's not much out there. Even Oracle's own Java EE tutorial doesn't explain JASPIC. Because of that many people simply don't know about JASPIC and how it can be used.

          People

          • Assignee:
            alex.kosowski
            Reporter:
            reza_rahman
          • Votes:
            14 Vote for this issue
            Watchers:
            7 Start watching this issue

            Dates

            • Created:
              Updated: