Spring boot 如何使用Spring boot Key斗篷适配器+;强制oAuth令牌续订(访问令牌+;刷新令牌);春季安全。?

Spring boot 如何使用Spring boot Key斗篷适配器+;强制oAuth令牌续订(访问令牌+;刷新令牌);春季安全。?,spring-boot,spring-security,oauth-2.0,keycloak,Spring Boot,Spring Security,Oauth 2.0,Keycloak,我有一个多租户应用程序(springboot Key隐形适配器+spring安全性),由Key隐形保护。考虑到项目的多租户性质,我编写了一个多客户机连接器,它工作得很好 在官方的keydape文档中,建议(对于多租户应用程序)将每个租户建模为一个新领域,但对我来说,在同一领域中有多个客户端效果更好。这是由于以下优点: 可以共享客户端范围、组和其他配置 用户不需要在N个不同的领域重复 SSO登录在同一领域的客户端(通过使用承载器)中可以完美地工作 服务+CORS) 所以,除了一件事之外,一切都

我有一个多租户应用程序(springboot Key隐形适配器+spring安全性),由Key隐形保护。考虑到项目的多租户性质,我编写了一个多客户机连接器,它工作得很好

在官方的keydape文档中,建议(对于多租户应用程序)将每个租户建模为一个新领域,但对我来说,在同一领域中有多个客户端效果更好。这是由于以下优点:

  • 可以共享客户端范围、组和其他配置
  • 用户不需要在N个不同的领域重复
  • SSO登录在同一领域的客户端(通过使用承载器)中可以完美地工作 服务+CORS)
所以,除了一件事之外,一切都很好,我的初始SSO
access\u token
(然后通过CORS在所有仅承载服务中共享)有点大(它显示了所有资源-租户-及其在每个资源/租户中的角色)

我想限制
访问\u令牌的大小,方法是使用“范围”将令牌中的角色限制为仅对我当时登录的租户有意义的角色。为此,我手动向auth服务器发出一个请求(springboot/spring security提供的标准功能之外),目的是手动覆盖我的应用程序中存在的任何访问令牌,并使用额外请求生成的新令牌

我的“新”令牌请求与此类似:

    SimpleKeycloakAccount currentUserAccount = (SimpleKeycloakAccount) auth.getDetails();
            String authServerUrl = currentUserAccount.getKeycloakSecurityContext().getDeployment().getAuthServerBaseUrl();
            String realm = currentUserAccount.getKeycloakSecurityContext().getDeployment().getRealm();
            String resource =  currentUserAccount.getKeycloakSecurityContext().getDeployment().getResourceName();
            String refreshToken = currentUserAccount.getKeycloakSecurityContext().getRefreshToken();
            String token = currentUserAccount.getKeycloakSecurityContext().getTokenString();
            
            
            Http http = new Http( new Configuration(authServerUrl, realm, resource,
                            currentUserAccount.getKeycloakSecurityContext().getDeployment().getResourceCredentials()
                           , null), 
                       (params, headers) -> {});
            
            String url = authServerUrl + "/realms/" + realm + "/protocol/openid-connect/token";
            
            AccessTokenResponse response = http.<AccessTokenResponse>post(url)
                .authentication()
                    .client()
                .form()
                    .param("grant_type", "refresh_token")
                    .param("refresh_token", refreshToken)
                    .param("client_id", resource)
                    .param("client_secret", "SOME_SECRET")
                    .param("scope", "SOME_SCOPE_TO_RESTRICT_ROLES")
                .response()
                    .json(AccessTokenResponse.class)
                .execute();

// :) -  response.getToken() and response.getRefreshToken(), contain new successfully generated tokens
            
