En la Primavera de Seguridad que utilice la intercept-url de la etiqueta para definir el acceso de las direcciones Url como la siguiente:

<intercept-url pattern="/**" access="ROLE_ADMIN" />
<intercept-url pattern="/student" access="ROLE_STUDENT" />

Esto está codificado en applicationContext-security.xml. Quiero leer el acceso a los valores de una tabla de base de datos en su lugar. He definido mi propia UserDetailsService y he leído los papeles para la sesión del usuario de la base de datos. ¿Cómo puedo asignar estas funciones a la dirección URL de patrones durante el tiempo de ejecución?

InformationsquelleAutor Cracker | 2011-07-31

6 Comentarios

  1. 20

    La FilterInvocationSecurityMetadatasourceparser clase en la Primavera-seguridad (intente Ctrl/Cmd+Shift+T en PTS con el código fuente) analiza el intercept-url etiquetas y crea instancias de ExpressionBasedFilterInvocationSecuritymetadatasource, que se extiende DefaultFilterInvocationSecurityMetadatasource que implementa FilterInvocationSecurityMetadatasource que se extiende SecurityMetadataSource.

    Lo que hice es crear una clase personalizada que implementa FilterInvocationSecurityMetadatasource, OptionsFromDataBaseFilterInvocationsecuritymetadatasource. He utilizado DefaultFilterInvocationSecurityMetadatasource como base para el uso de urlMatcher, para implementar el apoyo() método y algo como eso.

    A continuación, se debe a la implementación de estos métodos:

    • Colección getAttributes(Object objeto), donde se puede acceder a la base de datos, la búsqueda de la ‘objeto’ que ser asegurado (normalmente la URL para acceder) para obtener el permitido ConfigAttribute del (normalmente el PAPEL del)

    • booleano admite(Clase-clazz)

    • Colección getAllConfigAttributes()

    Tener cuidado con el, porque el es llamado en el inicio y tal vez no está bien configurado en este momento (me refiero a que, con los orígenes de datos o contexto de persistencia autowired, dependiendo de lo que usted está utilizando). La solución en un entorno web es para configurar el contextConfigLocation en el web.xml para cargar el applicationContext.xml antes de la applicationContext-security.xml

    El último paso es personalizar el applicationContext-security.xml para cargar este bean.

    Para ello, he utilizado regular frijoles en este archivo en lugar de la seguridad de espacio de nombres:

        <beans:bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
        <filter-chain-map path-type="ant">
            <filter-chain pattern="/images/*" filters="none" />
            <filter-chain pattern="/resources/**" filters="none" />
            <filter-chain pattern="/**" filters="
            securityContextPersistenceFilter,
            logoutFilter,
            basicAuthenticationFilter,
            exceptionTranslationFilter,
            filterSecurityInterceptor" 
        />
        </filter-chain-map>
    </beans:bean>
    

    Usted tiene que definir todos los relacionados con los frijoles. Por ejemplo:

        <beans:bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
        <beans:property name="authenticationManager" ref="authenticationManager"></beans:property>
        <beans:property name="accessDecisionManager" ref="affirmativeBased"></beans:property>
        <beans:property name="securityMetadataSource" ref="optionsFromDataBaseFilterInvocationSecurityMetadataSource"></beans:property>
        <beans:property name="validateConfigAttributes" value="true"/></beans:bean>
    

    Sé que no es un bien explicado respuesta, pero no es tan difícil como parece.

    Sólo el uso de la fuente como base y obtendrá lo que desea.

    De depuración con los datos en su base de datos, te ayudará mucho.

    • hola estoy tratando de lograr lo mismo pero con struts2. Fue a través de Spring Security 3.1, pero no podía conseguir lo suficiente de ideas acerca de la integración con struts2. ¿Te importaría dar algunas ideas básicas para integrarse con struts2?
    • Este ejemplo es en virtud de una versión antigua de la primavera. Cómo puedo hacerlo en la primavera-seguridad 3.2?
  2. 4

    Realidad, spring security 3.2 no se animan a hacer esto de acuerdo a http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/faq.html#faq-dynamic-url-metadata

    pero, es posible (pero no es elegante) mediante http elemento en el espacio de nombres personalizado accessDecisionManager..

    La config debería ser:

    <http pattern="/login.action" security="none"/>
    <http pattern="/media/**" security="none"/>
    
    <http access-decision-manager-ref="accessDecisionManager" >
        <intercept-url pattern="/**" access="ROLE_USER"/>
        <form-login login-page="/login.action"
                    authentication-failure-url="/login?error=1"
                    default-target-url="/console.action"/>
        <logout invalidate-session="true" delete-cookies="JSESIONID"/>
        <session-management session-fixation-protection="migrateSession">
            <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" expired-url="/login.action"/>
        </session-management>
    
        <!-- NO ESTA FUNCIONANDO, los tokens no se ponen en el request!
        <csrf />
         -->
    
    </http>
    <authentication-manager>
        <authentication-provider>
            <user-service>
                <user name="test" password="test" authorities="ROLE_USER" />
            </user-service>
        </authentication-provider>
    </authentication-manager>
    
    <beans:bean id="accessDecisionManager" class="openjsoft.core.services.security.auth.CustomAccessDecisionManager">
        <beans:property name="allowIfAllAbstainDecisions" value="false"/>
        <beans:property name="decisionVoters">
        <beans:list>
            <beans:bean class="org.springframework.security.access.vote.RoleVoter"/>
        </beans:list>
        </beans:property>
    </beans:bean>
    

    La CustomAccessDecisionManager debe ser…

    public class CustomAccessDecisionManager extends AbstractAccessDecisionManager  {
    ...
    
    public void decide(Authentication authentication, Object filter,
            Collection<ConfigAttribute> configAttributes)
            throws AccessDeniedException, InsufficientAuthenticationException {
    
      if ((filter == null) || !this.supports(filter.getClass())) {
            throw new IllegalArgumentException("Object must be a FilterInvocation");
        }
    
        String url = ((FilterInvocation) filter).getRequestUrl();
        String contexto = ((FilterInvocation) filter).getRequest().getContextPath();
    
        Collection<ConfigAttribute> roles = service.getConfigAttributesFromSecuredUris(contexto, url);
    
    
    
        int deny = 0;
    
        for (AccessDecisionVoter voter : getDecisionVoters()) {
            int result = voter.vote(authentication, filter, roles);
    
            if (logger.isDebugEnabled()) {
                logger.debug("Voter: " + voter + ", returned: " + result);
            }
    
            switch (result) {
            case AccessDecisionVoter.ACCESS_GRANTED:
                return;
    
            case AccessDecisionVoter.ACCESS_DENIED:
    
                deny++;
    
                break;
    
            default:
                break;
            }
        }
    
        if (deny > 0) {
            throw new AccessDeniedException(messages.getMessage("AbstractAccessDecisionManager.accessDenied",
                    "Access is denied"));
        }
    
        //To get this far, every AccessDecisionVoter abstained
        checkAllowIfAllAbstainDecisions();
    }
    
    ...
    }
    

    Donde getConfigAttributesFromSecuredUris recuperar formulario DB de funciones para la dirección URL específica

  3. 2

    Tengo el mismo problema, básicamente me gustaría mantener separada la lista de intercept-url de la otra springsecurity sección de configuración, la primera pertenecer a la configuración de la aplicación de este último para el producto (núcleo, complemento) de configuración.

    Hay un propuesta en la JIRA de la primavera, en cuanto a este problema.

    No quiero renunciar a utilizar el springsecurity espacio de nombres, así que tengo que pensar a algunas de las posibles soluciones con el fin de lidiar con esto.

    Con el fin de tener la lista de intercept-url crean de forma dinámica, que se tiene que inyectar el securitymetadatasource objeto en el FilterSecurityInterceptor.
    El uso de springsecurity esquema de la instancia de FilterSecurityInterceptor es creado por el HttpBuilder clase y no hay manera de pasar el securitymetadatasource como propiedad definida en el esquema de archivo de configuración, como menos como el uso de tipo de solución, que puede ser:

    • Definir un filtro personalizado, para ser ejecutado antes de FilterSecurityInterceptor, en este filtro de la recuperación de la instancia FilterSecurityInterceptor (suponiendo una única http sección se define) en la primavera de contexto e inyectar allí la securitymetadatasource instancia;
    • El mismo que el anterior pero en un HandlerInterceptor.

    ¿Qué te parece?

  4. 1

    Esta la solución que he aplicado con el fin de dividir la lista de intercept-url de las entradas de la otra primavera de configuración de seguridad.

    <security:custom-filter ref="parancoeFilterSecurityInterceptor"
            before="FILTER_SECURITY_INTERCEPTOR" />
    ........
    
    <bean id="parancoeFilterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor" >  
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="accessDecisionManager" ref="accessDecisionManager"/>
        <property name="securityMetadataSource" ref="securityMetadataSource"/>
    </bean>
    

    El frijol securityMetadataSource se puede poner en el mismo archivo de configuración o en otro archivo de configuración.

    <security:filter-security-metadata-source
        id="securityMetadataSource" use-expressions="true">
        <security:intercept-url pattern="/admin/**"
            access="hasRole('ROLE_ADMIN')" />
    </security:filter-security-metadata-source> 
    

    Por supuesto, usted puede decidir implementar su propio securityMetadataSource de frijol en la implementación de la interfaz de FilterInvocationSecurityMetadatasource.
    Algo como esto:

    <bean id="securityMetadataSource" class="mypackage.MyImplementationOfFilterInvocationSecurityMetadataSource" />
    

    Espero que esto ayude.

    • Terminé con la misma solución. Es una lástima que no hay ninguna manera fácil de cómo dividir la definición.
  5. 1

    Una solución simple que funciona para mí.

    <intercept-url pattern="/**/**" access="#{@customAuthenticationProvider.returnStringMethod}" />
    <intercept-url pattern="/**" access="#{@customAuthenticationProvider.returnStringMethod}" />
    

    customAuthenticationProvider es un bean

    <beans:bean id="customAuthenticationProvider"
        class="package.security.CustomAuthenticationProvider" />
    

    en CustomAuthenticationProvider método de crear de clase:

    public synchronized String getReturnStringMethod()
    {
        //get data from database (call your method)
    
        if(condition){
            return "IS_AUTHENTICATED_ANONYMOUSLY";
        }
        return "ROLE_ADMIN,ROLE_USER";
    }
    
  6. 0

    Esta es la forma en que se puede hacer en la Primavera de de Seguridad 3.2:

    @Configuration
    @EnableWebMvcSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Bean
        public SecurityConfigDao securityConfigDao() {
            SecurityConfigDaoImpl impl = new SecurityConfigDaoImpl() ;
            return impl ;
        }
    
    
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            /* get a map of patterns and authorities */
            Map<String,String> viewPermissions = securityConfigDao().viewPermissions() ;
    
             ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry interceptUrlRegistry = http
            .authorizeRequests().antMatchers("/publicAccess/**")
            .permitAll(); 
    
            for (Map.Entry<String, String> entry: viewPermissions.entrySet()) {
                interceptUrlRegistry.antMatchers(entry.getKey()).hasAuthority(entry.getValue());
            }
    
            interceptUrlRegistry.anyRequest().authenticated()
            .and()
            ...
            /* rest of the configuration */
        }
    }

Dejar respuesta

Please enter your comment!
Please enter your name here