我正在学习使用Spring MVC和一些基本的Spring Security构建网站的教程。我有以下问题:
功能
主页中的jQuery向/getmessages
方法发送请求,该方法返回表示地图的JSON对象。 'size'属性是消息的数量。然后jQuery使用该值更新SPAN标记。此SPAN标记包含在<sec:authorize access="isAuthenticated()">
标记中,因此只有登录用户才能看到它。这是在每5秒循环完成的。
/getMessages
网址受isAuthenticated()
拦截保护。
预期行为
实际行为
/getmessages
网址我认为这种情况正在发生,因为无论用户是否登录,都会发生/getmessages
的jQuery请求。当用户登录时,Spring会重定向到最近对受保护URL的请求尝试,在本例中为/getmessages
。
问题
我如何实现预期的行为。理想情况下,如果用户未经过身份验证,我希望jQuery不要调用/getmessages
。我已经尝试围绕<sec:authorize access="isAuthenticated()">
中jQuery的那部分工作,但是我不知道是否在jQuery / JavaScript代码中包含sec标签好/坏/丑陋的做法。
另一种可能性是从服务器返回一个变量,该变量指示用户(主体)是否已登录,然后在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 :(得分:0)
只需保护调用控制器的JavaScript代码块,以便使用
获取JSON数据<sec:authorize access="isAuthenticated()">
Home Page jQuery script-block
</sec:authorize>
关注:保护登录用户需要查看的代码/部分是完美的。你正确地理解spring-security记得重定向受保护的URL,onload你正在调用那个控制器,只是保护它,意味着整个调用序列,即脚本块。
$.getJSON("<c:url value="/getmessages"/>", getMessageCount);