Announcement Announcement Module
Collapse
No announcement yet.
Pre-authentication and Secured Annotations Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Pre-authentication and Secured Annotations

    I followed the sample code in the preauth demo to successfully create a custom token-based authentication filter, with a UserDetailsService which pulls ROLEs from our own user authorization database.

    However, when I tried to add @Secured annotations or JSR250 annotations to my service methods, I found that they were ignored. I tried adding the global-method-security tag to my app-security.xml, along with whatever annotation-based config pieces I could find, but to no avail. If I manually specify a required ROLE in the interceptor, it works fine, but no roles specified in annotations are enforced.

    Could someone please help me figure out how to mix the preauth demo with global-method-security, and maybe in the process simplify my app-security.xml to just what's needed? Here's what I have now:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:sec="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    						http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
    						http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
    
    	<context:annotation-config />
    	<context:component-scan base-package="com.masergy.rest" />
    
    
    	<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
    		<sec:filter-chain-map path-type="ant">
    			<sec:filter-chain pattern="/**"
    				filters="sif,tokenPreAuthFilter,logoutFilter,etf,fsi" />
    		</sec:filter-chain-map>
    	</bean>
    
    	<bean id="sif"
    		class="org.springframework.security.web.context.SecurityContextPersistenceFilter" />
    
    	<sec:authentication-manager alias="authenticationManager">
    		<sec:authentication-provider ref='preAuthenticatedAuthenticationProvider' />
    	</sec:authentication-manager>
    
    	<bean id="preAuthenticatedAuthenticationProvider"
    		class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
    		<property name="preAuthenticatedUserDetailsService" ref="authenUserDetailsService" />
    	</bean>
    
    	<bean id="authenUserDetailsService"
    		class="com.masergy.authen.client.spring.AuthenUserDetailsService" />
    
    	<bean id="tokenPreAuthFilter" class="com.masergy.authen.client.spring.TokenPreAuthFilter">
    		<property name="authenticationManager" ref="authenticationManager" />
    	</bean>
    
    	<bean id="preAuthenticatedProcessingFilterEntryPoint"
    		class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />
    
    	<bean id="logoutFilter"
    		class="org.springframework.security.web.authentication.logout.LogoutFilter">
    		<constructor-arg value="/" />
    		<constructor-arg>
    			<list>
    				<bean
    					class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
    			</list>
    		</constructor-arg>
    	</bean>
    
    	<bean id="servletContext"
    		class="org.springframework.web.context.support.ServletContextFactoryBean" />
    
    	<bean id="etf"
    		class="org.springframework.security.web.access.ExceptionTranslationFilter">
    		<property name="authenticationEntryPoint" ref="preAuthenticatedProcessingFilterEntryPoint" />
    	</bean>
    
    	<bean id="httpRequestAccessDecisionManager"
    		class="org.springframework.security.access.vote.AffirmativeBased">
    		<property name="allowIfAllAbstainDecisions" value="false" />
    		<property name="decisionVoters">
    			<list>
    				<ref bean="roleVoter" />
    				<ref bean="jsr250Voter" />
    			</list>
    		</property>
    	</bean>
    
    	<bean id="fsi"
    		class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
    		<property name="authenticationManager" ref="authenticationManager" />
    		<property name="accessDecisionManager" ref="httpRequestAccessDecisionManager" />
    		<property name="securityMetadataSource">
    			<sec:filter-security-metadata-source>
    				<sec:intercept-url pattern="/rest/**" />
    			</sec:filter-security-metadata-source>
    		</property>
    	</bean>
    
    
    	<sec:global-method-security
    		secured-annotations="enabled" jsr250-annotations="enabled" />
    	<bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter" />
    	<bean id="jsr250Voter"
    		class="org.springframework.security.access.annotation.Jsr250Voter" />
    	<bean id="securityContextHolderAwareRequestFilter"
    		class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter" />
    
    </beans>

  • #2
    I appreciate how late this reply is, but as I came across it trying to solve the same issue I thought I'd report how I managed to get this to work.

    When using method based security you don't need the FilterSecurityInterceptor in the filter stack as this will perform filtering on the url before the servlet is hit. Therefore you need to remove this from your xml and retain the sec:global-method-security declaration. Method based security is applied using AOP and therefore you need to allow calls to pass through the servlet filter stack into the dispatcher servlet in order for them to be invoked.

    I've corrected the XML below to show how I think it should work in your case.

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:sec="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    						http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
    						http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
    
    	<context:annotation-config />
    	<context:component-scan base-package="com.masergy.rest" />
    
    
    	<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
    		<sec:filter-chain-map path-type="ant">
    			<sec:filter-chain pattern="/**"
    				filters="sif,tokenPreAuthFilter,logoutFilter,etf" />
    		</sec:filter-chain-map>
    	</bean>
    
    	<bean id="sif"
    		class="org.springframework.security.web.context.SecurityContextPersistenceFilter" />
    
    	<sec:authentication-manager alias="authenticationManager">
    		<sec:authentication-provider ref='preAuthenticatedAuthenticationProvider' />
    	</sec:authentication-manager>
    
    	<bean id="preAuthenticatedAuthenticationProvider"
    		class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
    		<property name="preAuthenticatedUserDetailsService" ref="authenUserDetailsService" />
    	</bean>
    
    	<bean id="authenUserDetailsService"
    		class="com.masergy.authen.client.spring.AuthenUserDetailsService" />
    
    	<bean id="tokenPreAuthFilter" class="com.masergy.authen.client.spring.TokenPreAuthFilter">
    		<property name="authenticationManager" ref="authenticationManager" />
    	</bean>
    
    	<bean id="preAuthenticatedProcessingFilterEntryPoint"
    		class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />
    
    	<bean id="logoutFilter"
    		class="org.springframework.security.web.authentication.logout.LogoutFilter">
    		<constructor-arg value="/" />
    		<constructor-arg>
    			<list>
    				<bean
    					class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
    			</list>
    		</constructor-arg>
    	</bean>
    
    	<bean id="servletContext"
    		class="org.springframework.web.context.support.ServletContextFactoryBean" />
    
    	<bean id="etf"
    		class="org.springframework.security.web.access.ExceptionTranslationFilter">
    		<property name="authenticationEntryPoint" ref="preAuthenticatedProcessingFilterEntryPoint" />
    	</bean>
    
    
    	<sec:global-method-security
    		secured-annotations="enabled" jsr250-annotations="enabled" />
    
    
    </beans>

    Comment

    Working...
    X