这是旧的文章,但它仍然出现为“春季安全的Ajax登陆”前的结果之一,所以我想我会分享我的解决方案。它遵循Spring Security标准,安装非常简单,诀窍是在安全配置中有2 <http>
元素,一个用于REST/Ajax,一个用于应用程序的其他部分(常规HTML页面)。其中<http>
的出现顺序很重要,它已经从特殊到一般的网址去,就像一个<http>
内<url-intercept>
元素。
步骤1:设置两个单独的<http>
的
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- a shared request cache is required for multiple http elements -->
<beans:bean id="requestCache" class="org.springframework.security.web.savedrequest.HttpSessionRequestCache" />
<!-- remove security from static resources to avoid going through the security filter chain -->
<http pattern="/resources/**" security="none" />
<!-- http config for REST services (AJAX interface)
=================================================== -->
<http auto-config="true" use-expressions="true" pattern="/rest/**">
<!-- login configuration
login-processing-url="/rest/security/login-processing" front-end AJAX requests for authentication POST to this URL
login-page="/rest/security/login-page" means "authentication is required"
authentication-failure-url="/rest/security/authentication-failure" means "authentication failed, bad credentials or other security exception"
default-target-url="/rest/security/default-target" front-end AJAX requests are redirected here after success authentication
-->
<form-login
login-processing-url="/rest/security/login-processing"
login-page="/rest/security/login-page"
authentication-failure-url="/rest/security/authentication-failure"
default-target-url="/rest/security/default-target"
always-use-default-target="true" />
<logout logout-url="/rest/security/logout-url" />
<!-- REST services can be secured here, will respond with JSON instead of HTML -->
<intercept-url pattern="/rest/calendar/**" access="hasRole('ROLE_USER')" />
<!-- other REST intercept-urls go here -->
<!-- end it with a catch all -->
<intercept-url pattern="/rest/**" access="isAuthenticated()" />
<!-- reference to the shared request cache -->
<request-cache ref="requestCache"/>
</http>
<!-- http config for regular HTML pages
=================================================== -->
<http auto-config="true" use-expressions="true">
<form-login
login-processing-url="/security/j_spring_security_check"
login-page="/login"
authentication-failure-url="/login?login_error=t" />
<logout logout-url="/security/j_spring_security_logout" />
<intercept-url pattern="/calendar/**" access="hasRole('ROLE_USER')" />
<!-- other intercept-urls go here -->
<!-- in my app's case, the HTML config ends with permitting all users and requiring HTTPS
it is always a good idea to send sensitive information like passwords over HTTPS -->
<intercept-url pattern="/**" access="permitAll" requires-channel="https" />
<!-- reference to the shared request cache -->
<request-cache ref="requestCache"/>
</http>
<!-- authentication manager and other configuration go below -->
</beans:beans>
步骤2:Rest认证控制器
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import flexjson.JSONSerializer;
@Controller
@RequestMapping(value = "/rest/security")
public class RestAuthenticationController {
public HttpHeaders getJsonHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
return headers;
}
@RequestMapping(value="/login-page", method = RequestMethod.GET)
public ResponseEntity<String> apiLoginPage() {
return new ResponseEntity<String>(getJsonHeaders(), HttpStatus.UNAUTHORIZED);
}
@RequestMapping(value="/authentication-failure", method = RequestMethod.GET)
public ResponseEntity<String> apiAuthenticationFailure() {
// return HttpStatus.OK to let your front-end know the request completed (no 401, it will cause you to go back to login again, loops, not good)
// include some message code to indicate unsuccessful login
return new ResponseEntity<String>("{\"success\" : false, \"message\" : \"authentication-failure\"}", getJsonHeaders(), HttpStatus.OK);
}
@RequestMapping(value="/default-target", method = RequestMethod.GET)
public ResponseEntity<String> apiDefaultTarget() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
// exclude/include whatever fields you need
String userJson = new JSONSerializer().exclude("*.class", "*.password").serialize(authentication);
return new ResponseEntity<String>(userJson, getJsonHeaders(), HttpStatus.OK);
}
}
步骤3:提交AJAX形式和处理响应,需要jQuery的ajaxForm库
<form action="/rest/security/login-processing" method="POST">
...
</form>
$('form').ajaxForm({
success: function(response, statusText, xhr, $form) {
console.log(response);
if(response == null || response.username == null) {
alert("authentication failure");
} else {
// response is JSON version of the Spring's Authentication
alert("authentication success");
}
},
error: function(response, statusText, error, $form) {
if(response != null && response.message == "authentication-failure") {
alert("authentication failure");
}
}
});
您的解决方案看起来不错,但哪里是控制方法应对“/ REST /安全/登录处理”定义 – 2014-02-01 21:26:45