2013-03-15 3 views
5

Мы используем весеннюю безопасность для аутентификации пользователя на основе некоторых пользовательских данных (таких как userid), поступающих из внешнего приложения и выполняющих авторизацию с использованием держателя контекста безопасности. Мы используем пользовательскую реализацию AbstractAuthenticationProcessingFilter и пользовательскую реализацию CustomAuthenticationProvider с помощью нашего собственного UserDetailsServiceImpl, внедренного в провайдер, для извлечения данных пользователя из db.Аутентификация с использованием пользовательского AbstractAuthenticationProcessingFilter и пользовательского CustomAuthenticationProvider не работает должным образом

Когда один пользователь пытается войти в систему, он работает нормально, объект аутентификации создан и правильно установлен в SecurityCOntextHolder. Но когда другой пользователь пытается войти в систему, старые объекты аутентификации перезаписываются новым. Похоже, новый сеанс не создается при каждом входе в систему.

Реализация для фильтра и провайдера, как показано ниже -

public class DefaultAuthenticationProcessingFilter extends 
    AbstractAuthenticationProcessingFilter { 

private final static Logger logger = LoggerFactory.getLogger(DefaultAuthenticationProcessingFilter.class); 

private static final String INTERCEPTOR_PROCESS_URL = "/sso/landingpage.action"; 

public DefaultAuthenticationProcessingFilter() { 
    super(INTERCEPTOR_PROCESS_URL); 
} 

public DefaultAuthenticationProcessingFilter(
     String defaultFilterProcessesUrl) { 
    super(defaultFilterProcessesUrl); 
    Assert.notNull(defaultFilterProcessesUrl, "Configuration error :: DefaultFilterProcessesUrl must be specified"); 
} 


/** 
* Method to do authentication of user 
*/ 
@Override 
public Authentication attemptAuthentication(HttpServletRequest request, 
     HttpServletResponse response) throws AuthenticationException, 
     IOException, ServletException { 

    logger.info("Authenticating the user ....."); 

    Authentication authResult = null; 
    try { 

     String eid = request.getParameter("EID"); 

     if(StringUtils.isEmpty(eid)) { 
      throw new PreAuthenticatedCredentialsNotFoundException("EID param not found in request."); 
     } 

     String credentials = "NA"; 
     PreAuthenticatedAuthenticationToken authRequest = new PreAuthenticatedAuthenticationToken(eid, credentials); 
     authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); 
     authResult = getAuthenticationManager().authenticate(authRequest); 
    } catch (AuthenticationException e) { 
     unsuccessfulAuthentication(request, response, e); 
    } 
    return authResult; 
} 
    } 


    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, 
      Authentication authResult) throws IOException, ServletException { 

     if (logger.isDebugEnabled()) { 
      logger.debug("Authentication success. Updating SecurityContextHolder to contain: " + authResult); 
     } 

     SecurityContextHolder.getContext().setAuthentication(authResult); 

     getRememberMeServices().loginSuccess(request, response, authResult); 

     // Fire event 
     if (this.eventPublisher != null) { 
      eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass())); 
     } 

     getSuccessHandler().onAuthenticationSuccess(request, response, authResult); 
} 
    } 

Реализация пользовательского поставщика, как показано ниже -

public class CustomAuthenticationProvider implements AuthenticationProvider, InitializingBean { 

private final static Logger logger = LoggerFactory.getLogger(CustomAuthenticationProvider.class); 

private AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> preAuthenticatedUserDetailsService = null; 
/** 
* 
*/ 
public Authentication authenticate(Authentication authentication) throws AuthenticationException { 

    if (!supports(authentication.getClass())) { 
     return null; 
    } 

    if (logger.isDebugEnabled()) { 
     logger.debug("PreAuthenticated authentication request: " + authentication); 
    } 

    if (authentication.getPrincipal() == null) { 
     logger.debug("No pre-authenticated principal found in request."); 
     return null; 
    } 

    UserDetails ud = preAuthenticatedUserDetailsService.loadUserDetails((PreAuthenticatedAuthenticationToken)authentication); 

    PreAuthenticatedAuthenticationToken result = 
      new PreAuthenticatedAuthenticationToken(ud, authentication.getCredentials(), ud.getAuthorities()); 
    result.setDetails(authentication.getDetails()); 

    return result; 

} 

@Override 
public void afterPropertiesSet() throws Exception { 
    // TODO Auto-generated method stub 
} 

@Override 
public boolean supports(Class<?> authentication) { 
    return PreAuthenticatedAuthenticationToken.class.isAssignableFrom(authentication); 
} 

/** 
* @return the preAuthenticatedUserDetailsService 
*/ 
public AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> getPreAuthenticatedUserDetailsService() { 
    return preAuthenticatedUserDetailsService; 
} 

/** 
* @param preAuthenticatedUserDetailsService the preAuthenticatedUserDetailsService to set 
*/ 
public void setPreAuthenticatedUserDetailsService(
     AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> preAuthenticatedUserDetailsService) { 
    this.preAuthenticatedUserDetailsService = preAuthenticatedUserDetailsService; 
} 
} 

Мы также настраивает обработчик успеха пользовательских аутентификации для перенаправления пользователя к соответствующему URL-адресу после аутентификации -

public class CustomAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { 

/** 
* redirect user to appropriate home page based on user role 
*/ 
@Override 
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException { 

    Set<GrantedAuthority> authorities = ((UserDetails)authentication.getPrincipal()).getAuthorities(); 
    if(CollectionUtils.isNotEmpty(authorities)){ 
     GrantedAuthority role = getHighestRole(authorities); 
     String targetURL = getTargetURL(role); 
     if (targetURL != null) { 
      log.debug("Redirecting to target Url: " + targetURL); 
      getRedirectStrategy().sendRedirect(request, response, targetURL); 
      return; 
     } 
    } 

    super.onAuthenticationSuccess(request, response, authentication); 

} 
    } 

