How to use custom filter with authentication-success-handler-ref equivalent in spring security

后端 未结 1 1521
伪装坚强ぢ
伪装坚强ぢ 2021-01-24 14:35

I want to pass some parameters with login details to spring security such as some item id. then after i want to redirect to page according to the user type. For this i am using

相关标签:
1条回答
  • 2021-01-24 15:12

    I understood your question as follows: I want to submit an itemId in the form login which is used after a successful login for redirection.

    In order to establish such a process you need to do following things.

    Remove <form-login ...> from your configuration. You should have:

    <http use-expressions="true" entry-point-ref="authenticationEntryPoint">
        <intercept-url pattern="/login" access="permitAll" />
        <intercept-url pattern="/resources/**" access="permitAll" />
        <intercept-url pattern="/logout" access="permitAll" />
        <intercept-url pattern="/accessdenied" access="permitAll" />
    
        <custom-filter ref="ddAuthenticationFilter" position="FORM_LOGIN_FILTER" />
        <security:logout />
    </http>
    

    Don't forget to add a <security:logout /> for logout and the entry-point-ref attribute points to an authenticationEntryPoint.

    Add a LoginUrlAuthenticationEntryPoint for entry-point-ref which points to your login page:

    <bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
        <constructor-arg name="loginFormUrl" value="/login" />
    </bean>
    

    Refactor your ddAuthenticationFilter to meet the following configuration:

    <bean id="ddAuthenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
        <property name="authenticationManager" ref="authenticationManager" />
        <property name="filterProcessesUrl" value="/j_spring_security_check" />
        <property name="authenticationFailureHandler" ref="authenticationFailureHandler" />
        <property name="authenticationSuccessHandler" ref="ddAuthenticationSuccessHandler" />
        <property name="authenticationDetailsSource">
            <bean class="security.CustomWebAuthenticationDetailsSource" />
        </property>
    </bean>
    
    <bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
        <property name="defaultFailureUrl" value="/accessdenied" />
    </bean>
    

    Create a new class CustomWebAuthenticationDetailsSource:

    package security;
    
    import org.springframework.security.authentication.AuthenticationDetailsSource;
    import org.springframework.security.web.authentication.WebAuthenticationDetails;
    
    import javax.servlet.http.HttpServletRequest;
    
    public class CustomWebAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> {
        @Override
        public WebAuthenticationDetails buildDetails(HttpServletRequest context) {
            return new CustomWebAuthenticationDetails(context);
        }
    }
    

    and the related CustomWebAuthenticationDetails:

    package security;
    
    import org.springframework.security.web.authentication.WebAuthenticationDetails;
    import javax.servlet.http.HttpServletRequest;
    
    public class CustomWebAuthenticationDetails extends WebAuthenticationDetails {
    
        private final String itemId;
    
        public CustomWebAuthenticationDetails(HttpServletRequest request) {
            super(request);
            itemId = request.getParameter("itemId");
        }
    
        public String getItemId() {
            return itemId;
        }
    
        //TODO override hashCode, equals and toString to include itemId
        @Override
        public int hashCode() { /* collapsed */ }
        @Override
        public boolean equals(Object obj) { /* collapsed */ }
        @Override
        public String toString() { /* collapsed */ }
    }
    

    Your ddAuthenticationSuccessHandler should have a similiar logic like in this example:

    package com.dd.security;
    
    import org.springframework.security.core.Authentication;
    import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
    import org.springframework.util.StringUtils;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class DDAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    
        @Override
        public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
            CustomWebAuthenticationDetails details = (CustomWebAuthenticationDetails) authentication.getDetails();
            if(StringUtils.hasText(details.getItemId())) {
                //TODO sanity and security check for itemId needed
                String redirectUrl = "item/" + details.getItemId();
                response.sendRedirect(redirectUrl);
            }
            throw new IllegalStateException("itemId in authentication details not found");
        }
    }
    

    A working example can be found here

    0 讨论(0)
提交回复
热议问题