-
Notifications
You must be signed in to change notification settings - Fork 824
/
OIDCLoginIT.java
243 lines (206 loc) · 11.5 KB
/
OIDCLoginIT.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
/*******************************************************************************
* Cloud Foundry
* Copyright (c) [2009-2016] Pivotal Software, Inc. All Rights Reserved.
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
*
* This product includes a number of subcomponents with
* separate copyright notices and license terms. Your use of these
* subcomponents is subject to the terms and conditions of the
* subcomponent's license, as noted in the LICENSE file.
*******************************************************************************/
package org.cloudfoundry.identity.uaa.integration.feature;
import com.fasterxml.jackson.core.type.TypeReference;
import org.cloudfoundry.identity.uaa.ServerRunning;
import org.cloudfoundry.identity.uaa.constants.OriginKeys;
import org.cloudfoundry.identity.uaa.integration.util.IntegrationTestUtils;
import org.cloudfoundry.identity.uaa.integration.util.ScreenshotOnFail;
import org.cloudfoundry.identity.uaa.login.test.LoginServerClassRunner;
import org.cloudfoundry.identity.uaa.oauth.jwt.JwtHelper;
import org.cloudfoundry.identity.uaa.oauth.token.ClaimConstants;
import org.cloudfoundry.identity.uaa.provider.AbstractXOAuthIdentityProviderDefinition;
import org.cloudfoundry.identity.uaa.provider.IdentityProvider;
import org.cloudfoundry.identity.uaa.provider.OIDCIdentityProviderDefinition;
import org.cloudfoundry.identity.uaa.test.UaaTestAccounts;
import org.cloudfoundry.identity.uaa.util.JsonUtils;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.By;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.opensaml.saml2.core.AuthnContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.oauth2.client.test.TestAccounts;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.web.client.RestOperations;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.cloudfoundry.identity.uaa.integration.util.IntegrationTestUtils.getZoneAdminToken;
import static org.cloudfoundry.identity.uaa.provider.ExternalIdentityProviderDefinition.USER_NAME_ATTRIBUTE_NAME;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
@RunWith(LoginServerClassRunner.class)
@ContextConfiguration(classes = DefaultIntegrationTestConfig.class)
public class OIDCLoginIT {
@Autowired @Rule
public IntegrationTestRule integrationTestRule;
@Rule
public ScreenshotOnFail screenShootRule = new ScreenshotOnFail();
@Autowired
RestOperations restOperations;
@Autowired
WebDriver webDriver;
@Value("${integration.test.base_url}")
String baseUrl;
@Value("${integration.test.app_url}")
String appUrl;
@Autowired
TestAccounts testAccounts;
@Autowired
TestClient testClient;
ServerRunning serverRunning = ServerRunning.isRunning();
private boolean isSetUp = false;
@Before
public void setUp() throws Exception {
if (!isSetUp) {
doLogout();
}
isSetUp = true;
screenShootRule.setWebDriver(webDriver);
}
@After
public void tearDown() {
doLogout();
}
private void doLogout() {
webDriver.get(baseUrl + "/logout.do");
webDriver.manage().deleteAllCookies();
webDriver.get("https://oidc10.identity.cf-app.com/logout.do");
webDriver.get("http://simplesamlphp.cfapps.io/module.php/core/authenticate.php?as=example-userpass&logout");
}
@After
public void deleteProvider() throws Exception {
IntegrationTestUtils.deleteProvider(getZoneAdminToken(baseUrl, serverRunning), baseUrl, "uaa", "puppy");
}
@Test
public void successfulLoginWithOIDCProvider() throws Exception {
createOIDCProviderWithRequestedScopes();
webDriver.get(baseUrl + "/login");
webDriver.findElement(By.linkText("My OIDC Provider")).click();
Assert.assertThat(webDriver.getCurrentUrl(), Matchers.containsString("oidc10.identity.cf-app.com"));
webDriver.findElement(By.name("username")).sendKeys("marissa");
webDriver.findElement(By.name("password")).sendKeys("koala");
webDriver.findElement(By.xpath("//input[@value='Sign in']")).click();
Assert.assertThat(webDriver.getCurrentUrl(), Matchers.containsString("localhost"));
assertThat(webDriver.findElement(By.cssSelector("h1")).getText(), Matchers.containsString("Where to?"));
webDriver.findElement(By.cssSelector(".dropdown-trigger")).click();
webDriver.findElement(By.linkText("Sign Out")).click();
IntegrationTestUtils.validateAccountChooserCookie(baseUrl, webDriver);
}
@Test
public void successfulLoginWithOIDC_and_SAML_Provider() throws Exception {
/*
This test creates an OIDC provider. That provider in turn has a SAML provider.
The end user is authenticated using
*/
createOIDCProviderWithRequestedScopes();
webDriver.get(baseUrl + "/login");
webDriver.findElement(By.linkText("My OIDC Provider")).click();
Assert.assertThat(webDriver.getCurrentUrl(), Matchers.containsString("oidc10.identity.cf-app.com"));
webDriver.findElement(By.linkText("SAML Login")).click();
webDriver.findElement(By.xpath("//h2[contains(text(), 'Enter your username and password')]"));
webDriver.findElement(By.name("username")).clear();
webDriver.findElement(By.name("username")).sendKeys("marissa6");
webDriver.findElement(By.name("password")).sendKeys("saml6");
webDriver.findElement(By.xpath("//input[@value='Login']")).click();
Assert.assertThat(webDriver.getCurrentUrl(), Matchers.containsString("localhost"));
assertThat(webDriver.findElement(By.cssSelector("h1")).getText(), Matchers.containsString("Where to?"));
Cookie cookie= webDriver.manage().getCookieNamed("JSESSIONID");
System.out.println("cookie = " + String.format("%s=%s",cookie.getName(), cookie.getValue()));
Map<String,String> authCodeTokenResponse = IntegrationTestUtils.getAuthorizationCodeTokenMap(serverRunning,
UaaTestAccounts.standard(serverRunning),
"login",
"loginsecret",
null,
null,
"token id_token",
cookie.getValue(),
baseUrl,
false);
//validate that we have an ID token, and that it contains costCenter and manager values
String idToken = authCodeTokenResponse.get("id_token");
assertNotNull(idToken);
Jwt idTokenClaims = JwtHelper.decode(idToken);
Map<String, Object> claims = JsonUtils.readValue(idTokenClaims.getClaims(), new TypeReference<Map<String, Object>>() {});
assertNotNull("id_token should contain ACR claim", claims.get(ClaimConstants.ACR));
Map<String,Object> acr = (Map<String, Object>) claims.get(ClaimConstants.ACR);
assertNotNull("acr claim should contain values attribute", acr.get("values"));
assertThat((List<String>) acr.get("values"), containsInAnyOrder(AuthnContext.PASSWORD_AUTHN_CTX));
}
@Test
public void successfulLoginWithOIDCProvider_withClientContext() throws Exception {
createOIDCProviderWithRequestedScopes();
webDriver.get(appUrl);
webDriver.findElement(By.linkText("My OIDC Provider")).click();
Assert.assertThat(webDriver.getCurrentUrl(), Matchers.containsString("oidc10.identity.cf-app.com"));
webDriver.findElement(By.name("username")).sendKeys("marissa");
webDriver.findElement(By.name("password")).sendKeys("koala");
webDriver.findElement(By.xpath("//input[@value='Sign in']")).click();
Assert.assertThat(webDriver.getCurrentUrl(), Matchers.containsString("localhost"));
Assert.assertEquals("Application Authorization", webDriver.findElement(By.cssSelector("h1")).getText());
}
@Test
public void scopesIncludedInAuthorizeRequest() throws Exception {
createOIDCProviderWithRequestedScopes();
webDriver.get(appUrl);
Assert.assertThat(webDriver.findElement(By.linkText("My OIDC Provider")).getAttribute("href"), Matchers.containsString("scope=openid+cloud_controller.read"));
}
@Test
public void scopesIncludedInAuthorizeRequest_When_Issuer_Set() throws Exception {
createOIDCProviderWithRequestedScopes("https://oidc10.identity.cf-app.com/oauth/token", "https://oidc10.identity.cf-app.com");
try {
webDriver.get(appUrl);
} finally {
IntegrationTestUtils.takeScreenShot(webDriver);
}
Assert.assertThat(webDriver.findElement(By.linkText("My OIDC Provider")).getAttribute("href"), Matchers.containsString("scope=openid+cloud_controller.read"));
}
private void createOIDCProviderWithRequestedScopes() throws Exception {
createOIDCProviderWithRequestedScopes(null, "https://oidc10.identity.cf-app.com");
}
private void createOIDCProviderWithRequestedScopes(String issuer, final String urlBase) throws Exception {
IdentityProvider<AbstractXOAuthIdentityProviderDefinition> identityProvider = new IdentityProvider<>();
identityProvider.setName("my oidc provider");
identityProvider.setIdentityZoneId(OriginKeys.UAA);
OIDCIdentityProviderDefinition config = new OIDCIdentityProviderDefinition();
config.addAttributeMapping(USER_NAME_ATTRIBUTE_NAME, "user_name");
config.setAuthUrl(new URL(urlBase + "/oauth/authorize"));
config.setTokenUrl(new URL(urlBase + "/oauth/token"));
config.setTokenKeyUrl(new URL(urlBase + "/token_key"));
config.setShowLinkText(true);
config.setLinkText("My OIDC Provider");
config.setSkipSslValidation(true);
config.setRelyingPartyId("identity");
config.setRelyingPartySecret("identitysecret");
config.setIssuer(issuer);
List<String> requestedScopes = new ArrayList<>();
requestedScopes.add("openid");
requestedScopes.add("cloud_controller.read");
config.setScopes(requestedScopes);
identityProvider.setConfig(config);
identityProvider.setOriginKey("puppy");
String clientCredentialsToken = IntegrationTestUtils.getClientCredentialsToken(baseUrl, "admin", "adminsecret");
IntegrationTestUtils.createOrUpdateProvider(clientCredentialsToken, baseUrl, identityProvider);
}
}