Spring Security,REST基本身份验证问题

编程入门 行业动态 更新时间:2024-10-28 00:21:30
本文介绍了Spring Security,REST基本身份验证问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

在使用Spring进行基本认证时,我遇到了与HTTP响应标题Access-Control-Allow-Origin相关的问题。当我手动验证时,如下面的代码(我正在使用REST):

I got an issue related to the HTTP response header "Access-Control-Allow-Origin" when using basic authetication with Spring. When I authenticate manually, like the code bellow (I'm using REST):

@RequestMapping(value = "/login", method = RequestMethod.POST, consumes = "application/json") @ResponseStatus(value = HttpStatus.OK) public void login(@RequestBody String body, HttpServletResponse response) throws IOException { try { User user = gson.fromJson(body, User.class); UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken( usuario.getUsername(), usuario.getPassword()); authenticationManager.authenticate(token); } catch (BadCredentialsException e) { response.sendError(HttpServletResponse.SC_UNAUTHORIZED); } catch (Exception e) { response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } }

一切正常,我收到以下HTTP响应:

everything works fine, I receive the following HTTP response:

HTTP/1.1 401 Unauthorized Server: Apache-Coyote/1.1 Access-Control-Allow-Origin: null Access-Control-Allow-Credentials: true Content-Type: text/html;charset=utf-8 Content-Length: 951 Date: Fri, 17 May 2013 19:14:36 GMT

如您所见,访问控制 - 允许 - 原点出现在回复中。 这里一切都很好。我可以在我的ajax调用中捕获401错误。

as you can see, "Access-Control-Allow-Origin" is present on the response. Everything is fine here. I can catch a 401 error in my ajax call.

但是当自动执行身份验证时,如下面的代码:

But when the authentication is performed automatically, like the code bellow:

@RequestMapping(value = "/name", method = RequestMethod.POST, consumes = "application/json") @PreAuthorize("hasRole('ROLE_CUSTOMER')") public @ResponseBody String getName(HttpServletResponse response) throws IOException { String json = null; try { User userSession = (User) SecurityContextHolder.getContext() .getAuthentication().getPrincipal(); Customer customer = customerDao.getNameByUsername(userSession.getUsername()); json = gson.toJson(customer); } catch (Exception e) { response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } return json; }

HTTP响应是:

HTTP/1.1 401 Unauthorized Server: Apache-Coyote/1.1 WWW-Authenticate: Basic realm="Spring Security Application" Content-Type: text/html;charset=utf-8 Content-Length: 981 Date: Fri, 17 May 2013 19:41:08 GMT

回复中没有Access-Control-Allow-Origin

There is no "Access-Control-Allow-Origin" in the response

Google Chrome控制台显示以下错误:

Google Chrome console show the following error:

Origin null is not allowed by Access-Control-Allow-Origin

我的ajax调用没有返回401 Unauthorized错误,即使HTTP响应返回它(上面的响应),我收到一个未知错误。

My ajax call does not return a 401 Unauthorized error, even though the HTTP response return it (response above), I receive an unknow error.

我发现对于所有浏览器,我需要在HTTP响应中使用Access-Control-Allow-Origin,否则它们会产生某种静默错误,我的ajax调用将失败(无法捕获401错误)。实际上,javascript将无声地失败。 XMLHttpRequest 不接受没有Access-Control-Allow-Origin的HTTP响应。

I figured out that for all browsers, I need a "Access-Control-Allow-Origin" in the HTTP response, otherwise they will generate some kind of silent error and my ajax call will fail (can't catch the 401 error). Actually, javascript will fail silently. XMLHttpRequest does not accept an HTTP response without "Access-Control-Allow-Origin".

如何让Spring注入Access-Control-Allow -Origin在HTTP响应中进行基本身份验证?

How can I make Spring inject this "Access-Control-Allow-Origin" in HTTP responses for basic authentication?

这是我的Spring Security xml:

this is my Spring Security xml:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="www.springframework/schema/beans" xmlns:security="www.springframework/schema/security" xmlns:xsi="www.w3/2001/XMLSchema-instance" xsi:schemaLocation=" www.springframework/schema/beans www.springframework/schema/beans/spring-beans-3.2.xsd www.springframework/schema/security www.springframework/schema/security/spring-security-3.1.xsd"> <security:http create-session="stateless" entry-point-ref="authenticationEntryPoint"> <security:intercept-url pattern="/customer/**" /> <security:http-basic /> <security:custom-filter ref="basicAuthenticationFilter" after="BASIC_AUTH_FILTER" /> </security:http> <bean id="basicAuthenticationFilter" class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter"> <property name="authenticationManager" ref="authenticationManager" /> <property name="authenticationEntryPoint" ref="authenticationEntryPoint" /> </bean> <bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint"> <property name="realmName" value="teste" /> </bean> <!-- It is responsible for validating the user's credentials --> <security:authentication-manager alias="authenticationManager"> <!-- It is responsible for providing credential validation to the AuthenticationManager --> <security:authentication-provider> <security:password-encoder ref="passwordEncoder" /> <security:jdbc-user-service data-source-ref="mySQLdataSource" users-by-username-query="select username, password, enabled from usuario where username = ?" authorities-by-username-query="select username, papel from autoridade where username = ?" /> </security:authentication-provider> </security:authentication-manager> <bean class="org.springframework.security.crypto.password.StandardPasswordEncoder" id="passwordEncoder" /> </beans>

推荐答案

我找到了自己的方式:

首先,我真的不记得为什么我把这一行放在这里,但它弄乱了我的代码:

First of all, I don't really remember why I put this line here, but it was messing up my code:

<security:http-basic />

其次,这个答案告诉我路径:处理Spring Security中基本身份验证的未经授权的错误消息。我必须创建一个自定义身份验证入口点才能发送Access-Control-Allow-Origin。

Second, this answer show me the path: Handle unauthorized error message for Basic Authentication in Spring Security. I had to create a custom authentication entry point in order to send the Access-Control-Allow-Origin thing.

所以现在这是我的代码:

So this is my code now:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="www.springframework/schema/beans" xmlns:security="www.springframework/schema/security" xmlns:xsi="www.w3/2001/XMLSchema-instance" xsi:schemaLocation=" www.springframework/schema/beans www.springframework/schema/beans/spring-beans-3.2.xsd www.springframework/schema/security www.springframework/schema/security/spring-security-3.1.xsd"> <security:http create-session="stateless" entry-point-ref="authenticationEntryPoint"> <security:intercept-url pattern="/api/admin/**" /> <security:intercept-url pattern="/medico/**" /> <!-- <security:http-basic /> --> <security:custom-filter ref="basicAuthenticationFilter" after="BASIC_AUTH_FILTER" /> </security:http> <bean id="basicAuthenticationFilter" class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter"> <property name="authenticationManager" ref="authenticationManager" /> <property name="authenticationEntryPoint" ref="authenticationEntryPoint" /> </bean> <!-- <bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint"> <property name="realmName" value="test" /> </bean> --> <bean id="authenticationEntryPoint" class="com.test.util.PlainTextBasicAuthenticationEntryPoint"> <property name="realmName" value="test" /> </bean> <!-- It is responsible for validating the user's credentials --> <security:authentication-manager alias="authenticationManager"> <!-- It is responsible for providing credential validation to the AuthenticationManager --> <security:authentication-provider> <security:password-encoder ref="passwordEncoder" /> <security:jdbc-user-service data-source-ref="mySQLdataSource" users-by-username-query="select username, password, enabled from usuario where username = ?" authorities-by-username-query="select username, papel from autoridade where username = ?" /> </security:authentication-provider> </security:authentication-manager> <bean class="org.springframework.security.crypto.password.StandardPasswordEncoder" id="passwordEncoder" /> </beans>

package com.test.util; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; public class PlainTextBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { response.addHeader("Access-Control-Allow-Origin", "null"); response.addHeader("WWW-Authenticate", "Basic realm=\"" + getRealmName() + "\""); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); PrintWriter writer = response.getWriter(); writer.println("HTTP Status " + HttpServletResponse.SC_UNAUTHORIZED + " - " + authException.getMessage()); } }

我的http响应现在:

My http response now:

HTTP/1.1 401 Unauthorized Server: Apache-Coyote/1.1 Access-Control-Allow-Origin: null WWW-Authenticate: Basic realm="test" Content-Length: 35 Date: Mon, 20 May 2013 20:05:03 GMT HTTP Status 401 - Bad credentials

在更改之前,我收到此错误消息:

before the alteration, I got this error message:

OPTIONS localhost:8080/test/customer/name 200 (OK) jquery-1.8.2.min.js:2 XMLHttpRequest cannot load localhost:8080/test/customer/name. Origin null is not allowed by Access-Control-Allow-Origin.

现在按预期我得到这个:

and now as expected I get this one:

OPTIONS localhost:8080/test/customer/name 200 (OK) jquery-1.8.2.min.js:2 POST localhost:8080/test/customer/name 401 (Unauthorized)

更多推荐

Spring Security,REST基本身份验证问题

本文发布于:2023-10-28 20:05:30,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1537640.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:身份验证   Spring   Security   REST

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!