2015-05-06 37 views
0

目前,我遇到了Spring Security的问题,因为当我打开两个选项卡并在一个选项卡中注销时,会话肯定会被销毁,但我可以仍然在另一个选项卡上进行一些操作,这应该会将我重定向到登录页面,而不是让我进行任何其他操作。使用Spring Security在一个选项卡中注销后将所有选项卡重定向到登录页面

直到我刷新页面,它将重定向到登录页面,因为没有有效的会话了。

我试图找到一种解决方案,强制其他选项卡重定向到注销页面,而不让用户在其他选项卡中注销时执行任何其他操作。

不知我们是否可以用Spring Security配置来实现这样的事情?

下面是我弹簧security.xml文件

<!-- Secure token end point --> 
<http pattern="/api/oauth/token" create-session="stateless" 
    authentication-manager-ref="clientAuthenticationManager" 
    xmlns="http://www.springframework.org/schema/security"> 
    <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" /> 
    <anonymous enabled="false" /> 
    <http-basic entry-point-ref="clientAuthenticationEntryPoint" /> 
    <custom-filter ref="clientCredentialsTokenEndpointFilter" 
     before="BASIC_AUTH_FILTER" /> 
    <access-denied-handler ref="oauthAccessDeniedHandler" /> 
</http> 

<!-- secure api service --> 
<http pattern="/api/service/**" create-session="never" 
    entry-point-ref="oauthAuthenticationEntryPoint" xmlns="http://www.springframework.org/schema/security"> 
    <anonymous enabled="false" /> 
    <intercept-url pattern="/api/service/**" method="GET" 
     access="IS_AUTHENTICATED_FULLY" /> 
    <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" /> 
    <access-denied-handler ref="oauthAccessDeniedHandler" /> 
</http> 


<http auto-config="true" use-expressions="true" 
    xmlns="http://www.springframework.org/schema/security" 
    authentication-manager-ref="userAuthenticationManager"> 

    <access-denied-handler error-page="/accessDenied" /> 
    <intercept-url pattern="/home/**" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_HR')" /> 
    <intercept-url pattern="/index" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_HR')" /> 
    <intercept-url pattern="/pages/**" access="hasRole('ROLE_ADMIN')" /> 
    <intercept-url pattern="/overviewOfferLetter" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_MANAGER') or hasRole('ROLE_HR')"/> 
    <intercept-url pattern="/importOldCandidate" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_HR')"/> 
    <intercept-url pattern="/RecruitmentEvent" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_HR')"/> 
    <intercept-url pattern="/questionnaireResultId**" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_INTERVIEWER')"/> 
    <intercept-url pattern="/evaluation**" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_INTERVIEWER')"/> 
    <intercept-url pattern="/questionnaireResult" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_CV_SCREENER') or hasRole('ROLE_MANAGER')"/> 
    <intercept-url pattern="/activityLogs" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_HR')"/> 
    <intercept-url pattern="/oldCandidate" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_HR')"/> 
    <intercept-url pattern="/advancedSearch" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_HR')"/> 
    <intercept-url pattern="/listApplicants" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_HR')"/> 
    <intercept-url pattern="/duplicatedEmail" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_HR')"/> 
    <intercept-url pattern="/createApplicant" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_HR')"/> 
    <intercept-url pattern="/jobHistory" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_HR')" /> 
    <intercept-url pattern="/importOldCandidate" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_HR')" /> 
    <intercept-url pattern="/oldCandidate" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_HR')" /> 
    <intercept-url pattern="/importApplicant" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_HR')" /> 
    <form-login login-page="/login" 
     default-target-url="/index" 
     always-use-default-target="true" 
     authentication-failure-url="/login?error=incorrect" 
     authentication-success-handler-ref="customAuthenticationSuccessHandler" 
     username-parameter="username" 
     password-parameter="password" 
     /> 

    <logout logout-success-url="/login?logout" delete-cookies="JSESSIONID" /> 
