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.
fisso questo è citare utilizzando – Ekanath
come? Per favore aggiungi la tua risposta. –
@Ebanath, ti aspettavi che altre persone ti aiutassero, ma non hai condiviso una correzione, perché? –