From 07aae975ba4544753c5e3a3b39e2466a349a4baf Mon Sep 17 00:00:00 2001 From: Madhumita Date: Thu, 29 Dec 2022 21:22:08 +0530 Subject: [PATCH] fix: #2201 --- docs/admin/developer/interception-scripts.md | 4 +- docs/admin/developer/managed-beans.md | 191 +++++++++++++++--- .../scripts/person-authentication-faq.md | 88 ++++++++ .../person-authentication-interface.md | 8 +- .../scripts/person-authentication.md | 40 +++- docs/admin/recipes/social-login.md | 12 +- 6 files changed, 299 insertions(+), 44 deletions(-) create mode 100644 docs/admin/developer/scripts/person-authentication-faq.md diff --git a/docs/admin/developer/interception-scripts.md b/docs/admin/developer/interception-scripts.md index 268aa6f4d51..66f8b83d8cd 100644 --- a/docs/admin/developer/interception-scripts.md +++ b/docs/admin/developer/interception-scripts.md @@ -31,10 +31,10 @@ request authorization for each scope, and display the respective scope descripti 1. [Dynamic Scopes](./scripts/dynamic-scope.md) : Enables admin to generate scopes on the fly, for example by calling external APIs 1. ID Generator -1. [Update Token](./scripts/update-token.md) +1. [Update Token](./scripts/update-token.md) : Enables transformation of claims and values in id_token, Access token and Refresh tokens; allows the setting of token lifetime; allows the addition or removal of scopes to / from tokens; allows the addition of audit logs each time a token is created. 1. Session Management 1. SCIM -1. [Introspection](./scripts/introspection.md) +1. [Introspection](./scripts/introspection.md) : Introspection scripts allows to modify response of Introspection Endpoint spec and present additional meta information surrounding the token. 1. [Post Authentication](./scripts/post-authentication.md) 1. Resource Owner Password Credentials 1. UMA 2 RPT Authorization Policies diff --git a/docs/admin/developer/managed-beans.md b/docs/admin/developer/managed-beans.md index 0bd61b2a0f6..c2c5697b216 100644 --- a/docs/admin/developer/managed-beans.md +++ b/docs/admin/developer/managed-beans.md @@ -2,12 +2,37 @@ tags: - administration - developer + - bean + - CdiUtil --- ## Ready-to-use code in Custom script: -Jans-auth server uses Weld 3.0 (JSR-365 aka CDI 2.0) for managed beans. The most important aspects of business logic are implemented through a set of beans some of which are listed below: +Jans-auth server uses Weld 3.0 (JSR-365 aka CDI 2.0) for managed beans. +The most important aspects of business logic are implemented through a set of beans -### 1. [AuthenticationService](https://github.com/JanssenProject/jans/blob/main/jans-auth-server/server/src/main/java/io/jans/as/server/service/AuthenticationService.java) +### Obtaining a bean inside a custom script: +[CdiUtil](https://github.com/JanssenProject/jans/blob/main/jans-core/service/src/main/java/io/jans/service/cdi/util/CdiUtil.java) used to obtain managed beans inside a custom script. + +Relevant methods: + +|Signature|Description| +|-|-| +| T bean(Class clazz)|Gets the managed bean belonging to the class passed as parameter| + +Usage (jython code): +Suppose UserService and AuthenticationService beans have to be referenced in the code, it can be done as below: + +``` +from org.gluu.oxauth.service import UserService +from org.gluu.oxauth.service import AuthenticationService +... +userService = CdiUtil.bean(UserService) +authenticationService = CdiUtil.bean(AuthenticationService) +``` + +## Commonly used beans: + +### 1. [AuthenticationService](https://github.com/JanssenProject/jans/blob/main/jans-auth-server/server/src/main/java/io/jans/as/server/service/AuthenticationService.java) Allows to authenticate a user or obtain the current authenticated user
@@ -19,17 +44,28 @@ Relevant methods: |`boolean authenticate(String userName, String password)`|Performs authentication for the user whose identifier (`userName`) is passed as parameter. The `password` supplied must be the correct password of the user in question| |`User getAuthenticatedUser()`|Returns a representation of the currently authenticated user. `null` if no user is currently authenticated. See [User](#class-user) data object| -### 2. [Authenticator](https://github.com/JanssenProject/jans/blob/main/jans-auth-server/server/src/main/java/io/jans/as/server/auth/Authenticator.java) -This class is mainly used in facelets templates for authentication flows to proceed in the sequence of steps. -Relevant methods: +Usage: +``` -|Signature|Description| -|-|-| -|boolean authenticate()|Makes the authentication flow proceed by calling the `authenticate` method of the custom script| -|String prepareAuthenticationForStep()|Makes the authentication flow proceed by calling the `prepareForStep` method of the custom script| +from io.jans.as.server.service import AuthenticationService +... -### 3. [UserService](https://github.com/JanssenProject/jans/blob/main/jans-auth-server/server/src/main/java/io/jans/as/server/service/UserService.java) -Allows CRUD of users in the local persistence. +#1. authenticate a user using username and password +authenticationService = CdiUtil.bean(AuthenticationService) +logged_in = authenticationService.authenticate(user_name, user_password) + +# 2. authenticate method without passing password parameter +logged_in = authenticationService.authenticate(user_name, user_password) + +#3. obtain an authenticated user +user = authenticationService.getAuthenticatedUser() +userName = user.getUserId() +emailIds = user.getAttribute("oxEmailAlternate") + +``` + +### 2. [UserService](https://github.com/JanssenProject/jans/blob/main/jans-auth-server/common/src/main/java/io/jans/as/common/service/common/UserService.java) +Allows CRUD operations for users to the local persistence. Relevant methods: @@ -49,13 +85,63 @@ Relevant methods: |`void setCustomAttribute(User user, String attributeName, String attributeValue)`|Sets the value of the attribute `attributeName` with the single value `attributeValue` for the user representation passes as parameter. This method does not persist changes| |`User updateUser(User user)`|Updates the user represented by `user` object in the database| +#### Usage + +#### a. Add a user +``` +from io.jans.as.common.service.common import UserService +... + +new_user = User() +new_user.setAttribute("uid", user_email, True) +new_user.setAttribute("givenName", username, True) +new_user.setAttribute("displayName", username, True) +new_user.setAttribute("sn", "-", True) +new_user.setAttribute("mail", user_email, True) +new_user.setAttribute("gluuStatus", "active", True) +new_user.setAttribute("password", user_password) + +new_user = CdiUtil.bean(UserService).addUser(new_user, True) +``` +#### b. Add user attributes +``` +userObject = userService.addUserAttribute(user_name, "oxExternalUid", cert_user_external_uid) +``` +#### c. Get User +``` +# example 1 - get User by userId +user = userService.getUser(user_name) + +# example 2 - get User by User-Id only if attribute oxExternalUid is populated +user = userService.getUser(user_name, "oxExternalUid") +customAttributeValue = userService.getCustomAttribute(user, "oxExternalUid") +``` +#### d. Get specific User attribute +``` +status_attribute_value = userService.getCustomAttribute(find_user_by_uid, "gluuStatus") +``` +#### e. Replace user attributes +``` +userService.replaceUserAttribute(user_name, "oxOTPCache", cachedOTP, localTotpKey) +``` +#### f. Remove user attribute +``` +userService.removeUserAttribute(user.getUserId(),"oxTrustExternalId", "wwpass:%s"%puid) +``` +#### g. Update users +``` +found_user = userService.getUser(user_name) +found_user.setAttribute("userPassword", new_password) +userService.updateUser(found_user) +``` + ### 4. [User](https://github.com/JanssenProject/jans/blob/main/jans-auth-server/common/src/main/java/io/jans/as/common/model/common/User.java) A class employed to represent a user entry in the persistence. Provides getters and setters to retrieve and assign value(s) for attributes -### 5. [CustomAttribute](https://github.com/JanssenProject/jans/blob/main/jans-orm/model/src/main/java/io/jans/orm/model/base/CustomAttribute.java) +### 5. [CustomAttribute](https://github.com/JanssenProject/jans/blob/main/jans-orm/model/src/main/java/io/jans/orm/model/base/CustomAttribute.java) A class that models an attribute. An attribute has a name and a collection of associated values -### 6. [Identity](https://github.com/JanssenProject/jans/blob/main/jans-core/service/src/main/java/io/jans/model/security/Identity.java) +### 6. [Identity](https://github.com/JanssenProject/jans/blob/main/jans-core/service/src/main/java/io/jans/model/security/Identity.java) Mainly used to carry data between steps of authentication flows. |Signature|Description| @@ -64,7 +150,7 @@ Mainly used to carry data between steps of authentication flows. |`void setWorkingParameter(String name, Object value)`|Binds data to a name for further use in an authentication flow. Recommended values to store are `String`s| |`SessionId getSessionId()`|Retrieves a reference to the associated server session object, see [SessionId](https://github.com/JanssenProject/jans/blob/main/jans-auth-server/server/src/main/java/io/jans/as/server/model/common/SessionId.java)| -### 7. HttpService: [HttpService](https://github.com/JanssenProject/jans/blob/main/jans-auth-server/server/src/main/java/io/jans/as/server/service/net/HttpService.java) +### 7. HttpService: [HttpService](https://github.com/JanssenProject/jans/blob/main/jans-auth-server/server/src/main/java/io/jans/as/server/service/net/HttpService.java) Provides utility methods to execute HTTP requests, manipulate responses, etc @@ -76,7 +162,7 @@ Relevant methods: |`HttpServiceResponse executeGet(HttpClient httpClient, String requestUri)`|Perform a GET on the URI requested. Returns an instance of [io.jans.as.server.model.net.HttpServiceResponse](https://github.com/JanssenProject/jans/blob/main/jans-auth-server/server/src/main/java/io/jans/as/server/model/net/HttpServiceResponse.java) (a wrapper on `org.apache.http.HttpResponse`)| |`byte[] getResponseContent(HttpResponse httpResponse)`|Consumes the bytes of the associated response. Returns `null` if the response status code is not 200 (OK)| -### 8. [CacheService](https://github.com/JanssenProject/jans/blob/main/jans-core/cache/src/main/java/io/jans/service/CacheService.java) +### 8. [CacheService](https://github.com/JanssenProject/jans/blob/main/jans-core/cache/src/main/java/io/jans/service/CacheService.java) Provides a unified means to interact with the underlying cache provider configured in the Jans-auth Server Relevant methods: @@ -98,7 +184,7 @@ Relevant methods: |`void redirectToExternalURL(String url)`|Redirects the user's browser to the URL passed as parameter| |`String encodeParameters(String url, Map parameters)`|Builds a URL by appending query parameters as supplied in `parameters` map. Every value in the map is properly URL-encoded| -### 10. [FacesMessages](https://github.com/JanssenProject/jans/blob/main/jans-core/jsf-util/src/main/java/io/jans/jsf2/message/FacesMessages.java) +### 10. [FacesMessages](https://github.com/JanssenProject/jans/blob/main/jans-core/jsf-util/src/main/java/io/jans/jsf2/message/FacesMessages.java) Allows manipulation of JSF context messages Relevant methods: @@ -111,28 +197,48 @@ Relevant methods: |`void setKeepMessages()`|Sets the "keep messages" property of the JSF flash| -### 11. [CdiUtil](https://github.com/JanssenProject/jans/blob/main/jans-core/service/src/main/java/io/jans/service/cdi/util/CdiUtil.java) : Allows to obtain references of managed beans. This is particularly useful in custom scripts +### 11. [StringHelper](https://github.com/JanssenProject/jans/blob/main/jans-core/util/src/main/java/io/jans/util/StringHelper.java) + Provides many utility methods that often arise in the manipulation of Strings +Usage: -Relevant methods: +``` +from io.jans.util import StringHelper +``` -|Signature|Description| -|-|-| -| T bean(Class clazz)|Gets the managed bean belonging to the class passed as parameter| +1. #### isNotEmptyString +``` +if StringHelper.isNotEmptyString(user_name): + # do something +``` -Example (jython code): +2. #### equalsIgnoreCase +``` +if StringHelper.equalsIgnoreCase(authentication_mode, "one_step"): + # do something +``` +3. #### isEmpty ``` -from org.gluu.oxauth.service import UserService -from org.gluu.oxauth.service import AuthenticationService -... -userService = CdiUtil.bean(UserService) -authenticationService = CdiUtil.bean(AuthenticationService) +if StringHelper.isEmpty(auth_method): + # do something ``` -### 12. [StringHelper](https://github.com/JanssenProject/jans/blob/main/jans-core/util/src/main/java/io/jans/util/StringHelper.java) - Provides many utility methods that often arise in the manipulation of Strings +4. #### split +``` +allowedClientsListArray = StringHelper.split(allowedClientsList, ",") +``` -### 13. [EncryptionService](https://github.com/JanssenProject/jans/blob/main/jans-scim/service/src/main/java/io/jans/scim/service/EncryptionService.java) +5. #### toLowerCase +``` +remoteAttribute = StringHelper.toLowerCase(remoteAttributesListArray[i]) +``` +6. #### base64urlencode +``` +StringUtils.base64urlencode(input); +``` + + +### 13. [EncryptionService](https://github.com/JanssenProject/jans/blob/main/jans-scim/service/src/main/java/io/jans/scim/service/EncryptionService.java) Allows to encrypt/decrypt strings using a 3DES cipher whose salt is found in `/etc/jans/conf/salt` Relevant methods: @@ -141,4 +247,27 @@ Relevant methods: |-|-| |String decrypt(String encryptedString)|Decrypts the encrypted string supplied| |Properties decryptAllProperties(Properties connectionProperties)|Returns a `java.util.Properties` object with all decrypted values found in `connectionProperties`| -|`String encrypt(String unencryptedString)`|Encrypts the string supplied| \ No newline at end of file +|`String encrypt(String unencryptedString)`|Encrypts the string supplied| + +#### Usage: +``` +from io.jans.as.common.service.common import EncryptionService +.... + +encryptionService = CdiUtil.bean(EncryptionService) +pwd_decrypted = encryptionService.decrypt("stringtobedecrypted") + +``` + +14. [Base64Util](https://github.com/JanssenProject/jans/blob/main/jans-auth-server/model/src/main/java/io/jans/as/model/util/Base64Util.java) + +Usage: + +``` +from io.jans.as.model.util import Base64Util +.... + +Base64Util.base64urldecodeToString(input_string) + +Base64Util.base64urlencode(input_string.encode('utf-8'))); +``` diff --git a/docs/admin/developer/scripts/person-authentication-faq.md b/docs/admin/developer/scripts/person-authentication-faq.md new file mode 100644 index 00000000000..4cf4863a16b --- /dev/null +++ b/docs/admin/developer/scripts/person-authentication-faq.md @@ -0,0 +1,88 @@ +--- +tags: + - administration + - developer + - scripts + - acr_values_supported + - 2FA + - PersonAuthenticationType + - acr + - weld + - error messsages + - redirection +--- + + +### 1. Display error messages on a web page? +1.[FacesMessages](https://github.com/JanssenProject/jans/blob/main/jans-core/jsf-util/src/main/java/io/jans/jsf2/message/FacesMessages.java) bean is used for this purpose. + ``` + from org.jans.jsf2.message import FacesMessages + from org.jans.service.cdi.util import CdiUtil + from javax.faces.application import FacesMessage + ... + + facesMessages = CdiUtil.bean(FacesMessages) + facesMessages.setKeepMessages() + facesMessages.add(FacesMessage.SEVERITY_ERROR, "Please enter a valid username") + + ``` +2. The error will appear in the associated template using the following markup: + ``` + ... + + ... + ``` + See an example [here](https://github.com/JanssenProject/jans/blob/685a1593fb53e2310cfa38fcd49db94f3453042f/jans-auth-server/server/src/main/webapp/WEB-INF/incl/layout/template.xhtml#L41) + +### 2. Redirection to a third party application for authentication + +For user authentication or consent gathering, there might be a need to redirect to a third party application to perform some operation and return the control back to authentication steps of the custom script. Please apply these steps to a person authentication script in such a scenario: + + - Return from def getPageForStep(self, step, context), a page /auth/method_name/redirect.html ; with content similar to the code snippet below - + ``` + def getPageForStep(self, step, context): + return "/auth/method_name/redirect.html" + ``` + - Contents of redirect.xhtml should take the flow to prepareForStep method + ``` + ... + + + + ``` + - In method prepareForStep prepare data needed for redirect and perform the redirection to the external service. + ``` + def prepareForStep(self, step, context): + ..... + facesService = CdiUtil.bean(FacesService) + facesService.redirectToExternalURL(third_party_URL ) + + return True + ``` + - In order to resume flow after the redirection, invoke a similar URL to https://my.gluu.server/postlogin.htm?param=123 from the third party app which takes the flow back to the authenticate method of the custom script. +So create an xhtml page postlogin.xhtml which will look like this : + ``` + + + + + + + + + + + + ``` +The `` in step 4 takes us to the authenticate method inside the custom script `def authenticate(self, configurationAttributes, requestParameters, step):`. Here you can + - use parameters from request + ``` + param = ServerUtil.getFirstValue(requestParameters, "param-name")) + ``` + - perform the `state` check (state : Opaque value used to maintain state between the request and the callback.) + + - finally, return true or false from this method. + +3. diff --git a/docs/admin/developer/scripts/person-authentication-interface.md b/docs/admin/developer/scripts/person-authentication-interface.md index c14500906e9..4639bb538cf 100644 --- a/docs/admin/developer/scripts/person-authentication-interface.md +++ b/docs/admin/developer/scripts/person-authentication-interface.md @@ -3,6 +3,9 @@ tags: - administration - developer - scripts + - PersonAuthenticationType + - authentication + - authentication workflow --- ## Person Authentication interface @@ -55,8 +58,8 @@ Pseudo code: |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.| |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.| |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.| -|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.| -|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.| +|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.| +|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.| #### Objects | Object name | Object description | @@ -65,7 +68,6 @@ Pseudo code: |`SimpleCustomProperty`| Map of configuration properties. [Reference](https://github.com/JanssenProject/jans/blob/main/jans-core/util/src/main/java/io/jans/model/SimpleCustomProperty.java) | |usageType|[AuthenticationScriptUsageType](https://github.com/JanssenProject/jans/blob/main/jans-core/util/src/main/java/io/jans/model/AuthenticationScriptUsageType.java)| |step|Integer indicating step number| -|step|Integer indicating step number| |requestParameters|Request parameters stored as Map| diff --git a/docs/admin/developer/scripts/person-authentication.md b/docs/admin/developer/scripts/person-authentication.md index 41e099dfab0..7bc59983ac2 100644 --- a/docs/admin/developer/scripts/person-authentication.md +++ b/docs/admin/developer/scripts/person-authentication.md @@ -8,7 +8,6 @@ tags: - PersonAuthenticationType - acr - weld - - --- @@ -33,10 +32,38 @@ Jans-auth server comprises of a number of beans, configuration files and Facelet ### A. Custom script The **PersonAuthenticationType** script is described by a java interface whose methods should be overridden to implement an authentication workflow. -The [article](./person-authentication-interface) talks about these methods in detail and the psuedo code for each method. +The [article](../scripts/person-authentication-interface) talks about these methods in detail and the psuedo code for each method. ### B. UI pages: -All web pages are **xhtml** files. The Jans-auth server comes with a default set of pages for login, logout, errors, authorizations. You can easily override these pages or write new ones. You can easily apply your own stylesheet, images and resouce-bundles to your pages. +All web pages are **xhtml** files. The Command-Action offering by JSF framework is used by the Jans-auth server to implement authentication flows. + +#### a. Server-side actions implemented by custom script: +The custom script's `authenticate` and `prepareForStep` implementations are called by the following java class - [Authenticator](https://github.com/JanssenProject/jans/blob/main/jans-auth-server/server/src/main/java/io/jans/as/server/auth/Authenticator.java). These methods are mapped as command actions and view actions respectively in the web page. + +Relevant methods: + +|Signature|Description| +|-|-| +|boolean authenticate()|Makes the authentication flow proceed by calling the `authenticate` method of the custom script| +|String prepareAuthenticationForStep()|Makes the authentication flow proceed by calling the `prepareForStep` method of the custom script| + +#### b. Web page in xhtml: +1. The `f:metadata` and `f:viewAction` tags are used to load variables (prepared in the `prepareForStep` method of the custom script). These variables are rendered on the UI page. +``` + + + +``` +2. A form submit takes the flow to the `authenticate()` method of the custom script. +``` + +``` + +#### c. Page customizations: +The Jans-auth server comes with a default set of pages for login, logout, errors, authorizations. You can easily override these pages or write new ones. You can easily apply your own stylesheet, images and resouce-bundles to your pages. This [article](../../customization/customize-web-pages) covers all the details you need to write your own web page. @@ -84,8 +111,13 @@ Each authentication mechanism (script) has a "Level" assigned to it which descri ### A. Implementing 2FA authentication mechanisms 1. [FIDO2](../../../script-catalog/person_authentication/fido2-external-authenticator/README) : Authentications using platform authenticators embedded into a person's device or physical USB, NFC or Bluetooth security keys that are inserted into a USB slot of a computer + +2. [OTP authentication](../../../script-catalog/person_authentication/otp-external-authenticator) : Authentication mechanism using an app like [Google authenticator](https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=en), [FreeOTP](https://freeotp.github.io/) or [Authy](https://authy.com/) that implements the open standards [HOTP](https://tools.ietf.org/html/rfc4226) and [TOTP](https://tools.ietf.org/html/rfc6238) + 2. SMS OTP : -3. Email OTP + +3. Email OTP: + ### B. Implementing Multistep authentication 1. [Redirect to previous step](https://github.com/JanssenProject/jans/blob/main/jans-linux-setup/jans_setup/static/extension/person_authentication/other/basic.reset_to_step/BasicResetToStepExternalAuthenticator.py): The script here an example of how the number of steps can be varied depending on the context or business requirement. diff --git a/docs/admin/recipes/social-login.md b/docs/admin/recipes/social-login.md index 1a6e01cbed8..ff0296272ac 100644 --- a/docs/admin/recipes/social-login.md +++ b/docs/admin/recipes/social-login.md @@ -1,14 +1,18 @@ --- tags: - administration - - recipes + - Social login + - Google + - Apple + - Facebook --- ## Implementing Social logins You can use a `PersonAuthenticationType` script to allow users to sign using credentials from popular **Social Identity providers** or **Inbound Identity Providers** like Facebook, Google and Apple. After users authenticate, we provision their Social Identity Provider credentials into the Jans-auth server. No additional username, password, credentials are needed for this user. + 1. Facebook -2. [Google](../../script-catalog/person-authentication/google-external-authenticator/README.md) -3. [Apple](../../script-catalog/person-authentication/apple-external-authenticator/README.md) +2. [Google](../../../script-catalog/person-authentication/google-external-authenticator/README.md) +3. [Apple](../../../script-catalog/person-authentication/apple-external-authenticator/README.md) Following is a high-level diagram depicting a typical flow - user authentication on a Social Identity Platform and subsequent user provisioning on Jans-Auth server. @@ -35,7 +39,7 @@ Jans AS->User agent: 10. write Jans session cookie ``` ![Social Sign-In](https://github.com/JanssenProject/jans/raw/main/docs/assets/SocialSignIn.png) -### How user provisioning works +### User provisioning After a user has logged in at an external provider a new record is added in local LDAP - or updated if the user is known.