</http> 

<bean id="customAuthenticationSuccessHandler" class="com.axonactive.security.CustomAuthenticationSuccessHandler" /> 


<authentication-manager id="userAuthenticationManager" 
    xmlns="http://www.springframework.org/schema/security"> 
    <authentication-provider ref="authenticationProvider"> 
    </authentication-provider> 
</authentication-manager> 

<bean id="authenticationProvider" class="com.axonactive.security.CustomAuthenticationProvider"></bean> 

<global-method-security secured-annotations="enabled" 
    pre-post-annotations="enabled" proxy-target-class="true" 
    xmlns="http://www.springframework.org/schema/security"> 
    <expression-handler ref="expressionHandler" /> 
</global-method-security> 

<bean id="expressionHandler" 
    class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler"> 
    <property name="permissionEvaluator"> 
     <bean id="permissionEvaluator" class="com.axonactive.security.AccountPermissionEvaluator" /> 
    </property> 
</bean> 


<bean id="webExpressionHandler" 
    class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"> 
    <property name="permissionEvaluator"> 
     <bean id="permissionEvaluator" class="com.axonactive.security.AccountPermissionEvaluator" /> 
    </property> 
</bean> 

<!-- Define LDAP Service --> 
<bean id="ldapService" class="com.axonactive.service.implement.LdapService"> 
    <property name="contextFactory" value="${ldap.contextFactory}" /> 
    <property name="url" value="${ldap.url}" /> 
    <property name="securityAuthentication" value="${ldap.securityAuthentication}" /> 
    <property name="username" value="${ldap.username}" /> 
    <property name="password" value="${ldap.password}" /> 
    <property name="searchBase" value="${ldap.searchBase}" /> 
    <property name="searchName" value="${ldap.searchName}" /> 
    <property name="distinguishedName" value="${ldap.distinguishedName}" /> 
</bean> 
<!-- End LDAP Service --> 

<bean id="oauthAuthenticationEntryPoint" 
    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"> 
</bean> 

<bean id="clientAuthenticationEntryPoint" 
    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"> 
    <property name="realmName" value="springsec/client" /> 
    <property name="typeName" value="Basic" /> 
</bean> 

<bean id="oauthAccessDeniedHandler" 
    class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler"> 
</bean> 

<!-- End point filter for client --> 
<bean id="clientCredentialsTokenEndpointFilter" 
    class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter"> 
    <property name="authenticationManager" ref="clientAuthenticationManager" /> 
</bean> 

<!-- Client credential authentication manager --> 
<authentication-manager alias="clientAuthenticationManager" 
    xmlns="http://www.springframework.org/schema/security"> 
    <authentication-provider user-service-ref="clientDetailsUserService" /> 
</authentication-manager> 

<!-- Declare client service --> 
<bean id="clientDetailsUserService" 
    class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService"> 
    <constructor-arg ref="clientDetailsService" /> 
</bean> 


<!-- Declare client list --> 
<oauth:client-details-service id="clientDetailsService"> 
    <oauth:client client-id="testSystem" 
     secret="9346336818f9d382a22ac5d4486fa5ee" scope="read" 
     authorized-grant-types="client_credentials" /> 
</oauth:client-details-service> 


<!-- Config oauth server --> 
<oauth:authorization-server 
    client-details-service-ref="clientDetailsService" token-services-ref="tokenServices"> 
    <oauth:client-credentials /> 
</oauth:authorization-server> 

<!-- Declare resource server, where the token token are store --> 
<oauth:resource-server id="resourceServerFilter" 
    resource-id="springsec" token-services-ref="tokenServices" /> 

<!-- Store token in memory --> 
<bean id="tokenStore" 
    class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore"> 
    <constructor-arg ref="dataSource" /> 
</bean> 

<!-- Configuration token service , expire in one day, don't support refresh 
    token --> 
