From bcba2d00b321edd612845f75c19543dd04517117 Mon Sep 17 00:00:00 2001 From: Dusan Jakub Date: Fri, 15 Sep 2023 15:06:58 +0200 Subject: [PATCH] Implicit flow --- .../java/com/ysoft/geecon/OAuthResource.java | 25 +++++++++++++----- .../java/com/ysoft/geecon/dto/AuthParams.java | 10 +++++-- .../geecon/dto/AuthorizationSession.java | 26 ++++++++++++++++--- .../com/ysoft/geecon/repo/SessionsRepo.java | 19 +++++++++----- 4 files changed, 61 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/ysoft/geecon/OAuthResource.java b/src/main/java/com/ysoft/geecon/OAuthResource.java index 62a022b..812de81 100644 --- a/src/main/java/com/ysoft/geecon/OAuthResource.java +++ b/src/main/java/com/ysoft/geecon/OAuthResource.java @@ -16,7 +16,6 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.UriBuilder; import java.util.List; -import java.util.Optional; @Path("/auth") public class OAuthResource { @@ -69,12 +68,24 @@ public class OAuthResource { } } - String authCode = sessionsRepo.finishSession(sessionId, scopes); - return Response.seeOther(UriBuilder.fromUri(params.getRedirectUri()) - .queryParam("code", authCode) - .queryParam("state", params.getState()) - .build()) - .build(); + session = sessionsRepo.authorizeSession(sessionId, scopes); + + var responseTypes = params.getResponseTypes(); + + UriBuilder uri = UriBuilder.fromUri(params.getRedirectUri()) + .fragment("") + .queryParam("state", params.getState()); + + if (responseTypes.contains(AuthParams.ResponseType.code)) { + uri.queryParam("code", sessionsRepo.generateAuthorizationCode(sessionId)); + } + if (responseTypes.contains(AuthParams.ResponseType.token)) { + uri.queryParam("access_token", session.tokens().accessToken()); + } + if (responseTypes.contains(AuthParams.ResponseType.id_token)) { + uri.queryParam("id_token", session.tokens().idToken()); + } + return Response.seeOther(uri.build()).build(); } @POST diff --git a/src/main/java/com/ysoft/geecon/dto/AuthParams.java b/src/main/java/com/ysoft/geecon/dto/AuthParams.java index d2099c4..bcc9f74 100644 --- a/src/main/java/com/ysoft/geecon/dto/AuthParams.java +++ b/src/main/java/com/ysoft/geecon/dto/AuthParams.java @@ -6,6 +6,12 @@ import java.util.Arrays; import java.util.List; public class AuthParams { + public List getResponseTypes() { + return responseType == null ? List.of() : Arrays.stream(responseType.split(" ")) + .map(ResponseType::valueOf) + .toList(); + } + @RestQuery("login_hint") String loginHint; @RestQuery("response_type") @@ -31,8 +37,8 @@ public class AuthParams { return responseType; } - public void setResponseType(String responseType) { - this.responseType = responseType; + public enum ResponseType { + code, token, id_token } public String getClientId() { diff --git a/src/main/java/com/ysoft/geecon/dto/AuthorizationSession.java b/src/main/java/com/ysoft/geecon/dto/AuthorizationSession.java index 547bb43..5b55f85 100644 --- a/src/main/java/com/ysoft/geecon/dto/AuthorizationSession.java +++ b/src/main/java/com/ysoft/geecon/dto/AuthorizationSession.java @@ -1,18 +1,36 @@ package com.ysoft.geecon.dto; +import com.ysoft.geecon.repo.SecureRandomStrings; + import java.util.List; -public record AuthorizationSession(AuthParams params, OAuthClient client, User user, List acceptedScopes) { +public record AuthorizationSession(AuthParams params, + OAuthClient client, + User user, + List acceptedScopes, + AccessTokenResponse tokens) { public AuthorizationSession(AuthParams params, OAuthClient client) { - this(params, client, null, null); + this(params, client, null, null, null); } public AuthorizationSession withUser(User user) { - return new AuthorizationSession(params, client, user, acceptedScopes); + return new AuthorizationSession(params, client, user, acceptedScopes, tokens); } public AuthorizationSession withScopes(List acceptedScopes) { - return new AuthorizationSession(params, client, user, acceptedScopes); + return new AuthorizationSession(params, client, user, acceptedScopes, tokens); + } + + public AuthorizationSession withGeneratedTokens() { + String idToken = null; + var tokens = new AccessTokenResponse("Bearer", + 8400, + SecureRandomStrings.alphanumeric(50), + scope(), + SecureRandomStrings.alphanumeric(50), + idToken + ); + return new AuthorizationSession(params, client, user, acceptedScopes, tokens); } public String scope() { diff --git a/src/main/java/com/ysoft/geecon/repo/SessionsRepo.java b/src/main/java/com/ysoft/geecon/repo/SessionsRepo.java index 951f08d..658282e 100644 --- a/src/main/java/com/ysoft/geecon/repo/SessionsRepo.java +++ b/src/main/java/com/ysoft/geecon/repo/SessionsRepo.java @@ -1,6 +1,9 @@ package com.ysoft.geecon.repo; -import com.ysoft.geecon.dto.*; +import com.ysoft.geecon.dto.AuthParams; +import com.ysoft.geecon.dto.AuthorizationSession; +import com.ysoft.geecon.dto.OAuthClient; +import com.ysoft.geecon.dto.User; import jakarta.enterprise.context.ApplicationScoped; import java.util.*; @@ -20,11 +23,9 @@ public class SessionsRepo { return id; } - public String finishSession(String sessionId, List acceptedScopes) { - Objects.requireNonNull(authorizationSessions.computeIfPresent(sessionId, (id, s) -> s.withScopes(acceptedScopes))); - var authCode = SecureRandomStrings.alphanumeric(10); - sessionsByAuthorizationCode.put(authCode, sessionId); - return authCode; + public AuthorizationSession authorizeSession(String sessionId, List acceptedScopes) { + return Objects.requireNonNull(authorizationSessions.computeIfPresent(sessionId, + (id, s) -> s.withScopes(acceptedScopes).withGeneratedTokens())); } @@ -32,6 +33,12 @@ public class SessionsRepo { return Objects.requireNonNull(authorizationSessions.computeIfPresent(sessionId, (id, session) -> session.withUser(user))); } + public String generateAuthorizationCode(String sessionId) { + var authCode = SecureRandomStrings.alphanumeric(10); + sessionsByAuthorizationCode.put(authCode, sessionId); + return authCode; + } + public Optional redeemAuthorizationCode(String authorizationCode) { var sessionId = Optional.ofNullable(sessionsByAuthorizationCode.get(authorizationCode)); sessionId.ifPresent(_id -> sessionsByAuthorizationCode.remove(authorizationCode));