I want to authenticate a user (using his username and password) in an Android App using aerogear with a server using Keycloak. I haven't been able to do it, help me please.
I currently can authenticate the user without aerogear, but I want to use this library since it can help me to refresh the token when is needed. I authenticate the user making a POST call to the server like this (but from 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'
So the information I have is:
ie http://127.0.0.1:8080/auth/realms/example/protocol/openid-connect/token
What I have tried with Aerogear is this:
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);
}
}
However this doesn't do anything. What I don't understand is:
Any help would be very much appreciated
Keycloak supports both OpenID Connect (an extension to OAuth 2.0) and SAML 2.0.
Keycloak is Open Source Identity and Access Management Server, which is a OAuth2 and OpenID Connect(OIDC) protocol complaint.
Configure Keycloak to authenticate your cbioportal instance. Log in to your Keycloak Identity Provider, e.g. http://localhost:8080/auth, as an admin user. ⚠️ when setting this up on something else than localhost (e.g. production), you will need to use/enable https on your Keycloak server.
To create a new OAuth Client application in Keycloak, you will need to login to the Keycloak server and select the Realm for which the client application needs to be created. To learn how to create new Keycloak users and a new Realm, please check the following tutorial: Creating a new Keycloak user and a new Realm.
If all is good with the request and the client credentials get successfully validated by the authorization server, the authorization server will respond back with an access token right away. According to OAuth 2.0 specs, the Refresh Token should not be included in the response. But apparently, Keycloak does include the refresh token anyways.
To enable the Client Credentials Grant flow for the OAuth client application in Keycloak, follow these steps: 1 Open the Client application, 2 Select the Settings tab, 3 Enable the Service Accounts as it is shown in the image below, 4 Click on the Save button. More ...
Follow the below steps to find the client_id and the client_secret values for your OAuth client application in Keycloak. Open the Client application details in Keycloak, Switch to Credentials tab, Copy the Client Secret value. You will find the Client Id value on the Settings tab.
If you go with the standard Authorization Code
flow with access type = public client
(no clientSecret) then you may take a look at my example Android native app.
In short, you could open up a browser window in a WebView
, get the authorization code
by parsing the query parameter from the returned url and exchange it (the code) for the token via a POST request.
If you use Retrofit, then here is the REST interface:
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
)
And its instantiation:
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With