<bean id="tokenServices" 
    class="org.springframework.security.oauth2.provider.token.DefaultTokenServices"> 
    <property name="tokenStore" ref="tokenStore" /> 
    <property name="supportRefreshToken" value="false" /> 
    <property name="accessTokenValiditySeconds" value="86400"></property> 
    <property name="clientDetailsService" ref="clientDetailsService" /> 
</bean> 

如果有任何其他文件或信息,你们需要看到,请告诉我。

+0

您的客户端代码将不得不主动检查会话是否仍然活着,如果不是,则重定向到登录; Spring Security与它无关。 – kryger

+0

正如您所说,我必须在任何操作之前检查会话是否仍然存在? –

回答

0

正如@ kryger所说,您的客户端代码需要检查您的会话是否仍然通过身份验证。我们的客户端应用程序有类似的问题,因为Spring想要重定向未经授权的请求,但是我们的客户端应用程序正在以“休息”方式与我们的服务器进行通信,所以客户端应用程序只是向最终用户失败。

我们通过第二个AuthenticationEntryPoint来解决此问题,具体来说就是Http403ForbiddenEntryPoint。通过使用Http403ForbiddenEntryPoint.html,我们的客户端应用程序发出的所有未经授权的请求都会与传统的Spring安全重定向相比发生HTTP 403错误。然后,我们的客户端应用程序配置了一个拦截器来侦听任何403错误并提示用户登录。

下面是一个示例Spring Security配置,使用WebSecurityConfigurerAdapter配置中的Http403ForbiddenEntryPoint。

/** 
* Configures all the AuthenticationEntryPoints for our app 
*/ 
protected DelegatingAuthenticationEntryPoint delegatingAuthenticationEntryPoint() { 
    LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPoints = 
     new LinkedHashMap<RequestMatcher, AuthenticationEntryPoint>(); 
    // entry point for unauthenticated client apps 
    entryPoints.put(new SecuredApiRequestMatcher(), new Http403ForbiddenEntryPoint()); 

    // entry point for our normal website 
    DelegatingAuthenticationEntryPoint delegatingEntryPoint = 
     new DelegatingAuthenticationEntryPoint(entryPoints); 
    delegatingEntryPoint.setDefaultEntryPoint(new LoginUrlAuthenticationEntryPoint(SIGNIN_URL)); 

    return delegatingEntryPoint; 
} 


/** 
* {@link RequestMatcher} that checks if requested url matches a secured api path. 
*/ 
final class SecuredApiRequestMatcher implements RequestMatcher { 
    final Map<String, String[]> securedMethodToUrlMap; 

    public SecuredApiRequestMatcher() { 
     securedMethodToUrlMap = new HashMap<String, String[]>(); 
     securedMethodToUrlMap.put(GET.name(), SECURED_GET_URLS); 
     securedMethodToUrlMap.put(PUT.name(), SECURED_PUT_URLS); 
     securedMethodToUrlMap.put(POST.name(), SECURED_POST_URLS); 
     securedMethodToUrlMap.put(DELETE.name(), SECURED_DELETE_URLS); 
    } 

    @Override 
    public boolean matches(HttpServletRequest request) { 
     String url = UrlUtils.buildRequestUrl(request); 
     String method = request.getMethod(); 
     String[] securedUrls = securedMethodToUrlMap.get(method); 
     if(securedUrls != null) { 
      for(String securedUrl : securedUrls) { 
       if(url.startsWith(securedUrl)) 
        return true; 
      } 
     } 
     return false; 
    } 
} 

最后,这里是一个从Http403ForbiddenEntryPoint

{ “时间戳” 回应:1430938979916, “状态”:403, “错误”: “禁止”, “消息”:“访问被拒绝 “,”path“:”/ api/secured/url“}

+0

目前,我不管理Java字节码的任何配置,现在我的每个配置都在xml文件中。 那么你有没有任何其他选择与xml文件有关。 –

相关问题