Allow clients to authenticate using form post #6

Manually merged
ansv7779 merged 1 commits from client-auth-form into main 2025-05-08 16:00:01 +02:00
2 changed files with 106 additions and 4 deletions
Showing only changes of commit e9a82c0135 - Show all commits

View File

@ -170,9 +170,9 @@ public class ClientManager implements RegisteredClientRepository, ClientManageme
}
private static RegisteredClient toRegisteredClient(final ClientRow clientRow) {
ClientAuthenticationMethod clientAuthenticationMethod = clientRow.isPublic()
? ClientAuthenticationMethod.NONE
: ClientAuthenticationMethod.CLIENT_SECRET_BASIC;
Set<ClientAuthenticationMethod> clientAuthenticationMethods = clientRow.isPublic()
? Set.of(ClientAuthenticationMethod.NONE)
: Set.of(ClientAuthenticationMethod.CLIENT_SECRET_BASIC, ClientAuthenticationMethod.CLIENT_SECRET_POST);
return RegisteredClient.withId(clientRow.id())
.clientId(clientRow.clientId())
.clientSecret(clientRow.clientSecret())
@ -191,7 +191,7 @@ public class ClientManager implements RegisteredClientRepository, ClientManageme
grantTypes.add(AuthorizationGrantType.REFRESH_TOKEN);
}
})
.clientAuthenticationMethod(clientAuthenticationMethod)
.clientAuthenticationMethods(methods -> methods.addAll(clientAuthenticationMethods))
.tokenSettings(TokenSettings.builder()
.accessTokenFormat(OAuth2TokenFormat.SELF_CONTAINED)
.accessTokenTimeToLive(Duration.ofHours(1))

View File

@ -0,0 +1,102 @@
package se.su.dsv.oauth2;
import com.nimbusds.jwt.JWTClaimsSet;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.oauth2.admin.ClientData;
import se.su.dsv.oauth2.admin.ClientManager;
import se.su.dsv.oauth2.admin.NewClient;
import java.net.URI;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static se.su.dsv.oauth2.ShibbolethRequestProcessor.remoteUser;
@SpringBootTest
@Transactional
@Rollback
public class ClientAuthenticationTest extends AbstractMetadataCodeFlowTest {
public static final String REDIRECT_URI = "http://localhost";
@Autowired
ClientManager clientManager;
private NewClient client;
@BeforeEach
public void registerClient() {
ClientData clientData = new ClientData("test-client", URI.create(REDIRECT_URI), false,
Set.of(), "test@localhost", false);
client = clientManager.createClient(() -> "test@local", clientData);
}
@Test
public void authenticate_client_using_http_basic() throws Exception {
String principal = "user";
MvcResult authorizeResult = mockMvc.perform(get(getAuthorizationEndpoint())
.with(remoteUser(principal))
.queryParam("response_type", "code")
.queryParam("client_id", client.clientId())
.queryParam("redirect_uri", REDIRECT_URI))
.andExpect(status().is3xxRedirection())
.andReturn();
String code = extractCode(authorizeResult.getResponse().getRedirectedUrl());
MvcResult tokenResult = mockMvc.perform(post(getTokenEndpoint())
.with(httpBasic(client.clientId(), client.clientSecret()))
.param("grant_type", "authorization_code")
.param("code", code)
.param("redirect_uri", REDIRECT_URI))
.andExpect(status().isOk())
.andReturn();
TokenResponse tokenResponse = getTokenResponse(tokenResult);
assertNotNull(tokenResponse.accessToken());
JWTClaimsSet claims = verifyToken(tokenResponse.accessToken());
assertEquals(principal, claims.getSubject());
}
@Test
public void authenticate_client_using_form_post() throws Exception {
String principal = "user";
MvcResult authorizeResult = mockMvc.perform(get(getAuthorizationEndpoint())
.with(remoteUser(principal))
.queryParam("response_type", "code")
.queryParam("client_id", client.clientId())
.queryParam("redirect_uri", REDIRECT_URI))
.andExpect(status().is3xxRedirection())
.andReturn();
String code = extractCode(authorizeResult.getResponse().getRedirectedUrl());
MvcResult tokenResult = mockMvc.perform(post(getTokenEndpoint())
.param("grant_type", "authorization_code")
.param("code", code)
.param("client_id", client.clientId())
.param("client_secret", client.clientSecret())
.param("redirect_uri", REDIRECT_URI))
.andExpect(status().isOk())
.andReturn();
TokenResponse tokenResponse = getTokenResponse(tokenResult);
assertNotNull(tokenResponse.accessToken());
JWTClaimsSet claims = verifyToken(tokenResponse.accessToken());
assertEquals(principal, claims.getSubject());
}
}