simplekeydeposecount currentUserAccount=(simplekeydeposecount)auth.getDetails();
字符串authServerUrl=currentUserAccount.GetKeyPoveSecurityContext().getDeployment().getAuthServerBaseUrl();
String realm=currentUserAccount.GetKeyPoveSecurityContext().getDeployment().getRealm();
String resource=currentUserAccount.GetKeyPoveSecurityContext().getDeployment().getResourceName();
String refreshToken=currentUserAccount.GetKeyDopperSecurityContext().getRefreshToken();
String token=currentUserAccount.GetKeyPoveSecurityContext().getTokenString();
Http=新Http(新配置(authServerUrl、领域、资源、,
currentUserAccount.GetKeyDoveSecurityContext().getDeployment().getResourceCredentials()
,空),
(参数,头)->{};
字符串url=authServerUrl+“/realms/“+realm+”/protocol/openid connect/token”;
AccessTokenResponse=http.post(url)
.身份验证()
.client()
.表格(
.param(“授权类型”、“刷新令牌”)
.param(“刷新令牌”,刷新令牌)
.param(“客户端id”,资源)
.param(“客户秘密”、“某些秘密”)
.param(“范围”、“某些范围到限制角色”)
1.答复()
.json(AccessTokenResponse.class)
.execute();
//:)-response.getToken()和response.getRefreshToken()包含新的成功生成的令牌
我的问题是,如何强制我的应用程序使用这些“自定义创建”令牌更改/重置通过常规方式获得的标准访问令牌和刷新令牌?或者这是可能的吗

谢谢你的反馈

进一步信息

为了进一步说明,让我们分析一个典型的springboot/spring安全项目与KeyClope集成的行为:

  • 通过配置(在application.properties或SecurityContext上)使用“角色”保护端点
  • 您知道,这个Spring应用程序在后台与KeyClope授权服务器对话,这就是您成为access_令牌的方式(但对于开发人员来说,这一切都是一个黑盒子,您只知道创建了主体、安全上下文、凭据等-一切都发生在幕后)
考虑上述两点,假设您使用Http库基本上向auth server令牌端点请求一个新令牌,如上面的代码所示(是的,通过范围和所有内容过滤)。所以现在的情况是,尽管您已经创建了一个有效的
访问\u令牌
(和
刷新\u令牌
);由于它们是通过向令牌端点发出请求“手动”创建的,因此此新令牌尚未“合并”到应用程序中,因为没有创建新主体,没有生成新的安全上下文等。换句话说,对于springboot应用程序,此新令牌不存在

我试图完成的是告诉sprinboot/spring安全性:“嘿,伙计,我知道你不是自己生成这个令牌的,但是请接受它,表现得好像你已经创建了它一样。”


我希望这能澄清我问题的意图。

您可以使用
org.springframework.security.oauth2.provider.token.ConsumerTokenServices#revokeToken
方法撤销令牌

在自动化服务器上:

@Resource(name="tokenServices")
ConsumerTokenServices tokenServices;

@RequestMapping(method = RequestMethod.POST, value = "/tokens/revoke/{tokenId:.*}")
@ResponseBody
public String revokeToken(@PathVariable String tokenId) {
    tokenServices.revokeToken(tokenId);
    return tokenId;
}

当然,您必须保护此方法,因为它是一个非常敏感的方法。

如果每个租户都是一个单独的客户端,您可以在每个客户端使用KeyClope的“范围”映射。只需关闭允许的全范围,您的令牌将只包含该特定客户端(租户)的用户角色

“范围映射”是一种非直观的说法,表示“定义访问令牌中应该包含哪些角色”:-)

当关闭时,UI会发生更改,您甚至可以配置其他客户端的哪些其他角色应该附加到访问令牌中


为了结束这个问题:

  • 不,似乎没有任何优雅或有意的方式来强制
     // for creating your keycloak connector
     var keycloak = Keycloak({
                    url: 'http://localhost:8080/auth',
                    realm: '[YOUR_REALM]',
                    clientId: '[YOUR_CLIENT]'
                });
    
    
     // for login in (change scopes list to change access capabilities)
     var options = {
           scope: [EMPTY_STRING_SEPARATED_LIST_OF_SCOPES]  // <-- here specify valid scopes
         };
    
     keycloak.login(options); // <-- receive a new token with correctly processed scopes