2014-09-26 50 views
0

我正在使用Spring MVC和一些基本的Spring Security來構建網站。我有以下問題:Spring Security:僅對經過身份驗證的用戶執行jQuery代碼

功能

jQuery的在主頁發送到/getmessages方法,它返回代表地圖的JSON對象的請求。 'size'屬性是消息的數量。然後jQuery用該值更新SPAN標籤。此SPAN標籤包含在<sec:authorize access="isAuthenticated()">標籤中,因此只有登錄的用戶才能看到它。這是每5秒循環完成一次。

/getMessages URL受isAuthenticated()攔截的保護。

預期行爲

  • 用戶點擊「登錄」主頁上的鏈接,這使用戶在登錄頁面
  • 用戶成功登錄,並且用戶被重定向回到主頁。

實際行爲

  • 用戶點擊「登錄」鏈接的主頁,這使用戶在登錄頁面
  • 用戶成功登錄,但用戶在重定向到/getmessages URL顯示原始JSON數據

我假設這是因爲jQuery請求無論用戶是否登錄,都會發生。當用戶登錄時,Spring將重定向到受保護的URL的最近請求嘗試,在這種情況下爲/getmessages

問題

如何實現我的預期行爲。理想情況下,如果用戶未通過身份驗證,我寧願jQuery不要致電/getmessages。我試圖圍繞在<sec:authorize access="isAuthenticated()">這jQuery的那部分工作,但我不知道如果在jQuery/JavaScript代碼中包含sec標記好/壞/醜陋的做法。

另一種可能性是從服務器返回給jQuery的一個變量,表示如果用戶(委託人)登錄,然後使用在IF語句守衛進入到/getmessages呼叫

我會感謝關於解決這個問題的最佳方式的建議。

代碼

首頁jQuery的

<script type="text/javascript"> 


function getMessageCount(data){ 

    $("#message-count").text(data.size);   

} 

function onLoad(){ 

    updatePage(); 
    window.setInterval(updatePage, 5000); 

} 

function updatePage(){ 



    $.getJSON("<c:url value="/getmessages"/>", getMessageCount); 



} 



$(document).ready(onLoad); 


</script> 

的getMessages方法

@RequestMapping(value="/getmessages", method=RequestMethod.GET, produces="application/json") 
@ResponseBody 
public Map<String, Object> getMessages(Principal principal){ 

    List<Message> messages = new ArrayList<Message>(); 

    if(principal != null){ 
     String username = principal.getName();   
     messages = userService.getMessages(username);   
    } 

    Map<String, Object> data = new HashMap<String, Object>(); 
    data.put("messages", messages); 
    data.put("size", messages.size()); 

    return data; 

} 

登錄頁面JSP(瓦)

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" 
pageEncoding="ISO-8859-1"%> 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 

<script type="text/javascript"> 

$(document).ready(function(){ 

     document.f.j_username.focus() 

}) 


</script> 

<h3>Login With Username and Password</h3> 

<c:if test="${param.auth != null}"> 

    <p class="error">Username or password is incorrect</p> 

</c:if> 

<form name='f' 
    action='${pageContext.request.contextPath}/j_spring_security_check' 
    method='POST'> 

    <table class="formtable"> 
     <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" value=''></td> 
     </tr> 

     <tr> 
      <td>Remember Me</td> 
      <td><input type="checkbox" name="_spring_security_remember_me"></td> 
     </tr> 

     <tr> 
      <td class="label"></td> 
      <td><input type="submit" name="submit" value='Login'></td> 
     </tr> 

    </table> 

</form> 

<p> 
    <a href="<c:url value='/newaccount' />">Create New Account</a> 
</p> 

安全上下文配置XML

<?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/security http://www.springframework.org/schema/security/spring-security-3.2.xsd 
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 


<security:authentication-manager> 
    <security:authentication-provider> 
     <security:jdbc-user-service data-source-ref="dataSource" 
      authorities-by-username-query="SELECT username, authority FROM users WHERE BINARY username = ?" 
      users-by-username-query="SELECT username, password, enabled FROM users WHERE BINARY username = ?" 
      id="jdbcUserService" /> 
     <security:password-encoder ref="passwordEncoder"></security:password-encoder> 
    </security:authentication-provider> 
</security:authentication-manager> 


<security:http use-expressions="true"> 
    <security:intercept-url pattern="/admin" access="permitAll" /> 
    <security:intercept-url pattern="/admin" access="hasRole('ROLE_ADMIN')" /> 
    <security:intercept-url pattern="/createoffer" access="isAuthenticated()" /> 
    <security:intercept-url pattern="/offerdeleted" access="isAuthenticated()" /> 
    <security:intercept-url pattern="/docreate" access="isAuthenticated()" /> 
    <security:intercept-url pattern="/offercreated" access="isAuthenticated()" /> 
    <security:intercept-url pattern="/getmessages" access="isAuthenticated()" /> 
    <security:intercept-url pattern="/" access="permitAll" /> 
    <security:intercept-url pattern="/loggedout" access="permitAll" /> 
    <security:intercept-url pattern="/message" access="permitAll" /> 
    <security:intercept-url pattern="/static/**" access="permitAll" /> 
    <security:intercept-url pattern="/newaccount" access="permitAll" /> 
    <security:intercept-url pattern="/createaccount" access="permitAll" /> 
    <security:intercept-url pattern="/login" access="permitAll" /> 
    <security:intercept-url pattern="/offers" access="permitAll" /> 
    <security:intercept-url pattern="/denied" access="permitAll" /> 
    <security:intercept-url pattern="/**" access="denyAll" /> 
    <security:form-login login-page="/login" authentication-failure-url="/login?auth=false" /> 
    <security:logout logout-success-url="/loggedout" /> 
    <security:access-denied-handler error-page="/denied" /> 
    <security:remember-me key="offersAppKey" user-service-ref="jdbcUserService" /> 
</security:http> 


<security:global-method-security secured-annotations="enabled"></security:global-method-security> 

<bean id="passwordEncoder" 
    class="org.springframework.security.crypto.password.StandardPasswordEncoder"> 
</bean> 

+0

我不認爲包裝的JavaScript代碼部分在'<秒:授權訪問= 「isAuthenticated()」>'是壞/難看實踐。相反,盲目地發送需要認證的請求並不好。 – qingbo 2014-09-27 03:42:16

+0

如果你不介意總是重定向到主頁,也許你想嘗試[always-use-default-target](http://docs.spring.io/autorepo/docs/spring-security/current/reference/ htmlsingle /#ns-form-target) – qingbo 2014-09-27 03:43:30

+0

我第二@qingbo。使用'sec:authorize'來更改JavaScript邏輯沒有任何問題。第二種方法(在控制器中設置請求並在JSP中評估它)同樣很好。 – Ritesh 2014-09-27 17:37:13

回答

0

只需確保JavaScript代碼塊調用控制器與

<sec:authorize access="isAuthenticated()"> 
     Home Page jQuery script-block 
</sec:authorize> 

關注獲取JSON數據:它是完美的保護代碼/部分,登錄用戶需要查看。你已經正確地理解了,spring-security記得重定向那個被保護的URL,在你調用這個控制器的時候,保證這個,意味着整個調用序列,即腳本塊。

$.getJSON("<c:url value="/getmessages"/>", getMessageCount); 
相關問題