Question

I am using Spring framework with Security in my web application. I have a Guest user and its privileges in my db but I can't implement AnonymousAuthenticationFilter and AnonymousAuthenticationProvider to use that user. Here is my appSecurity configuration:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:security="http://www.springframework.org/schema/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-3.2.xsd">

    <bean id="loginUrlAuthenticationEntryPoint" 
        class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint" 
        p:loginFormUrl="/login" p:useForward="false" p:forceHttps="false" />

    <bean id="successHandler"
        class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"
        p:defaultTargetUrl="/" />

    <bean id="failureHandler"
        class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"
        p:defaultFailureUrl="/login?error=true" p:useForward="false" />

    <bean id="accessDeniedHandler"
        class="com.asosyalbebe.springtest.gui.user.security.CustomAccessDeniedHandler">
        <property name="accessDeniedUrl" value="/accessDenied" />
    </bean>

    <bean id="userDetailsService"
        class="com.asosyalbebe.springtest.gui.user.service.UserServiceImpl" />

    <bean id="tokenBasedRememberMeServices"
        class="com.asosyalbebe.springtest.gui.user.security.CustomRememberMeServices">
        <property name="alwaysRemember" value="true" />
        <property name="key" value="abcdef123456" />
        <property name="parameter" value="remember" />
        <property name="cookieName" value="_ab_memo" />
        <property name="userDetailsService" ref="userDetailsService" />
    </bean>

    <bean id="authenticationProcessingFilter"
        class="com.asosyalbebe.springtest.gui.user.security.AuthenticationProcessingFilter">
        <property name="filterProcessesUrl" value="/j_spring_security_check" />
        <property name="authenticationManager" ref="authenticationManager" />
        <property name="postOnly" value="true" />
        <property name="authenticationSuccessHandler" ref="successHandler" />
        <property name="authenticationFailureHandler" ref="failureHandler" />
        <property name="rememberMeServices" ref="tokenBasedRememberMeServices" />
    </bean>

    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider
            ref="anonymousAuthProvider" />
        <security:authentication-provider
            ref="rememberMeAuthProvider" />
        <security:authentication-provider
            ref="customAuthenticationProvider" />
    </security:authentication-manager>

    <bean id="anonymousAuthProvider" class="com.asosyalbebe.springtest.gui.user.security.CustomAnonymousAuthProvider">
        <property name="userDetailsService" ref="userDetailsService" />
        <property name="key" value="foobar" />
    </bean>

    <bean name="rememberMeAuthProvider"
        class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
        <property name="key" value="xy1245aazpo98qwe" />
    </bean>

    <bean id="customAuthenticationProvider"
        class="com.asosyalbebe.springtest.gui.user.security.UserAuthenticationProvider">
        <property name="userDetailsService" ref="userDetailsService" />
    </bean>

    <bean id="securityContextPersistenceFilter"
        class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
        <property name='securityContextRepository'>
            <bean
                class='org.springframework.security.web.context.HttpSessionSecurityContextRepository'>
                <property name='allowSessionCreation' value='false' />
            </bean>
        </property>
    </bean>

    <bean id="customLogoutSuccessHandler" class="com.asosyalbebe.springtest.gui.user.security.CustomLogoutSuccessHandler" />

    <bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
        <constructor-arg ref="customLogoutSuccessHandler" />
        <constructor-arg>
            <list>
                <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
                <ref bean="tokenBasedRememberMeServices"/> 
            </list>
        </constructor-arg>
    </bean>

    <bean name="rememberMeAuthenticationFilter" class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
        <property name="authenticationManager" ref="authenticationManager" />
        <property name="rememberMeServices" ref="tokenBasedRememberMeServices" />
    </bean>

    <bean id="anonymousProcessingFilter" class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
        <property name="key" value="foobar" />
        <property name="userAttribute" value="anonymousUser,PRIV_ANONYMOUS" />
    </bean>

    <bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter">
        <property name="authenticationEntryPoint" ref="loginUrlAuthenticationEntryPoint" />
        <property name="accessDeniedHandler" ref="accessDeniedHandler"/>
    </bean>

    <bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter">
        <property name="rolePrefix" value="PRIV_"/>
    </bean>

    <bean id="accessDecisionManager" class="com.asosyalbebe.springtest.gui.user.security.CustomAccessDecisionManager">
        <property name="allowIfAllAbstainDecisions" value="false" />
        <property name="decisionVoters">
            <list>
                <ref bean="roleVoter" />
            </list>
        </property>
    </bean>

    <bean id="securityMetadataSource" class="com.asosyalbebe.springtest.gui.user.security.CustomFilterInvocationDefinitionSource"/>

    <bean id="filterInvocationInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
        <property name="authenticationManager" ref="authenticationManager" />
        <property name="accessDecisionManager" ref="accessDecisionManager" />
        <property name="securityMetadataSource" ref="securityMetadataSource" />
        <property name="rejectPublicInvocations" value="false"/>
    </bean>

    <bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
        <security:filter-chain-map path-type="ant">
            <security:filter-chain pattern="/**"
                filters="securityContextPersistenceFilter,
                logoutFilter,
                authenticationProcessingFilter,
                rememberMeAuthenticationFilter,
                anonymousProcessingFilter,
                exceptionTranslationFilter,
                filterInvocationInterceptor" />
        </security:filter-chain-map>
    </bean>
</beans>

And here is my Custom Anonymous Authentication Provider:

package com.asosyalbebe.springtest.gui.user.security;

import org.springframework.security.authentication.AnonymousAuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

import com.asosyalbebe.springtest.gui.user.model.GuiUser;
import com.asosyalbebe.springtest.gui.user.service.UserService;

@SuppressWarnings("deprecation")
public class CustomAnonymousAuthProvider extends AnonymousAuthenticationProvider {
    private UserService userDetailsService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        GuiUser user = userDetailsService.getGuestUser();

        UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(user, "pwd", user.getAuthorities());
        result.setDetails(user);

        return result;
    }

    @Override
    public boolean supports(Class<?> class1) {
        return true;
    }

    public void setUserDetailsService(UserService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }
}

I think the authenticate method in CustomAnonymousAuthProvider is never executed. What else can I do?

Was it helpful?

Solution

From the AuthenticationManager's perspective, the AnonymousAuthenticationToken which is created by then filter is already authenticated (the isAuthenticated property is true), so it doesn't try to authenticate it. Hence your provider is not called.

The simplest option would be to customize the AnonymousAuthenticationFilter to use the authorities from your database directly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top