Skip to content

Commit ebca16b

Browse files
authored
fix: #2201 (#3365)
1 parent e83c087 commit ebca16b

File tree

7 files changed

+426
-155
lines changed

7 files changed

+426
-155
lines changed

docs/admin/developer/interception-scripts.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ request authorization for each scope, and display the respective scope descripti
3131
1. [Dynamic Scopes](./scripts/dynamic-scope.md) : Enables admin to generate scopes on the fly, for example by
3232
calling external APIs
3333
1. ID Generator
34+
1. [Update Token][Inrospection](./scripts/update-token)
3435
1. Session Management
3536
1. SCIM
36-
1. Inrospection
37+
1. [Inrospection](./scripts/introspection)
3738
1. Resource Owner Password Credentials
3839
1. UMA 2 RPT Authorization Policies
3940
1. UMA 2 Claims-Gathering
4041

41-
4242
## Implementation languages - Jython or pure Java
4343

4444
Interception scripts are written in **[Jython](http://www.jython.org/)** or in
@@ -195,7 +195,9 @@ where <library_name> is the name of the library to install.
195195

196196
### Debugging a Jython script
197197

198-
This [article](../interception-scripts-debug) covers the details.
198+
1. This [article](../interception-scripts-debug-ce) covers the details for debugging a script in a developer environment (CE).
199+
200+
2. This [article](../interception-scripts-debug) covers the details for debugging a script in a CN environment.
199201

200202
***
201203

@@ -256,7 +258,7 @@ The post-config-scripts and put-config-scripts require various details about the
256258
### Basic schema of a custom script
257259
Command:
258260

259-
`/opt/jans/jans-cli/config-cli.py --schema CustomScript`
261+
`/opt/jans/jans-cli/config-cli.py --schema /components/schemas/CustomScript `
260262

261263
Output:
262264
```json

docs/admin/developer/scripts/consent-gathering.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ tags:
33
- administration
44
- developer
55
- scripts
6+
- ConsentGathering
7+
- ConsentGatheringType
68
---
79

810
## Overview
9-
OAuth 2.0 allows providers to prompt users for consent before releasing their personal information to a client (application). The standard consent process is binary: approve or deny. Using the consent gathering interception script, the consent flow can be customized to meet unique business requirements, for instance to support payment authorization, where you need to present transactional information, or where you need to step-up authentication to add security.
11+
OAuth 2.0 allows providers to prompt users for consent before releasing their personal information to a client (application). The standard consent process is binary: approve or deny. Using the consent gathering interception script, the consent flow can be customized to meet unique business requirements, for instance to support payment authorization, where you need to present transactional information, or where you need to step-up authentication to add security.
1012

1113
## Interface
1214
The consent gathering script implements the [ConsentGathering](https://github.com/JanssenProject/jans/blob/main/jans-core/script/src/main/java/io/jans/model/custom/script/type/authz/ConsentGatheringType.java) interface. This extends methods from the base script type in addition to adding new methods:
@@ -65,7 +67,7 @@ class ConsentGathering(ConsentGatheringType):
6567
return 11
6668

6769
# All user entered values can be access via Map<String, String> context.getPageAttributes()
68-
def authorize(self, step, context):
70+
def authorize(self, step, context):
6971
print "Consent-Gathering. Authorizing..."
7072

7173
if step == 1:
@@ -95,7 +97,7 @@ class ConsentGathering(ConsentGatheringType):
9597

9698
if step == 2:
9799
pageAttributes = context.getPageAttributes()
98-
100+
99101
# Generate random consent gathering request
100102
consentRequest = "Requested transaction #%s approval for the amount of sum $ %s.00" % ( random.randint(100000, 1000000), random.randint(1, 100) )
101103
pageAttributes.put("consent_request", consentRequest)
@@ -216,4 +218,4 @@ public class ConsentGathering implements ConsentGatheringType {
216218
return "";
217219
}
218220
}
219-
```
221+
```

docs/admin/developer/scripts/person-authentication-interface.md

+113-98
Original file line numberDiff line numberDiff line change
@@ -5,113 +5,128 @@ tags:
55
- scripts
66
---
77

8-
9-
108
## Person Authentication interface
119
The **[PersonAuthenticationType](https://github.com/JanssenProject/jans/blob/main/jans-core/script/src/main/java/io/jans/model/custom/script/type/auth/PersonAuthenticationType.java)** script is described by a java interface whose methods should be overridden to implement an authentication workflow.
1210

13-
### Methods to override:
14-
1. `init(self, customScript, configurationAttributes)` : This method is only called once during the script initialization (or jans-auth service restarts). It can be used for global script initialization, initiate objects etc.
15-
```
11+
### Inherited Methods
12+
| Method header | Method description |
13+
|:-----|:------|
14+
| `def init(self, customScript, configurationAttributes)` | This method is only called once during the script initialization. It can be used for global script initialization, initiate objects etc |
15+
| `def destroy(self, configurationAttributes)` | This method is called once to destroy events. It can be used to free resource and objects created in the `init()` method |
16+
| `def getApiVersion(self, configurationAttributes, customScript)` | The getApiVersion method allows API changes in order to do transparent migration from an old script to a new API. Only include the customScript variable if the value for getApiVersion is greater than 10 |
17+
18+
#### Objects
19+
| Object name | Object description |
20+
|:-----|:------|
21+
|`customScript`| The custom script object. [Reference](https://github.com/JanssenProject/jans/blob/main/jans-core/script/src/main/java/io/jans/model/custom/script/model/CustomScript.java) |
22+
|`configurationAttributes`| `configurationProperties` passed in when adding custom script. `Map<String, SimpleCustomProperty> configurationAttributes` |
23+
|`SimpleCustomProperty`| Map of configuration properties. [Reference](https://github.com/JanssenProject/jans/blob/main/jans-core/util/src/main/java/io/jans/model/SimpleCustomProperty.java) |
24+
25+
Pseudo code:
26+
```
1627
def init(self, customScript, configurationAttributes):
1728
# an example of initializing global variables from script configuration
1829
if configurationAttributes.containsKey("registration_uri"):
1930
self.registrationUri = configurationAttributes.get("registration_uri").getValue2()
2031
return True
21-
```
32+
```
2233

23-
2. `destroy(self, configurationAttributes)` : This method is called when a custom script fails to initialize or upon jans-auth service restarts. It can be used to free resource and objects created in the init() method
24-
```
34+
```
2535
def destroy(self, configurationAttributes):
26-
print "OTP. Destroy"
36+
print "ACR_NAME. Destroy"
2737
# cleanup code here
2838
return True
29-
```
30-
31-
3. ` authenticate(self, configurationAttributes, requestParameters, step)` : The most important method which will encapsulate the logic for user credential verification / validation
32-
```
33-
def authenticate(self, configurationAttributes, requestParameters, step):
34-
authenticationService = CdiUtil.bean(AuthenticationService)
35-
36-
if (step == 1):
37-
# 1. obtain user name and password from UI
38-
# 2. verify if entry exists in database
39-
# 3. authenticationService.authenticate(user_name, user_password)
40-
# 4. return True or False
41-
42-
elif step == 2:
43-
# 1. obtain credentials from UI
44-
# 2. validate the credentials
45-
# 3. return True or False
46-
```
47-
48-
49-
4. `prepareForStep(self, configurationAttributes, requestParameters, step)` : This method can be used to prepare variables needed to render the UI page and store them in a suitable context.
50-
51-
```
52-
prepareForStep(self, configurationAttributes, requestParameters, step)
53-
# if (step == 1):
54-
# do this
55-
# if (step == 2)
56-
# do something else
57-
# 2. return True or False
58-
```
59-
60-
5. `getExtraParametersForStep` : Used to save session variables between steps. The Jans-auth Server persists these variables to support stateless, two-step authentications even in a clustered environment.
61-
```
62-
def getExtraParametersForStep(self, configurationAttributes, step):
63-
return Arrays.asList("paramName1", "paramName2", "paramName3")
64-
```
65-
6. `getCountAuthenticationSteps`: This method normally just returns 1, 2, or 3. In some cases, depending on the context like based on the user's country or department, you can decide to go for multistep or single step authentication.
66-
```
67-
def getCountAuthenticationSteps(self, configurationAttributes):
68-
return 1
69-
```
70-
7. `getPageForStep`: Used to specify the UI page you want to show for a given step.
71-
```
72-
def getPageForStep(self, configurationAttributes, step):
73-
# Used to specify the page you want to return for a given step
74-
if (step == 1):
75-
return "/auth/login.xhtml"
76-
if (step == 2)
77-
return "/auth/enterOTP.xhtml"
78-
```
79-
8. `getNextStep` : Steps usually go incrementally as 1, 2, 3... unless you specify a case where it can be reset to a previous step, or skip a particular step based on business case.
80-
```
81-
def getNextStep(self, configurationAttributes, requestParameters, step):
82-
# steps usually are incremented 1, 2, 3... unless you specify a case where it can be reset to a previous step, or skip a particular step based on
83-
business case.
84-
return -1
85-
```
86-
9. `getAuthenticationMethodClaims` : Array of strings that are identifiers for authentication methods used in the authentication. In OpenID Connect, if the identity provider supplies an "amr" claim in the ID Token resulting from a successful authentication, the relying party can inspect the values returned and thereby learn details about how the authentication was performed.
87-
```
88-
def getAuthenticationMethodClaims(self, requestParameters):
89-
return Arrays.asList("pwd", "otp")
90-
```
91-
10. `getApiVersion` : This value is currently meant to be hardcoded to 11
92-
93-
```
94-
def getApiVersion(self):
95-
return 11
96-
```
97-
11. `isValidAuthenticationMethod` : This method is used to check if the authentication method is in a valid state. For example we can check there if a 3rd party mechanism is available to authenticate users. As a result it should either return True or False.
98-
```
99-
def isValidAuthenticationMethod(self, usageType, configurationAttributes):
100-
return True
101-
```
102-
12. `getAlternativeAuthenticationMethod` : This method is called only if the current authentication method is in an invalid state. Hence authenticator calls it only if isValidAuthenticationMethod returns False. As a result it should return the reserved authentication method name.
103-
```
104-
def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):
105-
return None
106-
```
107-
108-
13. `getLogoutExternalUrl` : Returns the 3rd-party URL that is used to end session routines. The control from this Third party URL should re-direct user back to /oxauth/logout.htm again with empty URL query string. Jans-Auth server will then continue of the extended logout flow, restore the original URL query string, and send user to `/jans-auth/end_session` to complete it.
109-
```
110-
def getLogoutExternalUrl(self, configurationAttributes, requestParameters):
111-
return None
112-
```
113-
14. `logout` : This method is not mandatory. It can be used in cases when you need to execute specific logout logic in the authentication script when jans-auth receives an end session request to the /oxauth/logout.htm endpoint (which receives the same set of parameters than the usual end_session endpoint). This method should return True or False; when False jans-auth stops processing the end session request workflow.
114-
```
115-
def logout(self, configurationAttributes, requestParameters):
116-
return True
117-
```
39+
```
40+
41+
```
42+
def getApiVersion(self):
43+
return 11
44+
```
45+
46+
### Person Authentication interface Methods
47+
| | Method header | Method description |
48+
:-----|:-----|:------|
49+
|1.|`prepareForStep(self, configurationAttributes, requestParameters, step)` | This method can be used to prepare variables needed to render the UI page and store them in a suitable context.|
50+
|2.|` authenticate(self, configurationAttributes, requestParameters, step)` | The most important method which will encapsulate the logic for user credential verification / validation|
51+
|3.| `getExtraParametersForStep` | Used to save session variables between steps. The Jans-auth Server persists these variables to support stateless, two-step authentications even in a clustered environment.|
52+
|4.|`getCountAuthenticationSteps`| This method normally just returns 1, 2, or 3. In some cases, depending on the context like based on the user's country or department, you can decide to go for multistep or single step authentication.|
53+
|5.| `getPageForStep`| Used to specify the UI page you want to show for a given step.|
54+
|6.| `getNextStep` | Steps usually go incrementally as 1, 2, 3... unless you specify a case where it can be reset to a previous step, or skip a particular step based on business case.|
55+
|7.| `getAuthenticationMethodClaims` | Array of strings that are identifiers for authentication methods used in the authentication. In OpenID Connect, if the identity provider supplies an "amr" claim in the ID Token resulting from a successful authentication, the relying party can inspect the values returned and thereby learn details about how the authentication was performed.|
56+
|8.| `isValidAuthenticationMethod`| This method is used to check if the authentication method is in a valid state. For example we can check there if a 3rd party mechanism is available to authenticate users. As a result it should either return True or False.|
57+
|9.| `getAlternativeAuthenticationMethod` | This method is called only if the current authentication method is in an invalid state. Hence authenticator calls it only if isValidAuthenticationMethod returns False. As a result it should return the reserved authentication method name.|
58+
|10. `getLogoutExternalUrl` | Returns the 3rd-party URL that is used to end session routines. The control from this Third party URL should re-direct user back to /oxauth/logout.htm again with empty URL query string. Jans-Auth server will then continue of the extended logout flow, restore the original URL query string, and send user to `/jans-auth/end_session` to complete it.|
59+
|11. `logout` | This method is not mandatory. It can be used in cases when you need to execute specific logout logic in the authentication script when jans-auth receives an end session request to the /oxauth/logout.htm endpoint (which receives the same set of parameters than the usual end_session endpoint). This method should return True or False; when False jans-auth stops processing the end session request workflow.|
60+
61+
#### Objects
62+
| Object name | Object description |
63+
|:-----|:------|
64+
|`configurationAttributes`| `configurationProperties` passed in when adding custom script. `Map<String, SimpleCustomProperty> configurationAttributes` |
65+
|`SimpleCustomProperty`| Map of configuration properties. [Reference](https://github.com/JanssenProject/jans/blob/main/jans-core/util/src/main/java/io/jans/model/SimpleCustomProperty.java) |
66+
|usageType|[AuthenticationScriptUsageType](https://github.com/JanssenProject/jans/blob/main/jans-core/util/src/main/java/io/jans/model/AuthenticationScriptUsageType.java)|
67+
|step|Integer indicating step number|
68+
|step|Integer indicating step number|
69+
|requestParameters|Request parameters stored as Map<String, String[]>|
70+
71+
72+
Pseudocode:
73+
```
74+
def prepareForStep(self, configurationAttributes, requestParameters, step):
75+
if (step == 1):
76+
# do this
77+
if (step == 2):
78+
# do something else
79+
return True # or False
80+
81+
def authenticate(self, configurationAttributes, requestParameters, step):
82+
authenticationService = CdiUtil.bean(AuthenticationService)
83+
84+
if (step == 1):
85+
# 1. obtain user name and password from UI
86+
# 2. verify if entry exists in database
87+
# 3. authenticationService.authenticate(user_name, user_password)
88+
# 4. return True or False
89+
90+
elif step == 2:
91+
# 1. obtain credentials from UI
92+
# 2. validate the credentials
93+
# 3. return True or False
94+
95+
def getExtraParametersForStep(self, configurationAttributes, step):
96+
return Arrays.asList("paramName1", "paramName2", "paramName3")
97+
98+
def getCountAuthenticationSteps(self, configurationAttributes):
99+
return 1
100+
101+
def getPageForStep(self, configurationAttributes, step):
102+
# Used to specify the page you want to return for a given step
103+
if (step == 1):
104+
return "/auth/login.xhtml"
105+
if (step == 2)
106+
return "/auth/enterOTP.xhtml"
107+
108+
def getNextStep(self, configurationAttributes, requestParameters, step):
109+
# steps usually are incremented 1, 2, 3... unless you specify a case where it can be reset to a previous step, or skip a particular step based on business case.
110+
return -1
111+
112+
def getAuthenticationMethodClaims(self, requestParameters):
113+
return Arrays.asList("pwd", "otp")
114+
115+
def isValidAuthenticationMethod(self, usageType, configurationAttributes):
116+
return True
117+
118+
def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):
119+
return None
120+
121+
def getLogoutExternalUrl(self, configurationAttributes, requestParameters):
122+
return None
123+
124+
def logout(self, configurationAttributes, requestParameters):
125+
return True
126+
127+
```
128+
### Example scripts:
129+
130+
1. [Basic script](https://github.com/JanssenProject/jans/tree/main/docs/script-catalog/person_authentication/basic-external-authenticator)
131+
132+
2. [Script catalog](https://github.com/JanssenProject/jans/tree/main/docs/script-catalog)

0 commit comments

Comments
 (0)