Skip to content

Commit 20e6a67

Browse files
authored
Auth Updates for CWMS-CLI Login (#1680)
Alters CDA published OpenID Connect metadata and improves local OIDC test coverage Changes: - remove the invalid HTTP auth scheme("openid") from the oIdConnect security scheme so Swagger publishes a correct oIdConnectUrl - add a focused test for openID security scheme - add debug logging for JWT validation failures to expose the underlying claim/signature issue during local auth setup - update local compose seed data so m5hectest has TS ID Creator in SWT, matching the documented/test write-user expectations Used this in testing - HydrologicEngineeringCenter/cwms-cli#155
1 parent 7fb0b5e commit 20e6a67

File tree

4 files changed

+60
-9
lines changed

4 files changed

+60
-9
lines changed

compose_files/sql/users.sql

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ begin
1919
cwms_sec.add_cwms_user('m5hectest', null, 'SWT');
2020
cwms_sec.add_user_to_group('m5hectest', 'All Users', 'SWT');
2121
cwms_sec.add_user_to_group('m5hectest', 'CWMS Users', 'SWT');
22+
cwms_sec.add_user_to_group('m5hectest', 'TS ID Creator', 'SWT');
2223
cwms_sec.add_cwms_user('q0hectest', null, 'SWT');
2324
cwms_sec.add_user_to_group('q0hectest', 'All Users', 'SWT');
2425
cwms_sec.add_user_to_group('q0hectest', 'CWMS Users', 'SWT');
@@ -50,6 +51,7 @@ begin
5051
cwms_sec.add_cwms_user('m5hectest',NULL,'SWT');
5152
cwms_sec.add_user_to_group('m5hectest','All Users', 'SWT');
5253
cwms_sec.add_user_to_group('m5hectest','CWMS Users', 'SWT');
54+
cwms_sec.add_user_to_group('m5hectest','TS ID Creator', 'SWT');
5355
execute immediate 'grant execute on cwms_20.cwms_upass to web_user';
5456

5557

@@ -60,4 +62,4 @@ begin
6062

6163
end;
6264
/
63-
quit;
65+
quit;

cwms-data-api/src/main/java/cwms/cda/security/OpenIDConfig.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,25 +56,28 @@ public URL getJwksUrl() {
5656
return jwksUrl;
5757
}
5858

59-
public SecurityScheme getScheme() {
60-
61-
59+
static SecurityScheme buildScheme(String wellKnownUrl, String clientId, String idpHint) {
6260
SecurityScheme scheme = new SecurityScheme().type(Type.OPENIDCONNECT)
63-
.openIdConnectUrl(wellKnown.toString())
64-
.scheme("openid");
65-
if (idp_hint != null)
61+
.openIdConnectUrl(wellKnownUrl);
62+
if (idpHint != null)
6663
{
6764
Map<String, Object> hint = new HashMap<>();
6865
hint.put("query-parameter", "kc_idp_hint");
6966
ArrayList<String> values = new ArrayList<>();
70-
for (String value: idp_hint.split(",")) {
67+
for (String value: idpHint.split(",")) {
7168
values.add(value.trim());
7269
}
7370
hint.put("values", values);
7471
scheme.addExtension("x-kc_idp_hint", hint);
7572
}
7673

77-
scheme.addExtension("x-oidc-client-id", client_id);
74+
scheme.addExtension("x-oidc-client-id", clientId);
75+
return scheme;
76+
}
77+
78+
public SecurityScheme getScheme() {
79+
80+
SecurityScheme scheme = buildScheme(wellKnown.toString(), client_id, idp_hint);
7881
return scheme;
7982
}
8083
}

cwms-data-api/src/main/java/cwms/cda/security/OpenIdConnectIdentitityProvider.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ private DataApiPrincipal getUserFromToken(Context ctx) throws CwmsAuthException
115115
throw new CwmsAuthException("Not Authorized",HttpServletResponse.SC_UNAUTHORIZED);
116116
}
117117
} catch (NumberFormatException | JwtException ex) {
118+
log.atFine().withCause(ex).log(
119+
"JWT validation failed for bearer token from issuer configuration '%s'",
120+
System.getProperty(ISSUER_PROPERTY, System.getenv(ISSUER_PROPERTY))
121+
);
118122
throw new CwmsAuthException("JWT not valid",ex,HttpServletResponse.SC_UNAUTHORIZED);
119123
}
120124
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package cwms.cda.security;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertFalse;
5+
import static org.junit.jupiter.api.Assertions.assertNotNull;
6+
import static org.junit.jupiter.api.Assertions.assertTrue;
7+
8+
import io.swagger.v3.oas.models.security.SecurityScheme;
9+
import java.util.List;
10+
import java.util.Map;
11+
import org.junit.jupiter.api.Test;
12+
13+
class OpenIDConfigTest {
14+
15+
@Test
16+
void buildSchemeUsesWellKnownDiscoveryUrlWithoutHttpAuthScheme() {
17+
SecurityScheme scheme = OpenIDConfig.buildScheme(
18+
"https://identityc.sec.usace.army.mil/auth/realms/cwbi/.well-known/openid-configuration",
19+
"cwms",
20+
"federation-eams, login.gov"
21+
);
22+
23+
assertEquals(SecurityScheme.Type.OPENIDCONNECT, scheme.getType());
24+
assertEquals(
25+
"https://identityc.sec.usace.army.mil/auth/realms/cwbi/.well-known/openid-configuration",
26+
scheme.getOpenIdConnectUrl()
27+
);
28+
assertTrue(scheme.getScheme() == null || scheme.getScheme().isEmpty());
29+
assertNotNull(scheme.getExtensions());
30+
assertEquals("cwms", scheme.getExtensions().get("x-oidc-client-id"));
31+
32+
@SuppressWarnings("unchecked")
33+
Map<String, Object> hint = (Map<String, Object>) scheme.getExtensions().get("x-kc_idp_hint");
34+
assertNotNull(hint);
35+
assertEquals("kc_idp_hint", hint.get("query-parameter"));
36+
37+
@SuppressWarnings("unchecked")
38+
List<String> values = (List<String>) hint.get("values");
39+
assertEquals(List.of("federation-eams", "login.gov"), values);
40+
assertFalse(scheme.getExtensions().containsKey("flows"));
41+
}
42+
}

0 commit comments

Comments
 (0)