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

          主站蜘蛛池模板: 开远市| 马边| 邵阳市| 奎屯市| 江津市| 留坝县| 北海市| 安康市| 神池县| 九江市| 小金县| 屏东市| 陵川县| 甘德县| 永寿县| 榕江县| 新津县| 松阳县| 磴口县| 台中县| 织金县| 平湖市| 灵寿县| 陆河县| 深水埗区| 永善县| 莱芜市| 乐都县| 衢州市| 那曲县| 张家口市| 弋阳县| 平南县| 轮台县| 宁晋县| 清河县| 昌平区| 东台市| 义乌市| 平定县| 乐亭县|