美文网首页
为Keycloak添加自定义API

为Keycloak添加自定义API

作者: 陈sir的知识图谱 | 来源:发表于2021-02-09 15:46 被阅读0次

    添加机制 Service Provider Interfaces (SPI)

    创建 REST API

    我们创建一个不需要认证授权就可以访问的API,然后返回用户列表

    添加依赖

    <dependencies>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-core</artifactId>
            <scope>provided</scope>
            <version>${keycloak.version}</version>
        </dependency>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-server-spi</artifactId>
            <scope>provided</scope>
            <version>${keycloak.version}</version>
        </dependency>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-server-spi-private</artifactId>
            <scope>provided</scope>
            <version>${keycloak.version}</version>
        </dependency>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-services</artifactId>
            <scope>provided</scope>
            <version>${keycloak.version}</version>
        </dependency>
    </dependencies>
    

    整体文件结构如下

    +--- pom.xml
     +--- src
     | +--- main
     | | +--- java
     | | | +--- gaurav
     | | | | +--- keycloak
     | | | | | +--- DemoRestProvider.java
     | | | | | +--- DemoRestProviderFactory.java
     | | +--- resources
     | | | +--- META-INF
     | | | | +--- jboss-deployment-structure.xml
     | | | | +--- services
     | | | | | +--- org.keycloak.services.resource.RealmResourceProviderFactor
    

    DemoRestProviderFactoryDemoRestProvider 分别实现接口org.keycloak.services.resource.RealmResourceProviderFactoryorg.keycloak.services.resource.RealmResourceProvider

    DemoRestProviderFactory 将会定义 REST API 名称,并且在构造器中创建DemoRestProvider实例

    需要注意的是,factory 实例的生命周期是和keycloak server 生命周期同步的,而DemoRestProvider 则是没个请求都会生成与一个实例。

    DemoRestProviderFactory.java

    package gaurav.keycloak;
    
    import org.keycloak.Config.Scope;
    import org.keycloak.models.KeycloakSession;
    import org.keycloak.models.KeycloakSessionFactory;
    import org.keycloak.services.resource.RealmResourceProvider;
    import org.keycloak.services.resource.RealmResourceProviderFactory;
    
    public class DemoRestProviderFactory implements RealmResourceProviderFactory {
        public static final String ID = "gaurav-rest";
    
        public RealmResourceProvider create(KeycloakSession session) {
            return new DemoRestProvider(session);
        }
    
        public void init(Scope config) {
        }
    
        public void postInit(KeycloakSessionFactory factory) {
        }
    
        public void close() {
        }
    
        public String getId() {
            return ID;
        }
    
    }
    
    

    DemoRestProvider.java

    package gaurav.keycloak;
    
    import gaurav.keycloak.model.UserDetails;
    import org.jboss.resteasy.annotations.cache.NoCache;
    import org.keycloak.models.KeycloakSession;
    import org.keycloak.models.UserModel;
    import org.keycloak.services.resource.RealmResourceProvider;
    import org.keycloak.utils.MediaType;
    
    import javax.ws.rs.Encoded;
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.Produces;
    import java.util.List;
    import java.util.stream.Collectors;
    
    public class DemoRestProvider implements RealmResourceProvider {
        private final KeycloakSession session;
    
    
        public DemoRestProvider(KeycloakSession session) {
            this.session = session;
        }
    
    
        public void close() {
    
        }
    
        public Object getResource() {
            return this;
        }
    
        @GET
        @Path("users")
        @NoCache
        @Produces({MediaType.APPLICATION_JSON})
        @Encoded
        public List<UserDetails> getUsers() {
            List<UserModel> userModel = session.users().getUsers(session.getContext().getRealm());
            return userModel.stream().map(e -> toUserDetail(e)).collect(Collectors.toList());
        }
    
        private UserDetails toUserDetail(UserModel um) {
            return new UserDetails(um.getUsername(), um.getFirstName(), um.getLastName());
    
        }
    
    }
    

    UserDetails.java

    package gaurav.keycloak.model;
    
    public class UserDetails {
        private String userName;
        private String firstName;
        private String lastName;
    
        public UserDetails(String userName, String firstName, String lastName) {
            this.userName = userName;
            this.firstName = firstName;
            this.lastName = lastName;
        }
    
        public String getFirstName() {
            return firstName;
        }
    
        public String getUserName() {
            return userName;
        }
    
        public String getLastName() {
            return lastName;
        }
    
    
    }
    

    使用 SPI 机制添加factory class 到keycloak
    添加文件org.keycloak.services.resource.RealmResourceProviderFactory 到 src\main\resources\META-INF

    | +--- resources
    | | +--- META-INF
    | | | +--- services
    | | | | +--- org.keycloak.services.resource.RealmResourceProviderFactory
    

    添加文件jboss-deployment-structure.xml到 src\main\resources

    jboss-deployment-structure.xml

    <jboss-deployment-structure>
        <deployment>
            <dependencies>
                <module name="org.keycloak.keycloak-core"/>
                <module name="org.keycloak.keycloak-server-spi"/>
                <module name="org.keycloak.keycloak-server-spi-private"/>
                <module name="org.keycloak.keycloak-services"/>
            </dependencies>
        </deployment>
    </jboss-deployment-structure>
    

    org.keycloak.services.resource.RealmResourceProviderFactory 的内容为
    gaurav.keycloak.DemoRestProviderFactory

    运行 maven package,生成的jar包放入keycloak-12.0.2\standalone\deployments 内会自动生成keycloak-rest-api-1.0.jar.deployed 文件

    进入keycloak


    image.png
    image.png

    测试

    创建一个realm GW,然后在GW下随便添加几个用户。

    curl-s -X GET"http://localhost:8180/auth/realms/GW/gaurav-rest/users" | jq
    [
      { 
        "userName": "gaurav",
        "firstName": "gaurav",
        "lastName": "wadhone"
      },
      {
        "userName": "testuser",
        "firstName": "test",
        "lastName": "user"
      },
      {
        "userName": "testuser2",
        "firstName": "test",
        "lastName": "user2"
      }
    ]
    

    参考
    参考2
    源码

    相关文章

      网友评论

          本文标题:为Keycloak添加自定义API

          本文链接:https://www.haomeiwen.com/subject/vbqcxltx.html