我在 spring/spring-mvc 中有一个完全使用 JSON 通信的应用程序。 现在我需要通过 JSON 使用 spring security 3(使用 LdapAuthenticationProvider)对我的应用程序进行身份验证。
默认的 spring 安全提交表单需要这样的 POST:
POST /myapp/j_spring_security_check HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 32
Host: 127.0.0.1:8080
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
j_username=myUsername&j_password=myPass
但我想像这样传递一个 JSON 对象:
{"j_username":"myUsername","j_password":"myPass"}
我读过很多帖子,例如 this , this other或 this one没有运气,在所有 ajax 情况下都是像上面那样做一个 POST。
有什么想法吗?
最佳答案
根据凯文的建议,
并在阅读此帖子后:1 , 2 , 文档 3 ,感谢 this博文,
我自己写了FORM_LOGIN_FILTER,在认证前直接管理JSON。
我将我的代码粘贴到社区。p>
目标是同时授予经典浏览器表单 POST 身份验证和基于 JSON 的身份验证。同样在 JSON 身份验证中,我想避免重定向到 loginSuccesful.htm
在上下文中:
<security:http use-expressions="true" auto-config="false" entry-point-ref="http403EntryPoint">
<security:intercept-url pattern="/logs/**" access="denyAll" />
<!-- ... All other intercept URL -->
<security:custom-filter ref="CustomUsernamePasswordAuthenticationFilter" position="FORM_LOGIN_FILTER "/>
<security:logout
invalidate-session="true"
logout-success-url="/LogoutSuccessful.htm"
delete-cookies="true"
/>
<security:session-management>
<security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</security:session-management>
<security:access-denied-handler error-page="/accessDenied.htm" />
</security:http>
<bean id="CustomUsernamePasswordAuthenticationFilter" class="path.to.CustomUsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationSuccessHandler" ref="customSuccessHandler"/>
<property name="authenticationFailureHandler" ref="failureHandler"/>
<property name="filterProcessesUrl" value="/j_spring_security_check"/>
<property name="usernameParameter" value="j_username"/>
<property name="passwordParameter" value="j_password"/>
</bean>
<bean id="customSuccessHandler" class="path.to.CustomAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/login.htm" />
<property name="targetUrlParameter" value="/LoginSuccessful.htm" />
</bean>
<bean id="failureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/login.htm" />
</bean>
<bean id="http403EntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />
CustomUsernamePasswordAuthenticationFilter 类:
public class CustomUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{
private String jsonUsername;
private String jsonPassword;
@Override
protected String obtainPassword(HttpServletRequest request) {
String password = null;
if ("application/json".equals(request.getHeader("Content-Type"))) {
password = this.jsonPassword;
}else{
password = super.obtainPassword(request);
}
return password;
}
@Override
protected String obtainUsername(HttpServletRequest request){
String username = null;
if ("application/json".equals(request.getHeader("Content-Type"))) {
username = this.jsonUsername;
}else{
username = super.obtainUsername(request);
}
return username;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response){
if ("application/json".equals(request.getHeader("Content-Type"))) {
try {
/*
* HttpServletRequest can be read only once
*/
StringBuffer sb = new StringBuffer();
String line = null;
BufferedReader reader = request.getReader();
while ((line = reader.readLine()) != null){
sb.append(line);
}
//json transformation
ObjectMapper mapper = new ObjectMapper();
LoginRequest loginRequest = mapper.readValue(sb.toString(), LoginRequest.class);
this.jsonUsername = loginRequest.getUsername();
this.jsonPassword = loginRequest.getPassword();
} catch (Exception e) {
e.printStackTrace();
}
}
return super.attemptAuthentication(request, response);
}
}
CustomAuthenticationSuccessHandler 类:
public class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
public void onAuthenticationSuccess(
HttpServletRequest request,
HttpServletResponse response,
Authentication auth
)throws IOException, ServletException {
if ("application/json".equals(request.getHeader("Content-Type"))) {
/*
* USED if you want to AVOID redirect to LoginSuccessful.htm in JSON authentication
*/
response.getWriter().print("{\"responseCode\":\"SUCCESS\"}");
response.getWriter().flush();
} else {
super.onAuthenticationSuccess(request, response, auth);
}
}
}
https://stackoverflow.com/questions/19500332/
相关文章:
php - 在 JSON 编码的 HTML5 数据属性中转义/编码单引号
java - 从 json 文本文件加载 JSONObject 的最佳方法是什么?
java - Spring 3.2 测试,com.jajway 不包含在依赖项中
json - 如何配置spring mvc 3在json响应中不返回 "null"对象?
javascript - Socket.io 如何发送 JavaScript 对象
javascript - 使用来自 JSON 数据的不同值,而不是使用 Typeahead 的 di