2013-03-15 16 views
5

Wir verwenden Spring-Sicherheit, um den Benutzer basierend auf einigen Benutzerdetails (wie Benutzer-ID) aus externer Anwendung zu authentifizieren und die Autorisierung mit dem Sicherheitskontexthalter durchzuführen. Wir verwenden die benutzerdefinierte Implementierung von AbstractAuthenticationProcessingFilter und die benutzerdefinierte Implementierung von CustomAuthenticationProvider mit unserer eigenen UserDetailsServiceImpl, die in den Provider zum Abrufen von Benutzerdetails aus db eingefügt wird.Authentifizierung mit benutzerdefiniertem AbstractAuthenticationProcessingFilter und benutzerdefiniertem CustomAuthenticationProvider funktioniert nicht propertly

Wenn ein einzelner Benutzer versucht, sich anzumelden, funktioniert es einwandfrei, das Authentifizierungsobjekt wird erstellt und es wird ordnungsgemäß in SecurityCOntextHolder festgelegt. Wenn jedoch ein anderer Benutzer sich anmeldet, werden die alten Authentifizierungsobjekte durch ein neues überschrieben. Offenbar wird bei jeder Benutzeranmeldung keine neue Sitzung erstellt.

Die Implementierung für den Filter und Anbieter wie unten ist -

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

Die Implementierung von benutzerdefinierten Anbieter als unten -

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

Wir haben auch benutzerdefinierte Authentifizierung Erfolg Handler konfiguriert Benutzer umleiten zur entsprechenden URL bei der Authentifizierung -

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

} 
    } 

Die Federsicherheitskonfigurationsdatei ist wie unten -

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

Wir auch 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> 

konfiguriert haben wir mit Feder 3.1.3 und Feder Sicherheit 3.1.3 On Für jede Benutzeranmeldung sollte eine neue Sitzung erstellt und der Sicherheitskontext entsprechend festgelegt werden. Aber es passiert in meinem Fall. Ich habe debuggin meine Anwendung überprüft und festgestellt, dass neue Sitzung nicht bei der Benutzeranmeldung erstellt wird. Vielleicht vermisse ich es irgendwo. Ich finde nirgendwo eine relevante Lösung.

Jede Hilfe in dieser Hinsicht wird am meisten geschätzt werden.

Danke.

+0

Fest dies ist verklagen mit – Ekanath

+4

wie? Bitte fügen Sie Ihre Antwort hinzu. –

+1

@Ebanath, du hast erwartet, dass andere Leute dir helfen, aber keine Lösung teilen, warum? –

Antwort

1

Sorry Leute, ich habe nicht für eine lange Zeit auf die Frage suchen, obwohl ich dieses Problem dann gelöst hatte und dass die Zeit selbst -

I verwendet securityContextPersistenceFilter innerhalb des Elements und konfiguriert, wie unten -

<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

Ich habe ähnliche Anforderungen können Sie bitte ein Blick auf mein Problem http://StackOverflow.com/Questions/34269682/spring-Security-Handling-SSo-and-db-users – sumedha

Verwandte Themen