我从Spring OAuth2开始。我想以application/json格式将用户名和密码发送到POST主体中的/oauth/token端点。
curl -X POST -H "Authorization: Basic YWNtZTphY21lc2VjcmV0" -H "Content-Type: application/json" -d '{
"username": "user",
"password": "password",
"grant_type": "password"
}' "http://localhost:9999/api/oauth/token"
字符串
这可能吗?
你能给予我一个建议吗?
6条答案
按热度按时间ua4mk5z41#
解决方案(不确定是否正确,但它缝,它是工作):
资源服务器配置:
字符串
筛选器:
型
请求 Package 器:
型
授权服务器配置(禁用/oauth/token端点的基本授权:
型
vql8enpb2#
根据OAuth 2规范,
客户端通过向令牌端点发送
下面的参数使用“application/x-www-form-urlencoded”
访问令牌请求应使用
application/x-www-form-urlencoded
。在Spring Security中,Resource Owner Password Credentials Grant Flow由Spring Security中的
ResourceOwnerPasswordTokenGranter#getOAuth2Authentication
处理:字符串
您可以发送
username
和password
来请求参数。如果你真的需要使用JSON,有一个解决方案。正如你所看到的,
username
和password
是从请求参数中检索的。因此,如果你将它们从JSON主体传递到请求参数中,它将工作。这个想法是这样的:
1.创建自定义Spring安全过滤器。
1.在您的自定义过滤器中,创建一个子类
HttpRequestWrapper
的类。该类允许您 Package 原始请求并从JSON获取参数。1.在
HttpRequestWrapper
的子类中,解析请求体中的JSON,得到username
、password
和grant_type
,并将它们与原始请求参数一起放入新的HashMap
中。然后,重写getParameterValues
、getParameter
、getParameterNames
和getParameterMap
的方法,以返回来自新HashMap
的值1.将打包后的请求传递到过滤器链中。
1.在Spring Security Config中配置自定义过滤器。
希望本文能够帮助
flseospp3#
对于Spring Security 5,我只需要添加.allowFormAuthenticationForClients()+在另一个答案中提到的JsontoUrlEncodedAuthenticationFilter,就可以让它接受json和x-form post数据。不需要注册资源服务器或任何东西。
yzckvree4#
你也可以修改@ jakub-kopaiva解决方案来支持oauth的http基本认证。
资源服务器配置:
字符串
使用内部RequestWrapper的过滤器
型
你还需要允许x-www-form-urlencoded身份验证
型
通过这种方法,你仍然可以使用基本的auth来使用oauth token和json请求token,如下所示:
表头:
型
正文部分:
型
txu3uszq5#
您可以使用以下代码修改@ jakub-kopadriva解决方案以仅实现授权服务器。
字符串
yk9xbfzb6#
你好,基于@Jakub Kopkyiva的回答,我已经做了改进,以创建工作的集成测试。只是让你知道, Catalina RequestFacade在Junit中抛出一个错误,而mockmvc使用的MockHttpServletRequest在过滤器中不包含我期望的字段“request”(因此在使用getDeclaredField()时抛出NoSuchFieldException):
Field f = request.getClass().getDeclaredField("request");
这就是为什么我使用“Rest Assured”。然而,在这一点上,我遇到了另一个问题,即无论出于何种原因,即使我使用
MediaType.APPLICATION_JSON_VALUE
,“application/json”的内容类型也会被覆盖到“application/json; charset=utf8”中。然而,条件会查找类似于“application/json;charset=UTF-8”的内容,它位于MediaType.APPLICATION_JSON_UTF8_VALUE
后面,并且结论是这将始终是false。因此,我的行为就像我在PHP中编码时所做的那样,我已经规范化了字符串(所有字符都是小写,没有空格)。
字符串
Here is the repo with the integration test