您可以实现自己的 Custom AuthenticationManager和 Custom UsernamePasswordAuthenticationFilter。这是一个简单的示例,但它也可以为您的信息提供一个想法,这是安全上下文中非常敏感的部分:)
只需在 spring_security.xml 中创建 bean:
<http entry-point-ref="authenticationProcessingFilterEntryPoint"
        use-expressions="true">
        <custom-filter ref="sessionManagementFilter" before="SESSION_MANAGEMENT_FILTER" />
        <custom-filter ref="customUsernamePasswordAuthenticationFilter"
            position="FORM_LOGIN_FILTER" />
        <session-management
            session-authentication-strategy-ref="sas"></session-management>
    </http>
    <beans:bean id="authenticationProcessingFilterEntryPoint"
            class="org.springframework.security.web.authentication.AuthenticationProcessingFilterEntryPoint">
            <beans:property name="loginFormUrl" value="/login" />
        </beans:bean>
        <beans:bean id="sas"
            class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy" />
        <beans:bean id="customAuthenticationManager"
            class="my.package.security.CustomAuthenticationManager" />
        <beans:bean id="customUsernamePasswordAuthenticationFilter"
            class="my.package.security.CustomUsernamePasswordAuthenticationFilter">
            <beans:property name="sessionAuthenticationStrategy"
                ref="sas" />
            <beans:property name="authenticationManager" ref="customAuthenticationManager" />
            <beans:property name="authenticationSuccessHandler">
                <beans:bean
                    class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
                    <beans:property name="defaultTargetUrl" value="/main.xhtml" />
                </beans:bean>
            </beans:property>
            <beans:property name="authenticationFailureHandler">
                <beans:bean
                    class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
                    <beans:property name="defaultFailureUrl" value="/login.xhtml" />
                </beans:bean>
            </beans:property>
        </beans:bean>
<beans:bean id="sessionManagementFilter"
        class="org.springframework.security.web.session.SessionManagementFilter">
        <beans:constructor-arg name="securityContextRepository"
            ref="httpSessionSecurityContextRepository" />
    </beans:bean>
    <beans:bean id="httpSessionSecurityContextRepository"
        class="org.springframework.security.web.context.HttpSessionSecurityContextRepository" />
当您实现 CustomUsernamePasswordAuthenticationFilter 覆盖 Authentication 并添加您的外部逻辑时:
public final class CustomUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
@Override
    public Authentication attemptAuthentication(HttpServletRequest request,   HttpServletResponse response){
CustomAuthentication auth = new CustomAuthentication();
            // set details of current user
            auth.setDetails(new WebAuthenticationDetails(request));
            auth.setAuthenticated(true);
            auth.setUserName(username);
            // set authentication to current security session
            LOGGER.info("Setting authentication into existing security context");
            SecurityContextHolder.getContext().setAuthentication(auth);
            // if validation done return generated authentication
            return auth;
}
}
然后生成的身份验证对象将由身份验证管理器处理:
public final class CustomAuthenticationManager implements AuthenticationManager {
    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.security.authentication.AuthenticationManager#
     * authenticate(org.springframework.security.core.Authentication)
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(CustomUsernamePasswordAuthenticationFilter.class);
    private final BadCredentialsException badCredentialsException = new BadCredentialsException("Invalid username/password");
    @Override
    public Authentication authenticate(Authentication authentication) {
        //check if user has valid authentication
        if (authentication == null) {
            LOGGER.debug("Null authentication");
            throw badCredentialsException;
        }
        //Check mandatory fields
        if (!Validator.isValidString((String) authentication.getPrincipal()) || !Validator.isValidString((String) authentication.getCredentials())) {
            LOGGER.debug("Null/blank username/credential");
            throw badCredentialsException;
        }
        //Check if there is any role assigned into user
        if (authentication.getAuthorities() != null && authentication.getAuthorities().size() < 1) {
            LOGGER.debug("No authority found");
            throw badCredentialsException;
        }
        //Validate role
        //IF ROLE VALIDATION REQUIRED YOU CAN HANDLE IT HERE
        boolean authorityValid = false;
        LOGGER.info("Validating user authentication. Total grantedAuth size: " + authentication.getAuthorities().size());
        for (GrantedAuthority g : authentication.getAuthorities()) {
            if (!authorityValid) {
                //Testing purpose one type role available, when exact roles prepared create enum types
                authorityValid = g.getAuthority().equals("ROLE_LDAP_AUTHENTICATED");
            }
        }
        //if none of role matching to required throw exception
        if(!authorityValid){
            LOGGER.debug("User has authority but none of them matching");
            throw badCredentialsException;
        }
        LOGGER.info("Final validation done returning authentication");
        return authentication;
    }
}
然后,如果需要,您也可以覆盖默认身份验证对象,如果角色动态位于此处是您处理的位置:
public final class CustomAuthentication implements Authentication {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private transient String userName;
        private transient boolean authenticated;
        private transient Object details;
        private static final transient String ROLE = "ROLE_LDAP_AUTHENTICATED";
        /*
         * (non-Javadoc)
         * 
         * @see java.security.Principal#getName()
         */
        @Override
        public String getName() {
            return this.userName; //for dynamic username logic here
        }
     //IF ROLES DYNAMICALLY ALLOCATED ASSIGN IT HERE, HERE IS WHERE YOU READ FROM INTERCEPT URL
        /*
         * (non-Javadoc)
         * 
         * @see org.springframework.security.core.Authentication#getAuthorities()
         */
        @Override
        public Collection<GrantedAuthority> getAuthorities() {
            Collection<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
            auths.add(new GrantedAuthority() {
                /**
                 * 
                 */
                private static final long serialVersionUID = 1L;
                @Override
                public String getAuthority() {
                    if (authenticated) {
                        return ROLE;
                    }
                    return null;
                }
            });
            return auths;
        }
        /*
         * (non-Javadoc)
         * 
         * @see org.springframework.security.core.Authentication#getCredentials()
         */
        @Override
        public Object getCredentials() {
            //TODO: a specific algorithm can be stored
            return userName + " is ldap authenticated user";
        }
        /*
         * (non-Javadoc)
         * 
         * @see org.springframework.security.core.Authentication#getDetails()
         */
        @Override
        public Object getDetails() {
            return this.details;
        }
        /*
         * (non-Javadoc)
         * 
         * @see org.springframework.security.core.Authentication#getPrincipal()
         */
        @Override
        public Object getPrincipal() {
            return userName;
        }
        /*
         * (non-Javadoc)
         * 
         * @see org.springframework.security.core.Authentication#isAuthenticated()
         */
        @Override
        public boolean isAuthenticated() {
            return this.authenticated;
        }
        /*
         * (non-Javadoc)
         * 
         * @see
         * org.springframework.security.core.Authentication#setAuthenticated(boolean
         * )
         */
        @Override
        public void setAuthenticated(boolean arg0) {
            this.authenticated = arg0;
        }
        public String getUserName() {
            return userName;
        }
        public void setUserName(String userName) {
            this.userName = userName;
        }
        public void setDetails(Object details) {
            this.details = details;
        }
    }