Файл пружинной безопасности конфигурации как ниже -

<?xml version="1.0" encoding="UTF-8"?> 
    <beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:security="http://www.springframework.org/schema/security" 
xsi:schemaLocation="http://www.springframework.org/schema/beans 
         http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
         http://www.springframework.org/schema/security 
         http://www.springframework.org/schema/security/spring-security-3.1.xsd"> 

<security:http use-expressions="true" auto-config="false" pattern="/sso/*" entry-point-ref="http403ForbiddenEntryPoint" access-denied-page="/accessdenied.action" > 
    <security:anonymous enabled="false"/> 
    <security:custom-filter position="BASIC_AUTH_FILTER" ref="defaultBasicAuthFilter" /> 
    <security:expression-handler ref="expressionHandler"/> 
</security:http> 

<security:http use-expressions="true" auto-config="false" pattern="/rcd/associate/*" entry-point-ref="http403ForbiddenEntryPoint" access-denied-page="/accessdenied.action"> 
    <security:intercept-url pattern="/saml/sso/*" access="IS_AUTHENTICATED_ANONYMOUSLY"/> 
     <security:custom-filter position="BASIC_AUTH_FILTER" ref="defaultBasicAuthFilter" /> 
    <security:expression-handler ref="expressionHandler"/> 
</security:http> 

<bean id="http403ForbiddenEntryPoint" 
    class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" /> 


<bean id="expressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"> 
    <property name="permissionEvaluator" ref="customPermissionEvaluator" /> 
</bean> 

<bean id="defaultBasicAuthFilter" 
    class="com.example.security.authentication.DefaultAuthenticationProcessingFilter"> 
    <property name="authenticationManager" ref="authenticationManager" /> 
    <property name="authenticationSuccessHandler" ref="successRedirectHandler"/> 
    <property name="AuthenticationFailureHandler" ref="failureHandler"></property> 
</bean> 

<bean id="authProvider" 
class="com.example.security.authentication.CustomAuthenticationProvider"> 
    <property name="preAuthenticatedUserDetailsService"> 
     <bean id="userDetailsServiceWrapper" 
      class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper"> 
      <property name="userDetailsService" ref="userDetailsService" /> 
     </bean> 
    </property> 
</bean> 

<security:authentication-manager alias="authenticationManager"> 
    <security:authentication-provider 
     ref="authProvider" /> 
</security:authentication-manager> 

<bean id="userDetailsService" class="com.example.security.authorization.UserDetailsServiceImpl" /> 

<bean id="successRedirectHandler" 
     class="com.example.security.authentication.CustomAuthenticationSuccessHandler"> 
     <property name="defaultTargetUrl" value="/user1/user1LandingPage.action"/> 
    </bean> 

<bean id="failureHandler" 
     class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> 
    <property name="defaultFailureUrl" value="/accessdenied.action"/> 
</bean> 

Мы также настроены web.xml

<listener> 
    <listener-class> 
     org.springframework.web.context.ContextLoaderListener 
    </listener-class> 
</listener> 

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value> 
     /WEB-INF/spring/spring-app-context.xml <!-- ,/WEB-INF/spring/security.xml --> 
    </param-value> 
</context-param> 

<servlet> 
    <servlet-name>example-dispatcher-servlet</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/spring/mvc.xml</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

<!-- Map all /example*.action requests to the example-dispatcher-servlet for handling --> 
<servlet-mapping> 
    <servlet-name>example-dispatcher-servlet</servlet-name> 
    <url-pattern>*.action</url-pattern> 
</servlet-mapping> 

<welcome-file-list> 
    <welcome-file>/rcd/pages/index.jsp</welcome-file> 
</welcome-file-list> 

<listener> 
    <listener-class>com.example.HttpSessionListenerImpl</listener-class> 
</listener> 


<!-- Spring Security --> 
<filter> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 

<filter-mapping> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
</web-app> 

Мы используем пружинный 3.1.3 и пружины безопасность 3.1.3 On каждый пользователь должен войти в новый сеанс, и должен быть установлен контекст безопасности. Но это происходит в моем случае. Я проверил debuggin мое приложение и обнаружил, что новый сеанс не создается при входе пользователя. Может быть, я его где-то не хватает. Я нигде не нашел подходящего решения.

Любая помощь в этом отношении будет оценена больше всего.

Спасибо.

+0

Fixed это подать иск, используя – Ekanath

+4

как? Пожалуйста, добавьте свой ответ. –

+1

@Ebanath, вы ожидали, что другие люди помогут вам, но не решили, почему? –

ответ

1

Извините, ребята, я не смотрел на вопрос в течение длительного времени, хотя я решил эту проблему, то и само это время -

Я использовал securityContextPersistenceFilter внутри элемента и сконфигурирован, как показано ниже -

<security:http> 
<security:custom-filter before="SECURITY_CONTEXT_FILTER" ref="securityContextPersistenceFilter"/> 

....

<bean id="securityContextPersistenceFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"> 
    <property name="forceEagerSessionCreation" value="true"></property> 
    <property name="securityContextRepository" ref="httpSessionSecurityContextRepository"/> 
</bean> 

<bean id="httpSessionSecurityContextRepository" class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"> 
<property name="allowSessionCreation" value="false" /> 
</bean> 
+0

У меня есть аналогичное требование, можете ли вы взглянуть на мою проблему http://stackoverflow.com/questions/34269682/spring-security-handling-sso-and-db-users – sumedha