Skip to content

Commit e03a7ea

Browse files
feat: transfer idToken claims to session (#2865)
* feat: transfer idToken claims to session * fixed NPE * fixed assertion * added 'getSession' scripting function --------- Co-authored-by: Christian Gördes <118011644+christiangoerdes@users.noreply.github.com>
1 parent 6a5092e commit e03a7ea

File tree

7 files changed

+333
-0
lines changed

7 files changed

+333
-0
lines changed

core/src/main/java/com/predic8/membrane/core/interceptor/oauth2client/rf/SessionAuthorizer.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public void setSkipUserInfo(boolean skip) {
7272
}
7373

7474
public void authorizeSession(Map<String, Object> userInfo, Session session, String authSubject) {
75+
userInfo.forEach((k, v) -> { if (v != null) { session.put("idToken." + k, v); } });
7576

7677
session.put("headerX-Authenticated-" + convertFirstLetterToUpper(authSubject), getUsername(userInfo, auth));
7778

core/src/main/java/com/predic8/membrane/core/lang/CommonBuiltInFunctions.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.predic8.membrane.core.http.Message;
77
import com.predic8.membrane.core.interceptor.AbstractInterceptorWithSession;
88
import com.predic8.membrane.core.interceptor.Interceptor.Flow;
9+
import com.predic8.membrane.core.interceptor.session.Session;
910
import com.predic8.membrane.core.security.BasicHttpSecurityScheme;
1011
import com.predic8.membrane.core.security.SecurityScheme;
1112
import org.slf4j.Logger;
@@ -129,6 +130,16 @@ public static boolean isLoggedIn(String beanName, Exchange exc) {
129130
}
130131
}
131132

133+
public static Session getSession(String beanName, Exchange exc) {
134+
try {
135+
return ((AbstractInterceptorWithSession) requireNonNull(exc.getHandler().getTransport().getRouter().getBeanFactory()).getBean(beanName))
136+
.getSessionManager().getSession(exc);
137+
} catch (Exception e) {
138+
log.info("Failed to resolve bean with name '{}'", beanName);
139+
return null;
140+
}
141+
}
142+
132143
public static long getDefaultSessionLifetime(String beanName, Exchange exc) {
133144
try {
134145
return ((AbstractInterceptorWithSession) requireNonNull(exc.getHandler().getTransport().getRouter().getBeanFactory()).getBean(beanName))

core/src/main/java/com/predic8/membrane/core/lang/groovy/GroovyBuiltInFunctions.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.predic8.membrane.core.exchange.Exchange;
44
import com.predic8.membrane.core.interceptor.Interceptor.Flow;
5+
import com.predic8.membrane.core.interceptor.session.Session;
56
import com.predic8.membrane.core.lang.CommonBuiltInFunctions;
67
import groovy.lang.GroovyObjectSupport;
78

@@ -75,6 +76,10 @@ public boolean isLoggedIn(String beanName) {
7576
return CommonBuiltInFunctions.isLoggedIn(beanName, exchange);
7677
}
7778

79+
public Session getSession(String beanName) {
80+
return CommonBuiltInFunctions.getSession(beanName, exchange);
81+
}
82+
7883
public long getDefaultSessionLifetime(String beanName) {
7984
return CommonBuiltInFunctions.getDefaultSessionLifetime(beanName, exchange);
8085
}

core/src/main/java/com/predic8/membrane/core/lang/spel/functions/SpELBuiltInFunctions.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
limitations under the License. */
1414
package com.predic8.membrane.core.lang.spel.functions;
1515

16+
import com.predic8.membrane.core.interceptor.session.Session;
1617
import com.predic8.membrane.core.lang.CommonBuiltInFunctions;
1718
import com.predic8.membrane.core.lang.spel.SpELExchangeEvaluationContext;
1819

@@ -40,6 +41,10 @@ public static boolean isLoggedIn(String beanName, SpELExchangeEvaluationContext
4041
return CommonBuiltInFunctions.isLoggedIn(beanName, ctx.getExchange());
4142
}
4243

44+
public static Session getSession(String beanName, SpELExchangeEvaluationContext ctx) {
45+
return CommonBuiltInFunctions.getSession(beanName, ctx.getExchange());
46+
}
47+
4348
public static long getDefaultSessionLifetime(String beanName, SpELExchangeEvaluationContext ctx) {
4449
return CommonBuiltInFunctions.getDefaultSessionLifetime(beanName, ctx.getExchange());
4550
}

core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/b2c/B2CMembrane.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919
import com.predic8.membrane.core.exchange.*;
2020
import com.predic8.membrane.core.http.*;
2121
import com.predic8.membrane.core.interceptor.*;
22+
import com.predic8.membrane.core.interceptor.flow.ReturnInterceptor;
2223
import com.predic8.membrane.core.interceptor.oauth2.*;
2324
import com.predic8.membrane.core.interceptor.oauth2.authorizationservice.*;
2425
import com.predic8.membrane.core.interceptor.oauth2client.*;
2526
import com.predic8.membrane.core.interceptor.session.*;
27+
import com.predic8.membrane.core.interceptor.templating.TemplateInterceptor;
2628
import com.predic8.membrane.core.proxies.*;
2729
import org.jetbrains.annotations.*;
2830

@@ -88,7 +90,9 @@ public void init() {
8890
});
8991
ServiceProxy sp7_requireAuth = createRequireAuthServiceProxy(tc.api2Id, "/api2/", ra -> ra.setScope("https://localhost/" + tc.api2Id + "/Read"));
9092
ServiceProxy sp8_afterLogout = createAfterLogoutServiceProxy();
93+
ServiceProxy sp9_getClaim = createGetClaimProxy();
9194

95+
oauth2Resource.getRuleManager().addProxy(sp9_getClaim, MANUAL);
9296
oauth2Resource.getRuleManager().addProxy(sp8_afterLogout, MANUAL);
9397
oauth2Resource.getRuleManager().addProxy(sp7_requireAuth, MANUAL);
9498
oauth2Resource.getRuleManager().addProxy(sp6_requireAuth_ErrorStatus403, MANUAL);
@@ -99,6 +103,9 @@ public void init() {
99103
oauth2Resource.getRuleManager().addProxy(sp1_oauth2resource2, MANUAL);
100104
oauth2Resource.start();
101105

106+
FakeApplicationContext applicationContext = new FakeApplicationContext();
107+
applicationContext.registerBean("oauth2", oAuth2Resource2Interceptor);
108+
oauth2Resource.setApplicationContext(applicationContext);
102109
}
103110

104111
public void stop() {
@@ -201,6 +208,21 @@ public Outcome handleRequest(Exchange exc) {
201208
return sp;
202209
}
203210

211+
private ServiceProxy createGetClaimProxy() {
212+
ServiceProxy sp = new ServiceProxy(new ServiceProxyKey(tc.clientPort), null, 99999);
213+
Path p = new Path();
214+
p.setUri("/claim");
215+
sp.setPath(p);
216+
217+
TemplateInterceptor ti = new TemplateInterceptor();
218+
ti.setContentType("application/json");
219+
ti.setSrc("{\"claim\":\"${fn.getSession('oauth2')?.get('idToken.name')}\"}");
220+
sp.getFlow().add(ti);
221+
sp.getFlow().add(new ReturnInterceptor());
222+
223+
return sp;
224+
}
225+
204226
private static @NotNull List<LoginParameter> createLoginParameters2() {
205227
var lp1 = new LoginParameter();
206228
lp1.setName("domain_hint");
@@ -236,6 +258,8 @@ public Outcome handleRequestInternal(Exchange exc) throws IOException {
236258
body.put("method", exc.getRequest().getMethod());
237259
body.put("body", exc.getRequest().getBodyAsStringDecoded());
238260

261+
body.put("name", ((Session)exc.getProperty("SESSION")).get("idToken.name"));
262+
239263
exc.setResponse(ok(om.writeValueAsString(body)).build());
240264
return RETURN;
241265
}

0 commit comments

Comments
 (0)