Announcement Announcement Module
Collapse
No announcement yet.
How to assign a role to authentication provider Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to assign a role to authentication provider

    Hi,

    I built my own authentication provider, based on Spring classes generated by AndroMDA. To retrieve userdetails, I need to call a getUserAccount method on a ServiceAccess class. I want this method to be callable only for autenticated users. But the problem is that my authentication provider executes as an anonymous user, so I need to give access to ROLE_ANONYMOUS for my getUserByName method, and I don't want it at all !

    Here is how I configured my authentication provider :
    HTML Code:
    <bean id="serviceAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
    	<property name="userDetailsService" ref="serviceAuthenticationImpl" />
    </bean>
    	
    <bean id="serviceAuthenticationImpl" class="fr.horoquartz.t4.acegisecurity.userdetails.service.ServiceDaoImpl">
    	<property name="serviceAccess" ref="serviceAcces" />
    </bean>
    And here is how I configured the interceptor :

    HTML Code:
    <bean id="serviceSecurityInterceptor" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
            <property name="accessDecisionManager"><ref bean="serviceAccessDecisionManager"/></property>
            <property name="authenticationManager"><ref bean="authenticationManager"/></property>
            <property name="objectDefinitionSource">
                <value>
                    fr.horoquartz.t4.a14n.ServiceAcces.getCompteUtilisateur=ROLE_ANONYMOUS
                </value>
            </property>
    </bean>
    Is there a way to tell the authentication provider to execute with a specific role ? Or is there another way to do call protected methods from an authentication provider ?

    Thanks in advance

  • #2
    Checkout the chapter about run-as in the documentation. This allows a certain process to run as a specific role/permission.

    Comment


    • #3
      OK, I think I understood the idea behind runAsManager, but I can't make it work I still have an access denied message when runnning the getCompteUtilisateur method.

      Here is a part of the Java stack trace :
      Code:
      org.acegisecurity.AccessDeniedException: Accès refusé.
      	at org.acegisecurity.vote.AffirmativeBased.decide(AffirmativeBased.java:68)
      	at org.acegisecurity.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:285)
      	at org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:63)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
      	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
      	at $Proxy9.getCompteUtilisateur(Unknown Source)
      	at fr.horoquartz.t4.acegisecurity.userdetails.service.ServiceDaoImpl.loadUserByUsername(ServiceDaoImpl.java:75)
      	at org.acegisecurity.providers.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:87)
      	at org.acegisecurity.providers.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:115)
      	at org.acegisecurity.providers.ProviderManager.doAuthentication(ProviderManager.java:188)
      	at org.acegisecurity.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:45)
      	at org.acegisecurity.ui.webapp.AuthenticationProcessingFilter.attemptAuthentication(AuthenticationProcessingFilter.java:71)
      	at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:199)
      	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274)
      	at org.acegisecurity.ui.logout.LogoutFilter.doFilter(LogoutFilter.java:106)
      	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274)
      	at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:229)
      	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274)
      	at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:148)
      	at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:98)
      Here is how I configured the interceptor :

      Code:
          <bean id="serviceSecurityInterceptor" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
              <property name="accessDecisionManager"><ref bean="serviceAccessDecisionManager"/></property>
              <property name="authenticationManager"><ref bean="authenticationManager"/></property>
              <property name="runAsManager"><ref bean="runAsManager"/></property>
              <property name="objectDefinitionSource">
                  <value>
                      fr.horoquartz.t4.a14n.ServiceAcces.getCompteUtilisateur=RUN_AS_SERVER
                  </value>
              </property>
          </bean>
      And here is how I configured the runAsManager :
      Code:
      	<bean id="runAsManager" class="org.acegisecurity.runas.RunAsManagerImpl">
      		<property name="key"><value>my_run_as_password</value></property>
      	</bean>
      	
      	<bean id="runAsAuthenticationProvider" class="org.acegisecurity.runas.RunAsImplAuthenticationProvider">
      		<property name="key"><value>my_run_as_password</value></property>
      	</bean>
      And here is an extract of my web.xml with configuration for Acegi :
      Code:
      	<filter>
      		<filter-name>AcegiFilter</filter-name>
      		<filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
      		<init-param>
      			<param-name>targetBean</param-name>
      			<param-value>t4AcegiFilter</param-value>
      		</init-param>
      	</filter>
      	<filter-mapping>
      		<filter-name>AcegiFilter</filter-name>
      		<url-pattern>/*</url-pattern>
      	</filter-mapping>

      Note the runAsManager and the method interceptor are declared in different XML files. Can you see something wrong in my configuration ?
      Last edited by chawax; Mar 30th, 2007, 09:18 AM. Reason: Forgot to join web.xml ...

      Comment


      • #4
        Have you looked at the debug log output to get some idea of what is happening?

        Comment


        • #5
          Here is the log output :

          Code:
          2007-04-02 09:32:42,868 DEBUG [org.acegisecurity.providers.ProviderManager] - Authentication attempt using org.acegisecurity.providers.dao.DaoAuthenticationProvider
          2007-04-02 09:32:42,868 DEBUG [org.acegisecurity.intercept.AbstractSecurityInterceptor] - Secure object: invocation: method 'getCompteUtilisateur', arguments [00055069]; target is of class [fr.horoquartz.t4.a14n.ServiceAccesImpl]; ConfigAttributes: [RUN_AS_SERVER]
          2007-04-02 09:32:42,868 DEBUG [org.acegisecurity.intercept.AbstractSecurityInterceptor] - Previously Authenticated: org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken@9055e4a6: Username: anonymousUser; Password: [PROTECTED]; Authenticated: true; Details: org.acegisecurity.ui.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
          2007-04-02 09:32:42,884 DEBUG [org.springframework.web.context.support.XmlWebApplicationContext] - Publishing event in context [Root WebApplicationContext]: org.acegisecurity.event.authorization.AuthorizationFailureEvent[source=invocation: method 'getCompteUtilisateur', arguments [00055069]; target is of class [fr.horoquartz.t4.a14n.ServiceAccesImpl]]
          2007-04-02 09:32:42,884 DEBUG [org.acegisecurity.context.HttpSessionContextIntegrationFilter] - SecurityContextHolder set to new context, as request processing completed
          2007-04-02 09:32:42,884 ERROR [org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/T4-web-1.0].[default]] - "Servlet.service()" pour la servlet default a généré une exception
          org.acegisecurity.AccessDeniedException: Accès refusé.
          	at org.acegisecurity.vote.AffirmativeBased.decide(AffirmativeBased.java:68)
          	at org.acegisecurity.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:285)
          	at org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:63)
          	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
          	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
          	at $Proxy9.getCompteUtilisateur(Unknown Source)
          	at fr.horoquartz.t4.acegisecurity.userdetails.service.ServiceDaoImpl.loadUserByUsername(ServiceDaoImpl.java:61)
          What I see :
          - The interceptor for getCompteUtilisateur has RUN_AS_SERVER as config attribute
          - The anonymous user has only ROLE_ANONYMOUS granted authority, but not RUN_AS_SERVER one. For what I understood, it should have both ...

          Do you have to add RUN_AS_SERVER role by code or should it be done by Acegi Security itself ?

          Comment


          • #6
            Just a quick question. Are you trying to secure the retrieveUser code? e.g. the code that Acegi is going to try and use to find a user to place in the Authentication object.

            Comment


            • #7
              Yes, I want to secure the call to the service method that gets user infos.

              Comment


              • #8
                The exception you show occurs before the run-as manager is invoked.

                http://acegisecurity.org/multiprojec...eptor.html#285

                The run-as manager is intended to change the authentication under which a method runs. It is applied after the authorization checks for the method itself have been made.

                Comment


                • #9
                  I'm not sure to understand Does it mean there is a problem with my accessDecisionManager ?

                  Here is how I configured it :
                  Code:
                  <bean id="accessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
                  		<property name="allowIfAllAbstainDecisions" value="false"/>
                  		<property name="decisionVoters">
                  			<list>
                  				<bean class="org.acegisecurity.vote.RoleVoter"/>
                  				<bean class="org.acegisecurity.vote.AuthenticatedVoter"/>
                  			</list>
                  		</property>
                  </bean>

                  Comment


                  • #10
                    No, it's working as expected. The security interceptor applies the access constraints to the method and then *if* it's allowed, substitutes the run-as token for the duration of the method call.

                    I think you need to clarify what you're trying to achieve - are you trying to say that the only place you want your user details service called is via the authentication provider?

                    Comment


                    • #11
                      Originally posted by Luke View Post
                      I think you need to clarify what you're trying to achieve - are you trying to say that the only place you want your user details service called is via the authentication provider?
                      Yes, something like that. The method to get user details returns important informations like user password, so I want to secure it and authorize only authentication provider to call it.

                      Comment


                      • #12
                        Well, you can configure that kind of thing by running under a SecurityManager, or you could use aspectj. It's not really the kind of thing that Acegi should be doing - more about applying safeguard policies to your development process. If you're actually worried about code-level threats then you will have to do a lot more than just protecting the authentication provider.

                        Where do you see a threat coming from?

                        Comment


                        • #13
                          Well, I'm not a security specialist so I don't really know where the threat could come from. But all other methods will be secured (available only for authenticated and authorized users), so I want to do the same with the service method returning userdetails from the database, which is sensible data. Moreover we plan to expose these services methods to final users through business processes they can build with BPEL or something like that. So people who will potentially use these services are not only developers and are not always aware about security issues

                          Comment

                          Working...
                          X