首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >机密休息-Api/权限-总是403 s-我做错了什么?

机密休息-Api/权限-总是403 s-我做错了什么?
EN

Stack Overflow用户
提问于 2022-04-08 20:19:12
回答 1查看 436关注 0票数 4

我已经试了好几个小时了,好像撞到了墙。如有任何建议/帮助,将不胜感激。

目标:通过映射到客户机作用域的各种方法(例如:“create”/“read”/“update”/“”),-api (ex client-id:"my- rest-api ")路由(示例资源:"WeatherForecast")授权。我希望通过策略来控制这些权限(例如,如果满足策略“仅管理组”(用户属于管理组)),将授予“读- WeatherForecast -权限”。

Rest-api不会登录用户(将从前端直接与keycloak对话,然后他们将使用该令牌与rest-api对话)。

环境:

rest-api)

发生了什么:,我可以通过邮递员从密钥披风登录页面登录,并获得访问令牌。但是,当我碰到使用keycloak.protect()或keycloak.enforce()的端点时(不管是否指定了资源权限),我都无法通过。在下面的代码中,删除端点返回回传200 + postman中keycloak登录页面的HTML,Get返回回403 +“拒绝访问”。

当前状态

"Admin".

  • Client

  • 测试用户(我在邮递员中与其登录)具有组enabled.

  • Authorization "my-rest-api“,具有访问类型:使用授权enabled.

  • Authorization设置的机密:
  • 策略执行模式:强制执行,决策策略:使用uri的Unanimous
  • "WeatherForecast”资源“/api/weather预报”,并为组管理中的任何人创建/读取/更新/删除客户范围applied.
  • "Only Admins策略。“只选择管理策略”的“positive.
  • Permission”资源的每个客户端作用域的逻辑"Affirmative".

,决策策略:“Affirmative”.

Nodejs代码的当前状态:

代码语言:javascript
复制
import express from 'express';
import bodyParser from 'body-parser';
import session from "express-session";
import KeycloakConnect from 'keycloak-connect';

const app = express();

app.use(bodyParser.json());

const memoryStore = new session.MemoryStore();
app.use(session({
    secret: 'some secret',
    resave: false,
    saveUninitialized: true,
    store: memoryStore
  }));

const kcConfig: any = { 
    clientId: 'my-rest-api',
    bearerOnly: true,
    serverUrl: 'http://localhost:8080/auth',
    realm: 'my-realm',
};
const keycloak = new KeycloakConnect({ store: memoryStore }, kcConfig);

app.use(keycloak.middleware({
    logout: '/logout',
    admin: '/',
}));

app.get('/api/WeatherForecast', keycloak.enforcer(['WeatherForecast:read'],{  resource_server_id: "my-rest-api"}), function (req, res) {
   res.json("GET worked")
  });

app.delete('/api/WeatherForecast', keycloak.protect(), function (req, res) {
     res.json("DELETE worked")
});

app.listen(8081, () => {
    console.log(`server running on port 8081`);
  });

其他一些尝试过的东西:

  • I尝试使用邮递员提供的令牌调用RPT端点,得到完全正确的RPT令牌,按预期看到权限。
  • 尝试调用keycloak.checkPermissions({id:"WeatherForecast",作用域:“读”}},req).then(授予=> res.json(grant.access_token));在一个不安全的端点内部,并得到“连接拒绝”,127.0.0.1:8080".
  • I尝试禁用策略执行模式只是为了查看,仍然获得Access Denied/403.
  • I尝试使用keycloak.json配置,而不是上面的对象方法。
  • I尝试了openid-客户机(来自另一个教程),也遇到了连接拒绝的问题。
  • ,我尝试使用对接主机ip,host.docker.internal,容器名,等等,都没有用(尽管我不认为这是个问题,因为我显然可以访问auth服务并获得第一个访问令牌)。

我真的很想使用Keycloak,我觉得我的团队已经能够这么做了,但是需要一些帮助才能通过这个部分。谢谢!

编辑/更新#1:很好,所以再过几个小时就会陷入这个问题。决定读取它点击和调试的每一行键斗篷连接库。在keycloak-connect/middleware/auth-utils/grant-manager.js中发现它在checkPermissions的最后一行中失败。没有显示错误或捕捉块来进一步调试兔子洞,我发现它发生在使用http和选项的获取方法中:

代码语言:javascript
复制
'{"protocol":"http:","slashes":true,"auth":null,"host":"localhost:8080","port":"8080","hostname":"localhost","hash":null,"search":null,"query":null,"pathname":"/auth/realms/my-realm/protocol/openid-connect/token","path":"/auth/realms/my-realm/protocol/openid-connect/token","href":"http://localhost:8080/auth/realms/my-realm/protocol/openid-connect/token","headers":{"Content-Type":"application/x-www-form-urlencoded","X-Client":"keycloak-nodejs-connect","Authorization":"Basic YW(etc...)Z2dP","Content-Length":1498},"method":"POST"}'

它似乎没有进入该fetch/http包装器的回调。我将NODE_DEBUG=http添加到启动命令中,并找到了吞咽的错误,该错误似乎回到了起始线:

代码语言:javascript
复制
HTTP 31: SOCKET ERROR: connect ECONNREFUSED 127.0.0.1:8080 Error: connect ECONNREFUSED 127.0.0.1:8080

    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1157:16)

    at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)

然后,我看到了一些我认为可能与我的码头网络设置(Keycloak and Spring Boot web app in dockerized environment)有关的东西,并尝试更改主机名dns,这样我就可以使用本地主机以外的其他东西,但是它也不起作用(甚至添加到重定向uri,等等)。

更新2:好了,所以我现在让keycloak.protect() (纯身份验证)端点工作了。通过阅读keycloak-connect代码,我发现了更多的选项,并且在实例化keycloak-connect时,似乎将"realmPublicKey“添加到keycloak配置对象中,从而修复了这个选项。在授权keycloak.enforce方面,仍然没有运气。

代码语言:javascript
复制
const kcConfig: any = { 
    clientId: 'my-rest-api',
    bearerOnly: true,
    serverUrl: 'http://localhost:8080/auth',
    realm: 'my-realm',
    realmPublicKey : "MIIBIjANBgk (...etc) uQIDAQAB",
};
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-11 18:17:00

所以我的团队终于想出了答案--决议分为两部分:

somehow:

  • Add
  • 遵循了关于类似问题的说明,堆栈溢出问题的答案,例如:如果该链接曾经中断,则为127.0.0.1密钥披风的https://stackoverflow.com/a/51878212/5117487粗略步骤(如果' keycloak‘是您的对接器容器的名称,我更改了我的停靠-撰写以指定容器名称,使其更多一些fool-proof)
  • Change密钥斗篷-连接配置authServerUrl设置为:'http://keycloak:8080/auth/‘而不是'http://localhost:8080/auth/'
  1. Postman OAuth 2.0令牌请求Auth和访问令牌URL更改为使用现在更新的主机entry:
  • "http://localhost:8080/auth/realms/abra/protocol/openid-connect/auth“-> "http://keycloak:8080/auth/realms/abra/protocol/openid-connect/auth"
  • "http://localhost:8080/auth/realms/abra/protocol/openid-connect/token”-> "http://keycloak:8080/auth/realms/abra/protocol/openid-connect/token"

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71802757

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档