如何在 Android 客户端中使用 Keycloak OpenId 进行 oAuth

ACB*_*CBM 6 android aerogear keycloak

我想使用 aerogear 和使用 Keycloak 的服务器在 Android 应用程序中对用户进行身份验证(使用他的用户名和密码)。我一直无法做到,请帮助我。

我目前可以在没有 aerogear 的情况下对用户进行身份验证,但我想使用这个库,因为它可以帮助我在需要时刷新令牌。我像这样对向服务器发出 POST 调用的用户进行身份验证(但来自 android):

 curl -X POST http://127.0.0.1:8080/auth/realms/example/protocol/openid-connect/token  
 -H "Content-Type: application/x-www-form-urlencoded" -d "username=auser" -d 'password=apassword' -d 'grant_type=password' 
 -d 'client_id=clientId' -d 'client_secret=secret'
Run Code Online (Sandbox Code Playgroud)

所以我得到的信息是:

  • 认证网址, ie http://127.0.0.1:8080/auth/realms/example/protocol/openid-connect/token
  • 用户名,用户的用户名
  • 密码,用户的密码
  • Keycloak服务器的client_id和client_secret

我对 Aerogear 的尝试是这样的:

private void authz() {
    try {

        AuthzModule authzModule = AuthorizationManager.config("KeyCloakAuthz", OAuth2AuthorizationConfiguration.class)
                .setBaseURL(new URL("http://127.0.0.1:8080/"))
                .setAuthzEndpoint("/realms/example/protocol/openid-connect/auth")
                .setAccessTokenEndpoint("/realms/example/protocol/openid-connect/token")
                .setAccountId("keycloak-token")
                .setClientId("clientId")
                .setClientSecret("secret")
                .setRedirectURL("http://oauth2callback")
                .setScopes(Arrays.asList("openid"))
                .addAdditionalAuthorizationParam((Pair.create("grant_type", "password")))
                .addAdditionalAuthorizationParam((Pair.create("username", "aUserName")))
                .addAdditionalAuthorizationParam((Pair.create("password", "aPassword")))
                .asModule();


        authzModule.requestAccess(this, new Callback<String>() {
            @Override
            public void onSuccess(String o) {
                Log.d("TOKEN ", o);
            }

            @Override
            public void onFailure(Exception e) {
                System.err.println("Error!!");
                Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
            }
        });

    } catch (Exception e) {

        e.printStackTrace();
        throw new RuntimeException(e);
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,这没有任何作用。我不明白的是:

  1. 如何在 Aerogear 中使用 Keycloak 指定我正在执行的操作和 OpenID Connect?
  2. 如何以及在哪里发送用户名和密码?
  3. 如何指定 grant_type?(如果我不包含这个,我到服务器的 HTTP POST 将不起作用,所以这很重要)

任何帮助将不胜感激

mas*_*ick 6

Authorization Code如果您采用访问类型= (无 clientSecret)的标准流程public client,那么您可以查看我的示例 Android 本机应用程序

简而言之,您可以在 a 中打开一个浏览器窗口WebViewauthorization code通过解析返回的 url 中的查询参数来获取 ,并通过 POST 请求将其(代码)交换为令牌。

如果你使用Retrofit,那么这里是REST接口:

interface IKeycloakRest {
    @POST("token")
    @FormUrlEncoded
    fun grantNewAccessToken(
        @Field("code")         code: String,
        @Field("client_id")    clientId: String,
        @Field("redirect_uri") uri: String,
        @Field("grant_type")   grantType: String = "authorization_code"
    ): Observable<KeycloakToken>

    @POST("token")
    @FormUrlEncoded
    fun refreshAccessToken(
        @Field("refresh_token") refreshToken: String,
        @Field("client_id")     clientId: String,
        @Field("grant_type")    grantType: String = "refresh_token"
    ): Observable<KeycloakToken>

    @POST("logout")
    @FormUrlEncoded
    fun logout(
        @Field("client_id")     clientId: String,
        @Field("refresh_token") refreshToken: String
    ): Completable
}

data class KeycloakToken(
    @SerializedName("access_token")       var accessToken: String? = null,
    @SerializedName("expires_in")         var expiresIn: Int? = null,
    @SerializedName("refresh_expires_in") var refreshExpiresIn: Int? = null,
    @SerializedName("refresh_token")      var refreshToken: String? = null
)
Run Code Online (Sandbox Code Playgroud)

及其实例化:

val rest: IKeycloakRest = Retrofit.Builder()
            .baseUrl("https://[KEYCLOAK-URL]/auth/realms/[REALM]/protocol/openid-connect/")
            .addConverterFactory(GsonConverterFactory.create(GsonBuilder().setLenient().create()))
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()
            .create(IKeycloakRest::class.java)
Run Code Online (Sandbox Code Playgroud)


zap*_*tec 2

我也在使用 AeroGear,我发现我也遇到了同样的问题。然后我所做的就是(除了 Tolis Emmanouilidis 所说的其他配置信息之外)在 Manifest 中添加 Auth 服务。

尝试添加<service android:name="org.jboss.aerogear.android.authorization.oauth2.OAuth2AuthzService"/>到您的清单中

完成此操作后,它就会正常工作,您可以检索不记名令牌。