2013-03-15 13 views
5

Stiamo usando la sicurezza a molla per autenticare l'utente sulla base di alcuni dati utente (come userid) provenienti da applicazioni esterne ed eseguire l'autorizzazione con il titolare contesto di protezione. Stiamo utilizzando l'implementazione personalizzata di AbstractAuthenticationProcessingFilter e l'implementazione personalizzata di CustomAuthenticationProvider con il nostro UserDetailsServiceImpl inserito nel provider per il recupero dei dettagli dell'utente da db.Autenticazione tramite personalizzati AbstractAuthenticationProcessingFilter e CustomAuthenticationProvider personalizzato non funziona propertly

Quando un singolo utente tenta di accedere funziona correttamente, l'oggetto di autenticazione viene creato e correttamente impostato in SecurityCOntextHolder. Ma quando un altro utente tenta di accedere ai vecchi oggetti di autenticazione viene sovrascritto da uno nuovo. Sembra che la nuova sessione non venga creata per ogni accesso utente.

L'implementazione per il filtro e il provider è come qui sotto -

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); 
} 
    } 

L'implementazione del provider personalizzato è come sotto -

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; 
} 
} 

Abbiamo configura anche gestore successo di autenticazione personalizzato per reindirizzare utenti all'URL appropriato dopo l'autenticazione -

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); 

} 
    } 

Il file di protezione di primavera di configurazione è come qui di seguito -

<?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> 

Abbiamo anche configurato 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> 

Stiamo usando primavera 3.1.3 e la primavera di sicurezza 3.1.3 On ogni login utente deve essere creato una nuova sessione e il contesto di sicurezza deve essere impostato di conseguenza. Ma sta accadendo nel mio caso. Ho controllato debuggin della mia applicazione e ho scoperto che la nuova sessione non viene creata sul login dell'utente. Potrebbe essere che mi manca da qualche parte. Non trovo nessuna soluzione rilevante da nessuna parte.

Qualsiasi aiuto in questo senso sarà apprezzato di più.

Grazie.

+0

fisso questo è citare utilizzando – Ekanath

+4

come? Per favore aggiungi la tua risposta. –

+1

@Ebanath, ti aspettavi che altre persone ti aiutassero, ma non hai condiviso una correzione, perché? –

risposta

1

Scusate ragazzi, non ho guardato la questione per lungo tempo se avevo risolto questo problema allora e che il tempo stesso -

ho usato securityContextPersistenceFilter all'interno dell'elemento e configurato come di seguito -

<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

ho requisiti simili, per favore date un'occhiata al mio problema http://stackoverflow.com/questions/34269682/spring-security-handling-sso-and-db-users – sumedha

Problemi correlati