Skip to content

Commit

Permalink
Merge branch 'main' into jans-cedaling-issue-10748
Browse files Browse the repository at this point in the history
  • Loading branch information
olehbozhok authored Feb 4, 2025
2 parents 897ff29 + d13bdbf commit a92726d
Show file tree
Hide file tree
Showing 59 changed files with 691 additions and 228 deletions.
Binary file added docs/assets/agama-create-assignment.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/agama-create-cdiutil.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/agama-create-repeat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/agama-lab-add-git-repo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/agama-lab-create-assignment-uid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/agama-lab-create-cdiutil-instance.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/assets/agama-lab-flow-passwd-edit-assignment-uid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/assets/agama-lab-flow-passwd-edit-finish.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/agama-lab-flow-password-edit-when.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/agama-lab-flow-render-template.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/agama-lab-flow-save-template.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/agama-lab-git-login.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/agama-login.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/agama-loginpage.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/agamalab-flow-passwd-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/agamalab-flow-passwd-call.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/agamalab-flow-passwd-create-call.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/agamalab-flow-passwd-edit-cdiutil.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/agamalab-flow-passwd-edit-repeat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/agamalab-flow-passwd-edit-rrf.png
Binary file added docs/assets/agamalab-flow-passwd-editcdiutil.png
Binary file added docs/assets/agamalab-flow-passwd-new-call.png
Binary file added docs/assets/agamalab-new-flow-name.png
Binary file added docs/assets/agamalab-new-flow.png
Binary file added docs/assets/agamalab-new-proj.png
Binary file added docs/assets/agamalab-project-listing.png
Binary file added docs/assets/agamalab-project-page.png
Binary file added docs/assets/authentication-flow-input.png
Binary file added docs/assets/check-repeat.png
Binary file added docs/assets/select-agama-project.png
Binary file added docs/assets/select-community-agamaproject.png
Binary file added docs/assets/successful-tarp-auth-screen.png
Binary file added docs/assets/tarp-client-reg.png
Binary file added docs/assets/upload-gama-file.png
534 changes: 326 additions & 208 deletions docs/janssen-server/developer/agama/quick-start-using-agama-lab.md

Large diffs are not rendered by default.

23 changes: 6 additions & 17 deletions docs/script-catalog/consent_gathering/AgamaConsentGathering.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,25 +75,20 @@ def prepareForStep(self, step, context):
print "Agama-Consent. Failed to retrieve session_id"
return False

cesar = session.getSessionAttributes()
param = cesar.get("agama_flow")
sessionId = session.getId()
# print "Session id is %s" % sessionId
param = context.getSessionAttributes().get("consent_flow")

if not param:
param = self.extractAgamaFlow(cesar.get("acr_values"))
print "Agama-Consent. 'consent_flow' session attribute missing"
return False

if not param:
print "Agama-Consent. Unable to determine the Agama flow to launch. Check the docs"
return False

(qn, ins) = self.extractParams(param)
if qn == None:
print "Agama-Consent. Unable to determine the Agama flow to launch. Check the docs"
return False

try:
sessionId = session.getId()
# print "==================================== %s" % sessionId

bridge = CdiUtil.bean(NativeJansFlowBridge)
running = bridge.prepareFlow(sessionId, qn, ins, False, self.enterUrl)

Expand All @@ -120,13 +115,7 @@ def getPageForStep(self, step, context):
return "/" + self.enterUrl

# Misc routines

def extractAgamaFlow(self, acr):
prefix = "agama_"
if acr and acr.startswith(prefix):
return acr[len(prefix):]
return None


def extractParams(self, param):

# param must be of the form QN-INPUT where QN is the qualified name of the flow to launch
Expand Down
31 changes: 30 additions & 1 deletion docs/script-catalog/consent_gathering/consent-gathering.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ tags:
- administration
- developer
- script-catalog
- ConsentGathering
- consent
---

## Overview
Expand Down Expand Up @@ -262,3 +262,32 @@ This is how consent will work depending on the authentication request issued:
- With `agama_co.acme.mysuperflow`, the Agama flow `io.jans.consent.B` will be launched for consent

