2015-05-06 62 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文件有關。 –

相關問題