paulwong

          OIDC - KEYCLOAK - 自定義CLIENT SCOPE

          當CLIENT或用戶在KEYCLOAK中成功登錄后,會返回JWT字符串,其中默認含有權限的信息,但此信息以內嵌的方式呈現,非常不方便。
          "resource_access": {
              "app-springboot-confidential": {
                "roles": [
                  "user"
                ]
              },
              "test-employee-service": {
                "roles": [
                  "READ_EMPLOYEE"
                ]
              },
              "service-springboot": {
                "roles": [
                  "READ_PRODUCTS"
                ]
              },
              "account": {
                "roles": [
                  "manage-account",
                  "manage-account-links"
                ]
              },
              "test-department-service": {
                "roles": [
                  "READ_DEPARTMENT"
                ]
              }
            }

          • 需要將權限的信息輸出到一個KEY中,這時可以新增自定義CLIENT SCOPE。Mapper中新增KEYCLOAK已內置的【realm roles/client roles】,定義輸出到JTW的字段名:my-roles。
          • 授權哪些CLIENT可以讀取此CLIENT SCOPE.
          • 在登錄參數scope中,加入此值:my-roles,這樣在輸出的JWT就會以平面的方式輸出所有roles
          "my-roles": [
              "user",
              "READ_EMPLOYEE",
              "READ_PRODUCTS",
              "manage-account",
              "manage-account-links",
              "READ_DEPARTMENT",
              "offline_access",
              "user"
            ]

          • SPRING SECURITY中取出權限信息:

          @Bean
              public ReactiveJwtAuthenticationConverter jwtAuthenticationConverter(ObjectMapper objectMapper) {
                  
                  JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
                  jwtGrantedAuthoritiesConverter.setAuthorityPrefix("ROLE_");
                  jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName("my-roles");
                  
          //        KeycloakRealmRoleConverter keycloakRealmRoleConverter = new KeycloakRealmRoleConverter(objectMapper);
                  
                  ReactiveJwtGrantedAuthoritiesConverterAdapter reactiveJwtGrantedAuthoritiesConverterAdapter = 
                          new ReactiveJwtGrantedAuthoritiesConverterAdapter(
          //                        new KeycloakRealmRoleConverter(objectMapper);
                                  jwtGrantedAuthoritiesConverter
                              );
                  
                  ReactiveJwtAuthenticationConverter jwtConverter = new ReactiveJwtAuthenticationConverter();
                  jwtConverter.setJwtGrantedAuthoritiesConverter(reactiveJwtGrantedAuthoritiesConverterAdapter);
                  
                  return jwtConverter;
              }

          • 判斷是否有權限

          ServerHttpSecurity
                      .authorizeExchange(
                          a -> a.pathMatchers("/", "/error").permitAll()
                                .matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
                                .pathMatchers(HttpMethod.GET, "/protected/**").hasRole("READ_DEPARTMENT")
                                .anyExchange()
                                .authenticated()
                       )

          posted on 2021-12-22 11:15 paulwong 閱讀(758) 評論(0)  編輯  收藏 所屬分類: OAUTH2KEYCLOAK

          主站蜘蛛池模板: 镇安县| 南涧| 汕头市| 海兴县| 翁源县| 崇礼县| 蒲江县| 道孚县| 河西区| 潮安县| 祁连县| 斗六市| 莫力| 梨树县| 曲水县| 岚皋县| 遂宁市| 福州市| 财经| 乌鲁木齐县| 大连市| 阿合奇县| 雷波县| 利川市| 原平市| 临潭县| 南平市| 渭源县| 滕州市| 三穗县| 安国市| 安阳市| 那曲县| 迁安市| 鄂托克旗| 临沂市| 渑池县| 南乐县| 马山县| 鱼台县| 天全县|