This is an automated email from the ASF dual-hosted git repository.

ofuks pushed a commit to branch DLAB-1156
in repository https://gitbox.apache.org/repos/asf/incubator-dlab.git

commit 5b1f7f9474054a769679a99642dec3b84e93f122
Author: ofuks <olegfuk...@gmail.com>
AuthorDate: Wed Oct 2 14:01:32 2019 +0300

    [DLAB-1156]: Created endpoint to get new access and refresh token in case 
when access token is expired
---
 .../src/main/java/com/epam/dlab/auth/UserInfo.java | 13 +++++++++--
 .../backendapi/resources/KeycloakResource.java     | 27 +++++++++++++++++++++-
 .../backendapi/service/SecurityServiceImpl.java    | 26 ++++++---------------
 .../epam/dlab/backendapi/util/KeycloakUtil.java    | 22 ++++++++++++++++++
 4 files changed, 66 insertions(+), 22 deletions(-)

diff --git 
a/services/dlab-webapp-common/src/main/java/com/epam/dlab/auth/UserInfo.java 
b/services/dlab-webapp-common/src/main/java/com/epam/dlab/auth/UserInfo.java
index b0c05bf..5c6a74f 100644
--- a/services/dlab-webapp-common/src/main/java/com/epam/dlab/auth/UserInfo.java
+++ b/services/dlab-webapp-common/src/main/java/com/epam/dlab/auth/UserInfo.java
@@ -32,6 +32,7 @@ public class UserInfo implements Principal {
 
     private final String username;
     private final String accessToken;
+    private String refreshToken;
     private final Set<String> roles = new HashSet<>();
     private final Map<String,String> keys = new HashMap<>();
 
@@ -66,6 +67,15 @@ public class UserInfo implements Principal {
         return accessToken;
     }
 
+    @JsonProperty("refresh_token")
+    public String getRefreshToken() {
+        return refreshToken;
+    }
+
+    public void setRefreshToken(String refreshToken) {
+        this.refreshToken = refreshToken;
+    }
+
     @JsonProperty("roles")
     public Set<String> getRoles() {
         return roles;
@@ -121,8 +131,6 @@ public class UserInfo implements Principal {
         return newInfo;
     }
 
-
-
     public boolean isAwsUser() {
         return awsUser;
     }
@@ -182,6 +190,7 @@ public class UserInfo implements Principal {
         return "UserInfo{" +
                 "username='" + username + '\'' +
                 ", accessToken='" + accessToken + '\'' +
+                ", refreshToken='" + refreshToken + '\'' +
                 ", roles=" + roles +
                 ", keys=" + keys.keySet() +
                 ", firstName='" + firstName + '\'' +
diff --git 
a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/KeycloakResource.java
 
b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/KeycloakResource.java
index e719215..0a6e6d2 100644
--- 
a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/KeycloakResource.java
+++ 
b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/KeycloakResource.java
@@ -5,9 +5,12 @@ import com.epam.dlab.backendapi.conf.KeycloakConfiguration;
 import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
 import com.epam.dlab.backendapi.dao.SecurityDAO;
 import com.epam.dlab.backendapi.roles.UserRoles;
+import com.epam.dlab.backendapi.service.KeycloakService;
 import com.epam.dlab.backendapi.service.SecurityService;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.inject.Inject;
 import io.dropwizard.auth.Auth;
+import org.keycloak.representations.AccessTokenResponse;
 
 import javax.ws.rs.*;
 import javax.ws.rs.core.MediaType;
@@ -24,6 +27,7 @@ public class KeycloakResource {
        private static final String KEYCLOAK_LOGOUT_URI_FORMAT = 
"%s/realms/%s/protocol/openid-connect/logout" +
                        "?redirect_uri=";
        private final SecurityService securityService;
+       private final KeycloakService keycloakService;
        private final SecurityDAO securityDAO;
        private final String loginUri;
        private final String logoutUri;
@@ -32,12 +36,13 @@ public class KeycloakResource {
 
        @Inject
        public KeycloakResource(SecurityService securityService, 
SelfServiceApplicationConfiguration configuration,
-                                                       SecurityDAO 
securityDAO) {
+                                                       SecurityDAO 
securityDAO, KeycloakService keycloakService) {
                this.securityDAO = securityDAO;
                this.defaultAccess = configuration.getRoleDefaultAccess();
                final KeycloakConfiguration keycloakConfiguration = 
configuration.getKeycloakConfiguration();
                this.redirectUri = keycloakConfiguration.getRedirectUri();
                this.securityService = securityService;
+               this.keycloakService = keycloakService;
 
                loginUri =
                                format(LOGIN_URI_FORMAT,
@@ -78,4 +83,24 @@ public class KeycloakResource {
                                .location(new URI(logoutUri + redirectUri))
                                .build();
        }
+
+       @POST
+       @Path("/refresh/{refresh_token}")
+       @Produces(MediaType.APPLICATION_JSON)
+       public Response refreshAccessToken(@PathParam("refresh_token") String 
refreshToken) {
+               AccessTokenResponse tokenResponse = 
keycloakService.refreshToken(refreshToken);
+               return Response.ok(new TokenInfo(tokenResponse.getToken(), 
tokenResponse.getRefreshToken())).build();
+       }
+
+       class TokenInfo {
+               @JsonProperty("access_token")
+               private final String accessToken;
+               @JsonProperty("refresh_token")
+               private final String refreshToken;
+
+               TokenInfo(String accessToken, String refreshToken) {
+                       this.accessToken = accessToken;
+                       this.refreshToken = refreshToken;
+               }
+       }
 }
diff --git 
a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityServiceImpl.java
 
b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityServiceImpl.java
index f2930cd..9b17d91 100644
--- 
a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityServiceImpl.java
+++ 
b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityServiceImpl.java
@@ -2,12 +2,10 @@ package com.epam.dlab.backendapi.service;
 
 import com.epam.dlab.auth.UserInfo;
 import com.epam.dlab.backendapi.dao.SecurityDAO;
+import com.epam.dlab.backendapi.util.KeycloakUtil;
 import com.epam.dlab.exceptions.DlabException;
 import com.google.inject.Inject;
-import org.keycloak.common.util.Base64Url;
 import org.keycloak.representations.AccessTokenResponse;
-import org.keycloak.representations.IDToken;
-import org.keycloak.util.JsonSerialization;
 
 public class SecurityServiceImpl implements SecurityService {
        private final KeycloakService keycloakService;
@@ -22,9 +20,11 @@ public class SecurityServiceImpl implements SecurityService {
        @Override
        public UserInfo getUserInfo(String code) {
                final AccessTokenResponse token = 
keycloakService.getToken(code);
-               final String username = 
parseToken(token.getToken()).getPreferredUsername();
+               final String username = 
KeycloakUtil.parseToken(token.getToken()).getPreferredUsername();
                securityDAO.saveUser(username, token);
-               return new UserInfo(username, token.getToken());
+               UserInfo userInfo = new UserInfo(username, token.getToken());
+               userInfo.setRefreshToken(token.getRefreshToken());
+               return userInfo;
        }
 
        @Override
@@ -32,20 +32,8 @@ public class SecurityServiceImpl implements SecurityService {
                return securityDAO.getTokenResponse(username)
                                .map(AccessTokenResponse::getRefreshToken)
                                .map(keycloakService::refreshToken)
-                               .map(accessTokenResponse -> new 
UserInfo(parseToken(accessTokenResponse.getToken()).getPreferredUsername(), 
accessTokenResponse.getToken()))
+                               .map(accessTokenResponse -> new 
UserInfo(KeycloakUtil.parseToken(accessTokenResponse.getToken()).getPreferredUsername(),
+                                               accessTokenResponse.getToken()))
                                .orElseThrow(() -> new DlabException("Can not 
find token for user " + username));
        }
-
-       private IDToken parseToken(String encoded) {
-               try {
-                       String[] parts = encoded.split("\\.");
-                       if (parts.length < 2 || parts.length > 3) {
-                               throw new IllegalArgumentException("Parsing 
error");
-                       }
-                       byte[] bytes = Base64Url.decode(parts[1]);
-                       return JsonSerialization.readValue(bytes, 
IDToken.class);
-               } catch (Exception e) {
-                       throw new DlabException("Can not parse token due to: " 
+ e.getMessage());
-               }
-       }
 }
diff --git 
a/services/self-service/src/main/java/com/epam/dlab/backendapi/util/KeycloakUtil.java
 
b/services/self-service/src/main/java/com/epam/dlab/backendapi/util/KeycloakUtil.java
new file mode 100644
index 0000000..63fc62c
--- /dev/null
+++ 
b/services/self-service/src/main/java/com/epam/dlab/backendapi/util/KeycloakUtil.java
@@ -0,0 +1,22 @@
+package com.epam.dlab.backendapi.util;
+
+import com.epam.dlab.exceptions.DlabException;
+import org.keycloak.common.util.Base64Url;
+import org.keycloak.representations.IDToken;
+import org.keycloak.util.JsonSerialization;
+
+public class KeycloakUtil {
+
+    public static IDToken parseToken(String encoded) {
+        try {
+            String[] parts = encoded.split("\\.");
+            if (parts.length < 2 || parts.length > 3) {
+                throw new IllegalArgumentException("Parsing error");
+            }
+            byte[] bytes = Base64Url.decode(parts[1]);
+            return JsonSerialization.readValue(bytes, IDToken.class);
+        } catch (Exception e) {
+            throw new DlabException("Can not parse token due to: " + 
e.getMessage());
+        }
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@dlab.apache.org
For additional commands, e-mail: commits-h...@dlab.apache.org

Reply via email to