Agama flows used for consent can be built using the same approach and tooling used for regular authentication flows. Note however there is no need to pass a user identity in the `Finish` instruction. If passed, it will be ignored, thus, it suffices to end a consent flow with `Finish false/true`.

### Getting contextual data

To access information in your Agama consent flow related to the user attempting login, scopes requested, etc., get an instance of managed bean `io.jans.as.server.util.AgamaConsentUtil` and use the available methods as summarized below:

|Method|Description|Reference class|
|-|-|-|
|`getClient`|Gets a reference to the OAuth client associated to the authentication request|[Client](https://github.com/JanssenProject/jans/tree/vreplace-janssen-version/jans-auth-server/common/src/main/java/io/jans/as/common/model/registration/Client.java)|
|`getScopes`|A list of OAuth scopes requested|[Scope](https://github.com/JanssenProject/jans/tree/vreplace-janssen-version/jans-auth-server/persistence-model/src/main/java/io/jans/as/persistence/model/Scope.java)|
|`getUser`|A reference to the user attempting authentication|[User](https://github.com/JanssenProject/jans/tree/vreplace-janssen-version/jans-auth-server/common/src/main/java/io/jans/as/common/model/common/User.java) / [SimpleUser](https://github.com/JanssenProject/jans/tree/vreplace-janssen-version/jans-core/model/src/main/java/io/jans/model/user/SimpleUser.java)|
|`getSessionAttributes`|A map containing the parameters of the OAuth authentication request issued||

Java example code:

```
import io.jans.as.server.util.AgamaConsentUtil;
import io.jans.service.cdi.util.CdiUtil;
...
AgamaConsentUtil acu = CdiUtil.bean(AgamaConsentUtil.class);
String name = acu.getClient().getClientName(); //retrieves the client's display name
```

Agama DSL example:

```
acuCls = Call io.jans.as.server.util.AgamaConsentUtil#class
acu = Call io.jans.service.cdi.util.CdiUtil#bean acuCls
name = acu.client.clientName //retrieves the client's display name
```
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ public boolean shouldSaveInCache() {
}

public void persist(TokenEntity token) {
if (shouldPersist()) {
// always save access_token into persistence because we need to fetch it by session, see getGrantsBySessionDn
if (token.isAccessToken() || shouldPersist()) {
persistenceEntryManager.persist(token);
}

Expand Down
10 changes: 10 additions & 0 deletions jans-cedarling/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,13 @@ cargo doc -p cedarling --no-deps --open
The python bindings for `Cedarling` is located in the `bindings/cedarling_python` folder.

Or you can find readme by clicking [here](bindings/cedarling_python/README.md).

## Benchmarks

Benchmarks have been written with the help of the [`criterion`](https://crates.io/crates/criterion) crate.

You can run the benchmarks using:

```sh
cargo bench -p cedarling
```
10 changes: 10 additions & 0 deletions jans-cedarling/cedarling/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,13 @@ test_utils = { workspace = true }
rand = "0.8.5"
jsonwebkey = { workspace = true, features = ["generate", "jwt-convert"] }
mockito = "1.5.0"
criterion = { version = "0.5.1", features = ["async_tokio"] }
tokio = { version = "1.42.0", features = ["rt-multi-thread"] }

[[bench]]
name = "authz_benchmark"
harness = false

[[bench]]
name = "startup_benchmark"
harness = false
237 changes: 237 additions & 0 deletions jans-cedarling/cedarling/benches/authz_benchmark.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
// This software is available under the Apache-2.0 license.
// See https://www.apache.org/licenses/LICENSE-2.0.txt for full text.
//
// Copyright (c) 2024, Gluu, Inc.

use cedarling::{
AuthorizationConfig, BootstrapConfig, Cedarling, IdTokenTrustMode, InitCedarlingError,
JwtConfig, LogConfig, LogLevel, LogTypeConfig, PolicyStoreConfig, Request,
TokenValidationConfig, WorkloadBoolOp,
};
use criterion::{BenchmarkId, Criterion, black_box, criterion_group, criterion_main};
use jsonwebtoken::Algorithm;
use serde::Deserialize;
use serde_json::json;
use std::collections::{HashMap, HashSet};
use test_utils::token_claims::generate_token_using_claims;
use tokio::runtime::Runtime;

const POLICY_STORE: &str = include_str!("../../test_files/policy-store_ok.yaml");

fn without_jwt_validation_benchmark(c: &mut Criterion) {
let runtime = Runtime::new().expect("init tokio runtime");

let cedarling = runtime
.block_on(prepare_cedarling_without_jwt_validation())
.expect("should initialize Cedarling");

let request = prepare_cedarling_request().expect("should prepare r:equest");

c.bench_with_input(
BenchmarkId::new("authz_without_jwt_validation", "tokio runtime"),
&runtime,
|b, rt| {
b.to_async(rt)
.iter(|| cedarling.authorize(black_box(request.clone())));
},
);
}

fn with_jwt_validation_benchmark(c: &mut Criterion) {
let runtime = Runtime::new().expect("init tokio runtime");

let cedarling = runtime
.block_on(prepare_cedarling_with_jwt_validation())
.expect("should initialize Cedarling");

let request = prepare_cedarling_request().expect("should prepare r:equest");

c.bench_with_input(
BenchmarkId::new("authz_with_jwt_validation", "tokio runtime"),
&runtime,
|b, rt| {
b.to_async(rt)
.iter(|| cedarling.authorize(black_box(request.clone())));
},
);
}

criterion_group!(
authz_benchmark,
without_jwt_validation_benchmark,
with_jwt_validation_benchmark,
);
criterion_main!(authz_benchmark);

async fn prepare_cedarling_without_jwt_validation() -> Result<Cedarling, InitCedarlingError> {
let bootstrap_config = BootstrapConfig {
application_name: "test_app".to_string(),
log_config: LogConfig {
log_type: LogTypeConfig::Off,
log_level: LogLevel::DEBUG,
},
policy_store_config: PolicyStoreConfig {
source: cedarling::PolicyStoreSource::Yaml(POLICY_STORE.to_string()),
},
jwt_config: JwtConfig::new_without_validation(),
authorization_config: AuthorizationConfig {
use_user_principal: true,
use_workload_principal: true,
user_workload_operator: WorkloadBoolOp::And,
mapping_user: Some("Jans::User".to_string()),
mapping_workload: Some("Jans::Workload".to_string()),
mapping_role: Some("Jans::Role".to_string()),
mapping_tokens: HashMap::from([
("access_token".to_string(), "Jans::Access_token".to_string()),
("id_token".to_string(), "Jans::id_token".to_string()),
(
"userinfo_token".to_string(),
"Jans::Userinfo_token".to_string(),
),
])
.into(),
id_token_trust_mode: IdTokenTrustMode::None,
..Default::default()
},
};

Cedarling::new(&bootstrap_config).await
}

async fn prepare_cedarling_with_jwt_validation() -> Result<Cedarling, InitCedarlingError> {
let bootstrap_config = BootstrapConfig {
application_name: "test_app".to_string(),
log_config: LogConfig {
log_type: LogTypeConfig::Off,
log_level: LogLevel::DEBUG,
},
policy_store_config: PolicyStoreConfig {
source: cedarling::PolicyStoreSource::Yaml(POLICY_STORE.to_string()),
},
jwt_config: JwtConfig {
jwks: None,
jwt_sig_validation: false,
jwt_status_validation: false,
signature_algorithms_supported: HashSet::from([Algorithm::HS256]),
token_validation_settings: HashMap::from([
(
"access_token".to_string(),
TokenValidationConfig::access_token(),
),
("id_token".to_string(), TokenValidationConfig::id_token()),
(
"userinfo_token".to_string(),
TokenValidationConfig::userinfo_token(),
),
]),
},
authorization_config: AuthorizationConfig {
use_user_principal: true,
use_workload_principal: true,
user_workload_operator: WorkloadBoolOp::And,
mapping_user: Some("Jans::User".to_string()),
mapping_workload: Some("Jans::Workload".to_string()),
mapping_role: Some("Jans::Role".to_string()),
mapping_tokens: HashMap::from([
("access_token".to_string(), "Jans::Access_token".to_string()),
("id_token".to_string(), "Jans::id_token".to_string()),
(
"userinfo_token".to_string(),
"Jans::Userinfo_token".to_string(),
),
])
.into(),
id_token_trust_mode: IdTokenTrustMode::None,
..Default::default()
},
};

Cedarling::new(&bootstrap_config).await
}

pub fn prepare_cedarling_request() -> Result<Request, serde_json::Error> {
Request::deserialize(serde_json::json!(
{
"tokens": {
"access_token": generate_token_using_claims(json!({
"sub": "boG8dfc5MKTn37o7gsdCeyqL8LpWQtgoO41m1KZwdq0",
"code": "bf1934f6-3905-420a-8299-6b2e3ffddd6e",
"iss": "https://admin-ui-test.gluu.org",
"token_type": "Bearer",
"client_id": "5b4487c4-8db1-409d-a653-f907b8094039",
"aud": "5b4487c4-8db1-409d-a653-f907b8094039",
"acr": "basic",
"x5t#S256": "",
"scope": [
"openid",
"profile"
],
"org_id": "some_long_id",
"auth_time": 1724830746,
"exp": 1724945978,
"iat": 1724832259,
"jti": "lxTmCVRFTxOjJgvEEpozMQ",
"name": "Default Admin User",
"status": {
"status_list": {
"idx": 201,
"uri": "https://admin-ui-test.gluu.org/jans-auth/restv1/status_list"
}
}
})),
"id_token": generate_token_using_claims(json!({
"acr": "basic",
"amr": "10",
"aud": "5b4487c4-8db1-409d-a653-f907b8094039",
"exp": 1724835859,
"iat": 1724832259,
"sub": "boG8dfc5MKTn37o7gsdCeyqL8LpWQtgoO41m1KZwdq0",
"iss": "https://admin-ui-test.gluu.org",
"jti": "sk3T40NYSYuk5saHZNpkZw",
"nonce": "c3872af9-a0f5-4c3f-a1af-f9d0e8846e81",
"sid": "6a7fe50a-d810-454d-be5d-549d29595a09",
"jansOpenIDConnectVersion": "openidconnect-1.0",
"c_hash": "pGoK6Y_RKcWHkUecM9uw6Q",
"auth_time": 1724830746,
"grant": "authorization_code",
"status": {
"status_list": {
"idx": 202,
"uri": "https://admin-ui-test.gluu.org/jans-auth/restv1/status_list"
}
},
"role":"Admin"
})),
"userinfo_token": generate_token_using_claims(json!({
"country": "US",
"email": "[email protected]",
"username": "UserNameExample",
"sub": "boG8dfc5MKTn37o7gsdCeyqL8LpWQtgoO41m1KZwdq0",
"iss": "https://admin-ui-test.gluu.org",
"given_name": "Admin",
"middle_name": "Admin",
"inum": "8d1cde6a-1447-4766-b3c8-16663e13b458",
"client_id": "5b4487c4-8db1-409d-a653-f907b8094039",
"aud": "5b4487c4-8db1-409d-a653-f907b8094039",
"updated_at": 1724778591,
"name": "Default Admin User",
"nickname": "Admin",
"family_name": "User",
"jti": "faiYvaYIT0cDAT7Fow0pQw",
"jansAdminUIRole": [
"api-admin"
],
"exp": 1724945978
})),
},
"action": "Jans::Action::\"Update\"",
"resource": {
"id": "random_id",
"type": "Jans::Issue",
"org_id": "some_long_id",
"country": "US"
},
"context": {},
}
))
}
Loading

0 comments on commit a92726d

Please sign in to comment.