2013-04-13 76 views
0

我目前正在嘗試爲我的spring web應用程序實現登錄機制,而且我對於在春季使用的安全概念有點困惑。春季安全會議。保持登錄狀態

如果我訪問需要登錄的頁面,它正確地重定向到登錄頁面。登錄後,實際的頁面是可見的(到目前爲止是好的)。

代碼這個

<security:http use-expressions="true" auto-config="true"> 
    <security:intercept-url pattern="/login" access="permitAll" /> 
    <security:intercept-url pattern="/**" access="hasRole('ROLE_USER')" /> 
     <security:form-login login-page="/login" default-target-url="/welcome" 
      authentication-failure-url="/loginfailed" /> 
     <security:logout logout-success-url="/logout" /> 
     <security:remember-me/> 
    </security:http> 

但是,如果我再次訪問同一頁面,我需要重新登錄。所以我需要某種安全會話。我已經嘗試了很多關於記憶和會話管理的內容,但無法找到如何去做。

有人可以給我一些方向,在春季文檔或關鍵字適當的章節?

登錄表單

<form name='f' action="<c:url value='j_spring_security_check' />" 
     method='POST'> 

     <table> 
      <tr> 
       <td>User:</td> 
       <td><input type='text' name='j_username' value=''> 
       </td> 
      </tr> 
      <tr> 
       <td>Password:</td> 
       <td><input type='password' name='j_password' /> 
       </td> 
      </tr> 
      <tr> 
       <td colspan='2'><input name="submit" type="submit" 
        value="submit" /> 
       </td> 
      </tr> 
      <tr> 
       <td colspan='2'><input name="reset" type="reset" /> 
       </td> 
      </tr> 
     </table> 

    </form> 

LoginController.java

@RequestMapping(value="/login", method = RequestMethod.GET) 
    public String login(ModelMap model) { 

     return "login"; 

    } 

    @RequestMapping(value="/loginfailed", method = RequestMethod.GET) 
    public String loginerror(ModelMap model) { 

     model.addAttribute("error", "true"); 
     return "login"; 

    } 

    @RequestMapping(value="/logout", method = RequestMethod.GET) 
    public String logout(ModelMap model) { 

     return "login"; 

    } 

回答

1

你需要給你的安全定義的conf文件:

<security:remember-me services-alias="rememberMeService" data-source-ref="dataSource" user-service-ref="userService"/> 
</security:http> 

,並創建一個persistnet登錄表

create table persistent_logins (username varchar(64) not null, series varchar(64) primary key, token varchar(64) not null, last_used timestamp not null) 

但我現在重複Official docs

+0

嗨Nim, 如果用戶在(很長一段時間)之後返回到網頁,那麼用戶是否記得我?我需要的是,用戶只需一次認證,然後就可以使用網絡應用程序(逐屏顯示)。這是否一樣?如果是這樣,我真的需要一個持久性表嗎?難道不能在服務器緩存中保留登錄用戶數據嗎? –

+0

@GreenLomu yes記得我是在會話結束時。 Spring會自動將登錄的主體放入會話中... – NimChimpsky

+0

以及如何檢查用戶是否已經過身份驗證並擁有有效會話?它在中有所涉及? –

1

這是很神祕的,爲什麼安全會話沒有保持在登錄後的第二個請求,因爲你的配置看起來不錯。某些日誌對解決此問題很有用。在org.springframework.security上啓用跟蹤級別日誌記錄並在重現問題後共享日誌。

到目前爲止,評論已足以說明這一點,但我也想澄清remember-me功能的配置和使用情況,因爲您在那裏也有問題。

記得我服務應該與您在原始問題中的簡單配置一起工作。因爲您沒有在<remember-me>上指定data-source-ref,所以將應用更簡單且不太安全的實現,該實現不會持續向客戶端發放令牌。

這不是強制性的,但通過配置data-source-ref,您可以獲得一些額外的安全性:如果用戶的Remember-me令牌(cookie)被盜取並被攻擊者用來登錄您的用戶,您將能夠警告用戶網站與用戶的身份。這值得考慮投入額外的努力。

現在最重要的事情:記住我服務的下記錄的特點是客戶有明確要求服務器發送一個請求參數的名稱_spring_security_remember_me記住他的登錄。所以你必須插入類似下面的代碼片段到你的登錄表單中。

<p> 
    <label for="_spring_security_remember_me">Remember-me</label> 
    <input id="_spring_security_remember_me" 
      name="_spring_security_remember_me" type="checkbox"/> 
</p> 

沒有這個記事本服務不會做任何事情。(出於完整性考慮:還有一種選擇是在記住我服務上設置alwaysRemember標誌,但這有點不方便,因爲此配置點未由安全名稱空間公開)