前言
我正在为 Grails 微服务联合设计 API 网关。这个问题似乎与此 repository 中已经提交的一堆问题有关。但没有什么能提供解决方案。
版本和配置
chalice :3.2.2
Tomcat :8.5
插件版本:
compile 'org.grails.plugins:spring-security-core:3.1.2'
compile "org.grails.plugins:spring-security-rest:2.0.0.M2"
我使用 spring security rest 插件仅用于 token 身份验证。我通过返回
ROLE_NO_ROLES
自己做授权部分对于
getAuthorities()
中的所有用户.我拦截所有请求并根据我自己存储在数据库中的授权模式授权访问。
问题:
使用这些配置和策略,当我在本地系统上运行代码时,我的代码可以正常工作。当我将它作为 tomcat 中的 war 文件部署在服务器上时,它适用于对网关的所有请求,即对于模式
/umm/controller/action
的所有请求。 . Spring 安全上下文就在那里,用户得到了完美的评估。
当我尝试通过使用形式为
/umm/microservice/controller/action
的请求重定向来调用其他微服务时,
springSecurityService.getCurrentUser()
和
springSecurityService?.principal?.username
开始返回空值。虽然我的 token 得到了完美的评估,但我没有得到任何安全上下文。
有关详细信息,请查看此 issue .上述问题中还提供了重现错误的详细信息。
整个项目可用 here .
更新:2017 年 5 月 19 日
我尝试在本地机器上的 Tomcat 中部署我的 war 。此 question而这个 question提供以下解决方案。
grails.plugin.springsecurity.sch.strategyName = org.springframework.security.core.context.SecurityContextHolder.MODE_INHERITABLETHREADLOCAL
到目前为止似乎没有任何效果。
SecurityContextHolder
正在返回
null
反正。
SpringSecurityService
的所有用户检索功能即。
getCurrentUser()
,
getPrincipal()
,
getAuthentication()
和
loadCurrentUser()
返回空。
更新:2017 年 5 月 23 日
为了缩小问题的范围,我使用
java -Dgrails.env=prod -jar build/libs/mywar-0.1.war
现在对于任何非 umm 请求,我都会收到
404, page not found
.我认为问题出在生产环境上。该应用程序在开发中完全正常。
也试过
grails run-app
这工作正常。为了排除生产环境的问题,我用
grails dev war
创建了war但无济于事。到目前为止,
war
没有任何效果.
更新:2017 年 5 月 25 日
我应该问这个 http://security.stackexchange.com但为了记录,我也在这里问。
我在下面提供的答案包含一个解决方法。答案中解释了修复工作的机制。我的问题是:
请您参考如下方法:
解决方法
我得到了解决该问题的解决方法。因为我只需要用户名,所以我在拦截器中抓取了剩余的 token ,对其进行解码并从中提取用户名。
开始:
def extractUsername(def token){
Base64 coder = new Base64()
def tok = token - "Bearer "
def principal = tok.tokenize(".")
def dec = coder.decode(principal[1])
def sub = new String(dec)
def user = sub.tokenize(",")
def username=user[1].tokenize(":")
username = username[1]-"\""
return username-"\""
}
它对我有用,因为我不需要检查
springSecurityService.Principal
目的。如果是这样,我将无法获得用户名。
springSecurityService.Principal
和
springSecurityService.getCurrentUser()
仍然返回null。问题还没有解决。我回答是因为尽管有赏金,但我什至没有收到一条评论。
如果有人能解释为什么 spring-security-plugin 会这样行事,仍然欢迎回答原始问题 .
编辑:2017 年 5 月 25 日
我使用的解决方法基于 token 的结构以及用户名嵌入在 token 中并且 token 只是 base64 编码的事实。
这是由 spring 安全 REST 插件为 grails 生成的原始 token :
eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINHNJQUFBQUFBQUFBSlZTUDBcL2JRQlJcL0RrRkJpbWdCcVpVNjBLVjBxeHlKanBsSVNwRXFLNmthc2xDcDZHSVwvM0lQem5iazdrMlNwTXBXQkFVU0xWSld2d0RlQmhROVF0VU5YNXE1OVp3aE91eUJ1c2ZYdTU5K1wvNTdNcm1EWWFYc2FhY1dIOFZHUXhsNzVKTlpleHdURFQzQTc5ektDTzBPYUl0UnpZcFFsY0g2OEVYZ0FsSGxsWUNMYlpIcXNKSnVOYXU3ZU5vYTBQTkN3ckhkOHdibW1XWUZcL3BIZitXTzFRYVwveEVvcUwzdkphaHN3RHdMUTVWSjIxSnlkWkJ5amRFR3pCV3pRSVU3YnZRb3BCdVVsak5oSnFFVmxLd25NQXFneWpMN1VaRXFSMlBoNGJYWnpISlI2NkN0QnpDVE1tUEkzWDlKT3RaWmRcL2ZPcHFRRXVcL0FKeW9QVW8wUGRQWGRRM1wvSDRUU1VFcGVaS21xV3VURlRFdDdnVEpcLzdSNHZIbDRlbW9Xd0tnVGw3Y1wvVTB4ZjlLQTBmbUhQMFwvem9yM1F3dU1KNndXc1Brakp6WHpCdks3UktmXC80OXZiTHlkWCsreWxTZG9qWDk5XC9IMHNwTmM4T21TbEttbVZVVE95TGFmdG05RTNuamJ2THhGb1oraHllcFFQcWpwTVhvVnFJZ3ByaGxyY1M0Ynd1ejc5ckI2bWFydmVtZUhUZXBzQ2poOGxXRHBCXC9reWQzS1wvRURSd2c1K0gxMGNQdnRKTkc5Z2VvK0pES240dVFMVXlwSWU2czluSjR2VnI3OE84aGpqWFwvb3Z4RG9UU3hZREFBQT0iLCJzdWIiOiJhZG1pbkRCIiwicm9sZXMiOlsiUk9MRV9OT19ST0xFUyJdLCJleHAiOjE0OTU3MTU3OTMsImlhdCI6MTQ5NTcxMjE5M30.MPEXURGhJo5s75LfUSm5ckG99Byc7FCLyj1gYZJu1zk
这是解码版本:
"principal":"H4sIAAAAAAAAAJVSP0/bQBR/DkFBimgBqZU60KV0qxyJjplISpEqK6kaslCp6GI/3IPznbk7k2SpMpWBAUSLVJWvwDeBhQ9QtUNX5q59ZwhOuyBusfXu59+/57MrmDYaXsaacWH8VGQxl75JNZexwTDT3A79zKCO0OaItRzYpQlcH68EXgAlHllYCLbZHqsJJuNau7eNoa0PNCwrHd8wbmmWYF/pHf+WO1Qa/xEoqL3vJahswDwLQ5VJ21JydZByjdEGzBWzQIU7bvQopBuUljNhJqEVlKwnMAqgyjL7UZEqR2Ph4bXZzHJR66CtBzCTMmPI3X9JOtZZd/fOpqQEu/AJyoPUo0PdPXdQ3/H4TSUEpeZKmqWuTFTEt7gTJ/7R4vHl4emoWwKgTl7c/U0xf9KA0fmHP0/zor3QwuMJ6wWsPkjJzXzBvK7RKf/49vbLydX++ylSdojX99/H0spNc8OmSlKmmVUTOyLaftm9E3njbvLxFoZ+hyepQPqjpMXoVqIgprhlrcS4bwuz79rB6marvemeHTepsCjh8lWDpB/kyd3K/EDRwg5+H10cPvtJNG9geo+JDKn4uQLUypIe6s9nJ4vVr78O8hjjX/ovxDoTSxYDAAA=","sub":"adminDB","roles":["ROLE_NO_ROLES"],"exp":1495715793,"iat":1495712193
此处的主体已签名和加密,但用户名未加密。因此可以通过上面给出的代码轻松提取。