2015-04-06 170 views
7

我對以下幾個方面有疑問:spring-session和spring-security。Spring Session和Spring Security

春季會議

我必須通過基本內存驗證與春季安全保護的應用程序的例子示例中提供。

我看到spring正在創建會話ID,即使身份驗證不成功,也就是說,即使我沒有提供基本身份驗證憑據詳細信息,我在我的響應頭中也看到了x-auth-token。 我們如何避免爲驗證失敗創建會話?

春季安全

需要使用Spring的安全保護資源假設春季會議只針對受保護的資源創建會話。

假設Signin API(/ signin-HTTP Post)根據第三方REST API驗證(用戶名&密碼)憑證。

一旦外部API驗證憑據,如何更新成功驗證的彈簧安全上下文?

需要驗證對x-auth-token的其他安全資源的訪問權限,並且應該提供基於訪問安全資源的信息。

我們是否需要在這種情況下擁有Spring Security?還是我應該使用基本的過濾器和彈簧會話?建議什麼?

回答

11

通常最好將您的問題分解爲多個StackOverflow問題,因爲您更有可能找到知道單個問題的答案的人。

我們如何避免爲驗證失敗創建會話?

默認情況下,Spring Security會將最後一次未經身份驗證的請求保存到會話中,以便在驗證身份之後可以再次自動發出請求。例如,如果您在瀏覽器中請求example.com/a/b/c並且未通過身份驗證,則它會將example.com/a/b/c保存到HttpSession中,然後讓用戶進行身份驗證。通過身份驗證後,它會自動爲您提供example.com/a/b/c的結果。這提供了很好的用戶體驗,因此您的用戶無需再次輸入URL。

對於REST服務,這不是必須的,因爲客戶端會記住哪個URL需要重新請求。您可以通過修改配置使用NullRequestCache防止保存,如下圖所示:

protected void configure(HttpSecurity http) throws Exception { 
    http 
     .authorizeRequests() 
      .anyRequest().authenticated() 
      .and() 
     .requestCache() 
      .requestCache(new NullRequestCache()) 
      .and() 
     .httpBasic(); 
} 

您可以通過提供自己的AuthenticationProvider提供自定義的身份驗證。例如:

import org.springframework.security.authentication.AuthenticationProvider; 
import org.springframework.security.authentication.BadCredentialsException; 
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 
import org.springframework.security.core.Authentication; 
import org.springframework.security.core.AuthenticationException; 
import org.springframework.security.core.authority.AuthorityUtils; 

public class RestAuthenticationProvider implements AuthenticationProvider { 

    public Authentication authenticate(Authentication authentication) 
      throws AuthenticationException { 
     UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication; 

     String username = token.getName(); 
     String password = (String) token.getCredentials(); 

     // validate making REST call 
     boolean success = true; 
     // likely your REST call will return the roles for the user 
     String[] roles = new String[] { "ROLE_USER" }; 

     if(!success) { 
      throw new BadCredentialsException("Bad credentials"); 
     } 

     return new UsernamePasswordAuthenticationToken(username, null, AuthorityUtils.createAuthorityList(roles)); 
    } 

    public boolean supports(Class<?> authentication) { 
     return (UsernamePasswordAuthenticationToken.class 
       .isAssignableFrom(authentication)); 
    } 

} 

可以使用這樣的事情,然後配置你的RestAuthenticationProvider:

@EnableWebSecurity 
@Configuration 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 
    ... 

    @Bean 
    public RestAuthenticationProvider restAuthenticationProvider() { 
     return new RestAuthenticationProvider(); 
    } 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth, AuthenticationProvider provider) throws Exception { 
     auth 
      .authenticationProvider(provider); 
    } 
} 
+0

謝謝搶劫,當然我會嘗試將我的問題分解爲多個帖子。我會嘗試你的答案,並會回覆你。再次非常感謝你,並對延遲響應感到抱歉 –

+0

你在哪裏放置配置方法? – snowe

0

會話ID越來越存儲在Redis的,即使驗證失敗。

Rob的設置NullRequestCache的答案不適用於我。即使在將請求緩存設置爲NullRequestCache之後,也存在redis條目。爲了使它工作,我不得不使用身份驗證失敗處理程序。

http.formLogin().failureHandler(authenticationFailureHandler()).permitAll(); 

private AuthenticationFailureHandler authenticationFailureHandler() { 
    return new AuthenticationFailureHandler(); 
} 

public class AuthenticationFailureHandler 
    extends SimpleUrlAuthenticationFailureHandler { 
} 

請注意,失敗處理程序只會顯式擴展默認處理程序。如果失敗,它將返回401。如果您正在執行重定向,則可以輕鬆地在處理程序中配置它。