6 Replies Latest reply on Nov 16, 2006 10:23 AM by aahamlin

    seam-security example

    aahamlin

      In Seam 1.1 the security classes are available to setup an Authentication Provider and begin using the @Secure annotation. I've successfully run the examples\security application (after a few minor tweaks in the User and Role EJBs).

      So, now my questions are: how do I use the annotations?

      Specifically, the ProtectedAction class has a series of annotations and calls, which apparently work because I receive the security error when I'm not the 'admin' user, but for which I can not find documentation.

      The foo() method's:
      @Secure(permissions = {@Permission(name = "protected", action = "call")})

      I get an error that I don't have permission but how do I setup a user/role with the necessary permissions?

      The modifyCustomer() and modifyReadonlyCustomer() methods' both make these calls:
      SeamSecurityManager.instance().checkPermission(customer, "modify");

      Is this explicit call really necessary? There must be away to check permissions using an annotation.

      BTW: the modifyReadonlyCustomer() method breaks when logged in as the 'admin' user but works fine when logged in as the 'user' user role.

      Thanks for any more information on how to use this API. In comparison to all the other hoops there are to jump through in setting up JAAS security on Seam this setup seems much, much simpler and streamlined.

        • 1. Re: seam-security example
          shane.bryzak

          The security API is still under heavy construction and I've yet to write documentation for it. The @Secure annotation is used to "secure" access to a component or component method by specifying which roles or permissions are required to be able to invoke it.

          Within the security API there are two types of permissions; "static" and "dynamic" (those are the best descriptions I can come up with). Static permissions are intended to be allocated to roles at initialization time, and to answer your question about how to set up user/roles with permissions, this bit isn't implemented yet.

          Dynamic permissions are used when you need to make a decision based on some contextual information whether a permission should be granted or not.

          The checkPermission() call is necessary because it performs an explicit permissions check against the specified object using its ACL - something that you can't do with an annotation. This is the functionality I'm currently working on, and as a result the security example may break occasionally.

          • 2. Re: seam-security example

            Hey Shane,

            I have one more question regarding the security layer you are currently building:

            As far as i can see you are concentrating on the backend part (calls on Beanmethods).

            What are your plans regarding frontend security (access to web pages / URLs)?

            I would like to see the possibility to enforce HTTP or HTTPS access to certain URLs (the security hole arising by changing from HTTPS to HTTP could be prevented by creating a 2nd session identifier cookie that is _only_ transmitted by HTTPS requests - and verified that it isn't transfered by HTTP requests).

            Further i would like to see some certificate authentication - i.e. access to example.com/admin is allowed only to people having a certain certificate (all employees) and the rest of the world gets a 404 not found.

            So how are your plans regarding such matters?

            • 3. Re: seam-security example
              shane.bryzak

              There will be a component of the security API that handles page security, however it currently has low priority. In terms of what it will provide, most likely it will be simple role-based restriction to view-tier resources. There are plans to support X509 authentication, however it is quite a way off.

              There are currently no plans for special handling of http/https requests, I imagine that this kind of thing could be implemented by a servlet filter?

              • 4. Re: seam-security example
                aahamlin

                Thanks for additional information so far... I have two questions - one specific to the current implementation, one more general. Due to the length of the error stack trace, I'll post the second question as a second reply to this thread.

                First the specific one. I have successfully deployed the seam-security example and used the simple annotations @Secure(roles = "myrole"), as shown in the example. However, when I try to deploy this same code, virtually line by line the components.xml, AuthenticatorAction, and LoginAction, from the example into my little demo app I get a seam error page. Here is the error and stack trace (sorry for the length!):

                An Error Occurred:
                No Authentication could be created, make sure the Component exists in session scope
                +- Stack Trace

                org.jboss.seam.security.AuthenticationException: No Authentication could be created, make sure the Component exists in session scope
                at org.jboss.seam.security.Authentication.instance(Authentication.java:35)
                at org.jboss.seam.interceptors.SecurityInterceptor.checkSecurity(SecurityInterceptor.java:51)
                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                at java.lang.reflect.Method.invoke(Method.java:585)
                at org.jboss.seam.util.Reflections.invoke(Reflections.java:35)
                at org.jboss.seam.intercept.Interceptor.aroundInvoke(Interceptor.java:337)
                at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:64)
                at org.jboss.seam.interceptors.BijectionInterceptor.bijectTargetComponent(BijectionInterceptor.java:51)
                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                at java.lang.reflect.Method.invoke(Method.java:585)
                at org.jboss.seam.util.Reflections.invoke(Reflections.java:35)
                at org.jboss.seam.intercept.Interceptor.aroundInvoke(Interceptor.java:337)
                at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:64)
                at org.jboss.seam.interceptors.ManagedEntityIdentityInterceptor.aroundInvoke(ManagedEntityIdentityInterceptor.java:157)
                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                at java.lang.reflect.Method.invoke(Method.java:585)
                at org.jboss.seam.util.Reflections.invoke(Reflections.java:35)
                at org.jboss.seam.intercept.Interceptor.aroundInvoke(Interceptor.java:337)
                at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:64)
                at org.jboss.seam.interceptors.OutcomeInterceptor.interceptOutcome(OutcomeInterceptor.java:45)
                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                at java.lang.reflect.Method.invoke(Method.java:585)
                at org.jboss.seam.util.Reflections.invoke(Reflections.java:35)
                at org.jboss.seam.intercept.Interceptor.aroundInvoke(Interceptor.java:337)
                at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:64)
                at org.jboss.seam.interceptors.RollbackInterceptor.rollbackIfNecessary(RollbackInterceptor.java:65)
                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                at java.lang.reflect.Method.invoke(Method.java:585)
                at org.jboss.seam.util.Reflections.invoke(Reflections.java:35)
                at org.jboss.seam.intercept.Interceptor.aroundInvoke(Interceptor.java:337)
                at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:64)
                at org.jboss.seam.interceptors.ConversationInterceptor.endOrBeginLongRunningConversation(ConversationInterceptor.java:55)
                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                at java.lang.reflect.Method.invoke(Method.java:585)
                at org.jboss.seam.util.Reflections.invoke(Reflections.java:35)
                at org.jboss.seam.intercept.Interceptor.aroundInvoke(Interceptor.java:337)
                at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:64)
                at org.jboss.seam.interceptors.TransactionInterceptor$1.work(TransactionInterceptor.java:49)
                at org.jboss.seam.util.Work.workInTransaction(Work.java:61)
                at org.jboss.seam.interceptors.TransactionInterceptor.doInTransactionIfNecessary(TransactionInterceptor.java:37)
                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                at java.lang.reflect.Method.invoke(Method.java:585)
                at org.jboss.seam.util.Reflections.invoke(Reflections.java:35)
                at org.jboss.seam.intercept.Interceptor.aroundInvoke(Interceptor.java:337)
                at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:64)
                at org.jboss.seam.interceptors.ExceptionInterceptor.handleExceptions(ExceptionInterceptor.java:28)
                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                at java.lang.reflect.Method.invoke(Method.java:585)
                at org.jboss.seam.util.Reflections.invoke(Reflections.java:35)
                at org.jboss.seam.intercept.Interceptor.aroundInvoke(Interceptor.java:337)
                at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:64)
                at org.jboss.seam.intercept.RootInterceptor.createSeamInvocationContext(RootInterceptor.java:287)
                at org.jboss.seam.intercept.RootInterceptor.invokeInContexts(RootInterceptor.java:257)
                at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:203)
                at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:128)
                at org.jboss.seam.intercept.JavaBeanInterceptor.intercept(JavaBeanInterceptor.java:69)
                at org.blackcat.seam.framework.example.UserHome$$EnhancerByCGLIB$$a5dc8a8c.create()
                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                at java.lang.reflect.Method.invoke(Method.java:585)
                at org.jboss.seam.util.Reflections.invoke(Reflections.java:35)
                at org.jboss.seam.util.Reflections.invokeAndWrap(Reflections.java:203)
                at org.jboss.seam.Component.callComponentMethod(Component.java:1738)
                at org.jboss.seam.Component.callCreateMethod(Component.java:1686)
                at org.jboss.seam.Component.newInstance(Component.java:1675)
                at org.jboss.seam.Component.getInstance(Component.java:1583)
                at org.jboss.seam.Component.getInstance(Component.java:1557)
                at org.jboss.seam.jsf.SeamVariableResolver.resolveVariable(SeamVariableResolver.java:89)
                at org.apache.myfaces.config.LastVariableResolverInChain.resolveVariable(LastVariableResolverInChain.java:42)
                at com.sun.facelets.el.LegacyELContext$LegacyELResolver.getValue(LegacyELContext.java:134)
                at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:65)
                at com.sun.el.parser.AstValue.getValue(AstValue.java:106)
                at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:192)
                at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
                at com.sun.facelets.el.LegacyValueBinding.getValue(LegacyValueBinding.java:56)
                at javax.faces.component.UIOutput.getValue(UIOutput.java:77)
                at org.apache.myfaces.shared_impl.renderkit.RendererUtils.getStringValue(RendererUtils.java:217)
                at org.apache.myfaces.shared_impl.renderkit.html.HtmlTextRendererBase.renderInput(HtmlTextRendererBase.java:135)
                at org.apache.myfaces.shared_impl.renderkit.html.HtmlTextRendererBase.encodeEnd(HtmlTextRendererBase.java:53)
                at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:536)
                at org.jboss.seam.ui.JSF.renderChild(JSF.java:355)
                at org.jboss.seam.ui.JSF.renderChildren(JSF.java:321)
                at org.jboss.seam.ui.UIDecorate.encodeChildren(UIDecorate.java:323)
                at com.sun.facelets.tag.jsf.ComponentSupport.encodeRecursive(ComponentSupport.java:234)
                at com.sun.facelets.tag.jsf.ComponentSupport.encodeRecursive(ComponentSupport.java:239)
                at com.sun.facelets.tag.jsf.ComponentSupport.encodeRecursive(ComponentSupport.java:239)
                at com.sun.facelets.tag.jsf.ComponentSupport.encodeRecursive(ComponentSupport.java:239)
                at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:580)
                at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:384)
                at javax.faces.webapp.FacesServlet.service(FacesServlet.java:138)
                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                at org.jboss.seam.servlet.SeamRedirectFilter.doFilter(SeamRedirectFilter.java:63)
                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                at org.jboss.seam.servlet.SeamExceptionFilter.doFilter(SeamExceptionFilter.java:91)
                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
                at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
                at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
                at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
                at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
                at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
                at org.jboss.web.tomcat.tc5.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:156)
                at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
                at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
                at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
                at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
                at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
                at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
                at java.lang.Thread.run(Thread.java:595)

                • 5. Re: seam-security example
                  aahamlin

                  Now my second question. My apologies that this is more out of my own ignorance of JBoss and Security than anything specific to your security API but I am trying to make the best decision I can upfront for security in a little web application project that I am starting on the side, both to solve an IT problem and to learn more about JBossAS,Ejb3, and Seam. So, I hope you can shed some light on the issue for me. I would really appreciate the input.

                  I have successfully implemented JAAS security of my Seam web app, following several steps posted throughout the forums. It entails a LoginModule and JAAS security domain and a FORM configuration in the web.xml file. Then after the authentication occurs a @Factory method is called that populates the Seam context with my actual User object (from the Seam/EJB3 EntityManager) by retrieving the Principal subject out of the facesContext object. So, that is all good, however... the issues with this are:

                  Using the LoginModule requires (potentially) two hits to the database, or a partitioning of my user and authentication data across different sources. For example, JAAS login via the UserRolesLoginModule from user.properties file, then a lookup of user data in EJB3 EntityManager to populate the Seam context. (In a way, I the partitioning attractive because it keeps the authentication elements out of my application data, where it is not necessary.)

                  Second, the security is configured in the web.xml at the url level rather than in the Beans themselves. So to ensure security I have to right these regex to process the URL and/or be very careful where I deploy my xhtml files to properly secure them. This is what I find particularly distasteful!

                  The solution you're developing seems to streamline this process in a very nice way for Seam components. I am wondering how does this solution relate to JAAS? For instance, I know (or think I know) that with JAAS security I can secure my EJBs from remote clients, if I choose to setup remote interfaces for them in the future - which is a likely possibility. Can the two live side-by-side? The Seam security for the web app and the JAAS security for the EJBs. Is this a reasonable approach?

                  Or, am I way off base in tackling this problem?

                  Thanks in advance for any recommendations on solving this issue.

                  • 6. Re: seam-security example
                    aahamlin

                    Oh, and I think my security constraints are significantly simple enough that just the basic @Secure(roles = "...") annotations and the ACL stuff that is in the exampe seam-security will do all that I need, at least for now. :-)