7

前言

我正在为 Grails 微服务联合设计一个 API 网关。此问题似乎与已在此存储库中提交的一堆问题有关,但没有提供解决方案。

版本和配置

圣杯:3.2.2

雄猫: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 插件仅用于令牌身份验证。我自己通过返回ROLE_NO_ROLES所有用户来完成授权部分getAuthorities()。我拦截所有请求并根据我自己存储在数据库中的授权模式授权访问。

问题:

使用这些配置和策略,当我在本地系统上运行我的代码时,它可以按需要运行。当我将它作为 tomcat 中的 war 文件部署在服务器上时,它适用于对网关的所有请求,即所有模式的请求/umm/controller/action。Spring 安全上下文就在那里,并且完美地评估了用户。

当我尝试使用表单的请求通过重定向调用其他微服务/umm/microservice/controller/actionspringSecurityService.getCurrentUser()springSecurityService?.principal?.username开始返回 null。尽管我的令牌得到了完美的评估,但我没有得到任何安全上下文。

有关详细信息,请查看此问题。上述问题中还提供了重现该错误的详细信息。整个项目可在此处获得。

更新:2017 年 5 月 19 日

我尝试在本地机器上的 Tomcat 中部署我的战争。这个问题和这个问题提供了以下解决方案。

  • 禁用tomcat缓存
  • 环境 grails.plugin.springsecurity.sch.strategyName = org.springframework.security.core.context.SecurityContextHolder.MODE_INHERITABLETHREADLOCAL

到目前为止似乎没有任何效果。反正SecurityContextHolder要回来了。null即所有用户检索功能SpringSecurityServicegetCurrentUser(), getPrincipal(),getAuthentication()loadCurrentUser()返回 null。

更新: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.

更新:2017 年 5 月 25 日

我可能应该问这个http://security.stackexchange.com但为了记录,我也在这里问。

我在下面提供的答案包含一个解决方法修复。答案中解释了修复工作的机制。我的问题是:

  1. 这种方法是否会在安全系统中引入任何漏洞或漏洞?
  2. 这个授权模式是安全的还是需要修改?
  3. 我正在通过插件进行身份验证,但正在授权自己。有人可以绕过安全过滤器并直接命中授权拦截器吗?因为如果有人能做到这一点,他只需给我一个与令牌格式相同的管理员用户名,他就可以访问所有内容。
4

1 回答 1

1

解决方法

我得到了解决该问题的解决方法。由于我只需要用户名,因此我在拦截器中抓取了其余令牌,对其进行解码并从中提取用户名。

开始:

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 日

我使用的解决方法是基于令牌的结构以及用户名嵌入在令牌中的事实,而令牌只是 base64 编码。

这是由 spring security REST 插件为 grails 生成的原始令牌:

eyJhbGciOiJIUzI1NiJ9。eyJwcmluY2lwYWwiOiJINHNJQUFBQUFBQUFBSlZTUDBcL2JRQlJcL0RrRkJpbWdCcVpVNjBLVjBxeHlKanBsSVNwRXFLNmthc2xDcDZHSVwvM0lQem5iazdrMlNwTXBXQkFVU0xWSld2d0RlQmhROVF0VU5YNXE1OVp3aE91eUJ1c2ZYdTU5K1wvNTdNcm1EWWFYc2FhY1dIOFZHUXhsNzVKTlpleHdURFQzQTc5ektDTzBPYUl0UnpZcFFsY0g2OEVYZ0FsSGxsWUNMYlpIcXNKSnVOYXU3ZU5vYTBQTkN3ckhkOHdibW1XWUZcL3BIZitXTzFRYVwveEVvcUwzdkphaHN3RHdMUTVWSjIxSnlkWkJ5amRFR3pCV3pRSVU3YnZRb3BCdVVsak5oSnFFVmxLd25NQXFneWpMN1VaRXFSMlBoNGJYWnpISlI2NkN0QnpDVE1tUEkzWDlKT3RaWmRcL2ZPcHFRRXVcL0FKeW9QVW8wUGRQWGRRM1wvSDRUU1VFcGVaS21xV3VURlRFdDdnVEpcLzdSNHZIbDRlbW9Xd0tnVGw3Y1wvVTB4ZjlLQTBmbUhQMFwvem9yM1F3dU1KNndXc1Brakp6WHpCdks3UktmXC80OXZiTHlkWCsreWxTZG9qWDk5XC9IMHNwTmM4T21TbEttbVZVVE95TGFmdG05RTNuamJ2THhGb1oraHllcFFQcWpwTVhvVnFJZ3ByaGxyY1M0Ynd1ejc5ckI2bWFydmVtZUhUZXBzQ2poOGxXRHBCXC9reWQzS1wvRURSd2c1K0gxMGNQdnRKTkc5Z2VvK0pES240dVFMVXlwSWU2czluSjR2VnI3OE84aGpqWFwvb3Z4RG9UU3hZREFBQT0iLCJzdWIiOiJhZG1pbkRCIiwicm9sZXMiOlsiUk9MRV9OT19ST0xFUyJdLCJleHAiOjE0OTU3MTU3OTMsImlhdCI6MTQ5NTcxMjE5M30.MPEXURGhJo5s75LfUSm5ckG91Byc7FCLygj1

这是解码版本:

"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

此处的主体经过签名和加密,但用户名未加密。因此可以通过上面给出的代码轻松提取它。

于 2017-05-23T13:54:07.310 回答