Implement support for user consent #4

Manually merged
ansv7779 merged 13 commits from user-consent into main 2025-04-25 10:22:44 +02:00
Showing only changes of commit 2ebf8c649d - Show all commits

View File

@ -18,10 +18,12 @@ import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationException; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationException;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationToken; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationConsentAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2AuthorizationCodeRequestAuthenticationConverter; import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2AuthorizationCodeRequestAuthenticationConverter;
import org.springframework.security.web.DefaultRedirectStrategy; import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy; import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.security.web.util.RedirectUrlBuilder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
@ -117,15 +119,21 @@ public class CustomAuthorizationEndpointFilter extends HttpFilter {
Authentication authenticatedPrincipal = authenticationManager.authenticate(principal); Authentication authenticatedPrincipal = authenticationManager.authenticate(principal);
Authentication normalCodeRequest = authenticationConverter.convert(withGetMethod(request)); Authentication normalCodeRequest = authenticationConverter.convert(withGetMethod(request));
Authentication codeRequest = overridePrincipal(authenticatedPrincipal, (OAuth2AuthorizationCodeRequestAuthenticationToken) normalCodeRequest); OAuth2AuthorizationCodeRequestAuthenticationToken codeRequestAuthenticationToken = (OAuth2AuthorizationCodeRequestAuthenticationToken) normalCodeRequest;
Authentication codeRequest = overridePrincipal(authenticatedPrincipal, codeRequestAuthenticationToken);
Authentication authenticatedCodeRequest = authenticationManager.authenticate(codeRequest); Authentication authenticatedCodeRequest = authenticationManager.authenticate(codeRequest);
if (!authenticatedCodeRequest.isAuthenticated()) { if (!authenticatedCodeRequest.isAuthenticated()) {
String authorizationUrl = getAuthorizationUrl(request); String authorizationUrl = getAuthorizationUrl(request);
respondWithTemplate(response, templates.authorize(authorizationUrl, loggedInUser.getName(), (ShibbolethAuthenticationDetails) authenticatedPrincipal)); respondWithTemplate(response, templates.authorize(authorizationUrl, loggedInUser.getName(), (ShibbolethAuthenticationDetails) authenticatedPrincipal));
} else { } else {
sendAuthorizationResponse(request, response, authenticatedCodeRequest); if (authenticatedCodeRequest instanceof OAuth2AuthorizationCodeRequestAuthenticationToken authenticatedCodeRequestAuthenticationToken) {
sendAuthorizationResponse(request, response, authenticatedCodeRequestAuthenticationToken);
} else if (authenticatedCodeRequest instanceof OAuth2AuthorizationConsentAuthenticationToken consent) {
sendConsentResponse(request, response, codeRequestAuthenticationToken, consent);
} else {
response.sendError(HttpStatus.INTERNAL_SERVER_ERROR.value(), "Invalid authentication token");
}
} }
} }
@ -188,10 +196,12 @@ public class CustomAuthorizationEndpointFilter extends HttpFilter {
output.writeTo(response.getOutputStream()); output.writeTo(response.getOutputStream());
} }
private void sendAuthorizationResponse(HttpServletRequest request, HttpServletResponse response, private void sendAuthorizationResponse(
Authentication authentication) throws IOException { HttpServletRequest request,
HttpServletResponse response,
OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication = (OAuth2AuthorizationCodeRequestAuthenticationToken) authentication; OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication)
throws IOException
{
UriComponentsBuilder uriBuilder = UriComponentsBuilder UriComponentsBuilder uriBuilder = UriComponentsBuilder
.fromUriString(authorizationCodeRequestAuthentication.getRedirectUri()) .fromUriString(authorizationCodeRequestAuthentication.getRedirectUri())
.queryParam(OAuth2ParameterNames.CODE, .queryParam(OAuth2ParameterNames.CODE,
@ -240,4 +250,31 @@ public class CustomAuthorizationEndpointFilter extends HttpFilter {
String redirectUri = uriBuilder.build(true).toUriString(); String redirectUri = uriBuilder.build(true).toUriString();
this.redirectStrategy.sendRedirect(request, response, redirectUri); this.redirectStrategy.sendRedirect(request, response, redirectUri);
} }
private void sendConsentResponse(
HttpServletRequest request,
HttpServletResponse response,
OAuth2AuthorizationCodeRequestAuthenticationToken codeRequestAuthenticationToken,
OAuth2AuthorizationConsentAuthenticationToken consent)
throws IOException
{
Set<String> requestedScopes = codeRequestAuthenticationToken.getScopes();
String consentUri = resolveConsentUri(request, "/oauth2/consent");
String redirectUri = UriComponentsBuilder.fromUriString(consentUri)
.queryParam(OAuth2ParameterNames.SCOPE, String.join(" ", requestedScopes))
.queryParam(OAuth2ParameterNames.CLIENT_ID, consent.getClientId())
.queryParam(OAuth2ParameterNames.STATE, consent.getState())
.toUriString();
this.redirectStrategy.sendRedirect(request, response, redirectUri);
}
private String resolveConsentUri(HttpServletRequest request, String consentPage) {
RedirectUrlBuilder urlBuilder = new RedirectUrlBuilder();
urlBuilder.setScheme(request.getScheme());
urlBuilder.setServerName(request.getServerName());
urlBuilder.setPort(request.getServerPort());
urlBuilder.setContextPath(request.getContextPath());
urlBuilder.setPathInfo(consentPage);
return urlBuilder.getUrl();
}
} }