{"id":15898666,"url":"https://github.com/vzakharchenko/keycloak-radius-plugin","last_synced_at":"2025-05-16T11:03:48.189Z","repository":{"id":37180475,"uuid":"232993145","full_name":"vzakharchenko/keycloak-radius-plugin","owner":"vzakharchenko","description":"Make the radius server as part of keycloak SSO","archived":false,"fork":false,"pushed_at":"2025-05-11T02:44:02.000Z","size":15281,"stargazers_count":209,"open_issues_count":122,"forks_count":48,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-05-11T03:29:25.616Z","etag":null,"topics":["authport","chillispot","cisco","docker","docker-compose","fido2","hotspot","keycloak","keycloak-plugin","mikrotik","radius","radius-accounting","radius-attributes","radius-plugin","radius-protocol","radius-proxy","radius-server","radsec-server","webauthn","yubikey"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vzakharchenko.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"docs/securityKeyOrFingerPrintRegistration.png","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-01-10T07:43:15.000Z","updated_at":"2025-05-06T22:11:25.000Z","dependencies_parsed_at":"2023-02-15T18:31:35.905Z","dependency_job_id":"cba7e059-e3f9-4e07-bffb-b885eb996e24","html_url":"https://github.com/vzakharchenko/keycloak-radius-plugin","commit_stats":null,"previous_names":[],"tags_count":46,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vzakharchenko%2Fkeycloak-radius-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vzakharchenko%2Fkeycloak-radius-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vzakharchenko%2Fkeycloak-radius-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vzakharchenko%2Fkeycloak-radius-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vzakharchenko","download_url":"https://codeload.github.com/vzakharchenko/keycloak-radius-plugin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254518384,"owners_count":22084374,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authport","chillispot","cisco","docker","docker-compose","fido2","hotspot","keycloak","keycloak-plugin","mikrotik","radius","radius-accounting","radius-attributes","radius-plugin","radius-protocol","radius-proxy","radius-server","radsec-server","webauthn","yubikey"],"created_at":"2024-10-06T10:07:19.256Z","updated_at":"2025-05-16T11:03:48.159Z","avatar_url":"https://github.com/vzakharchenko.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Embedded Radius Server in [Keycloak](https://www.keycloak.org/) SSO\n[![CircleCI](https://circleci.com/gh/vzakharchenko/keycloak-radius-plugin/tree/master.svg?style=svg)](https://circleci.com/gh/vzakharchenko/keycloak-radius-plugin/tree/master)\n![Java CI with Maven](https://github.com/vzakharchenko/keycloak-radius-plugin/workflows/Java%20CI%20with%20Maven/badge.svg)\n![Node.js Examples](https://github.com/vzakharchenko/keycloak-radius-plugin/workflows/Node.js%20Examples/badge.svg)\n[![Coverage Status](https://coveralls.io/repos/github/vzakharchenko/keycloak-radius-plugin/badge.svg?branch=master)](https://coveralls.io/github/vzakharchenko/keycloak-radius-plugin?branch=master)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.vzakharchenko/keycloak-plugins/badge.svg)]\n\u003ca href=\"https://codeclimate.com/github/vzakharchenko/keycloak-radius-plugin/maintainability\"\u003e\u003cimg src=\"https://api.codeclimate.com/v1/badges/499d56ae9242cfaf2cbb/maintainability\" /\u003e\u003c/a\u003e\n[![BCH compliance](https://bettercodehub.com/edge/badge/vzakharchenko/keycloak-radius-plugin?branch=master)](https://bettercodehub.com/)\n\nRun radius server inside [keycloak](https://www.keycloak.org/).\nfeatures:\n- Embedded radius server in [keycloak](https://www.keycloak.org/)\n- use keycloak authentication and authorization for the embedded RADIUS server\n- [radius oidc password](Examples/OneTimePasswordJSExample)\n- [webAuthn authentication. Radius Authentication using your fingerprint or FIDO2 security key](Examples/WebAuthnJSExample)\n- [radius OTP password (TOTP/HOTP via Google Authenticator or FreeOTP)](#otp-password)\n- use [Keycloak user credentials, if radius access-request protocol is PAP](#mapping-radius-password-to-keycloak-credentials) Otherwise is using [Keycloak Radius credentials](#keycloak-radius-credentials) or OTP\n- [use Kerberos/ldap credentials(only if Radius client use PAP authorization)](#mapping-radius-password-to-keycloak-credentials)\n- can work as [radius proxy](#radius-proxy)\n- support [Radsec Protocol](keycloak-plugins/rad-sec-plugin/README.md#radsec-example) (Radius over TLS)\n- Map Keycloak [authorization](#assign-radius-attributes-to-authorization-resource) ,  [Role](#assign-radius-attributes-to-role), [Group](#assign-radius-attributes-to-group) and [User](#assign-radius-attributes-to-user) Attributes to Radius Attributes\n- conditional attributes for authorization/Role/Group/User\n- reject attribute for authorization/Role/Group/User\n- dynamically assign attributes based on keycloak policies(Role, [javascript](Examples/RadiusAuthorizationJSExample), Time, User)\n- start/stop Keycloak Session ![sessionManagment.png](./docs/sessionManagment.png)\n- BackChannel logout(Disconnect-message request)\n- Service to Service communication\n- [Mikrotik plugin](keycloak-plugins/mikrotik-radius-plugin)\n- [Cisco plugin](keycloak-plugins/cisco-radius-plugin) (thanks [vbkunin](https://github.com/vbkunin))\n- [Chillispot plugin](keycloak-plugins/chillispot-radius-plugin)\n- [Social Hotspot Login](https://github.com/vzakharchenko/mikrotik-hotspot-oauth)\n- [PPTP VPN with Radsec](https://github.com/vzakharchenko/pptp-radius-docker)\n- [L2TP IPSec VPN with Radius and Radsec](https://github.com/vzakharchenko/l2tp-ipsec-radius-docker)\n- Specify Realm in username: username@realm\n- support docker arm64 and arm/v7\n\n## Examples\n - [Assign attributes dynamically using javascript policy](Examples/RadiusAuthorizationJSExample)\n - [Reject and Accept by condition example](Examples/ConditionAccessRequestJSExample)\n - [Radius and OIDC integration example](Examples/OneTimePasswordJSExample)\n - [OTP Password example](Examples/OTPPasswordJSExample)\n - [Ldap Password with OTP example](Examples/LdapOtpExample)\n - [Default Realm example(if the radius client does not support realm attribute)](Examples/RadiusDefaultRealmJSExample)\n - [An example of a call from  backend service to radius using a service account (Service to Service communication)](Examples/RadiusServiceAccountJSExample)\n - [WebAuthn authentication. Radius Authentication using your fingerprint or FIDO2 security key](Examples/WebAuthnJSExample)\n\n## Donate\n\u003ca href=\"https://secure.wayforpay.com/button/bf1e79d05af0c\" style=\"display:inline-block!important;background:#2B3160 url('https://s3.eu-central-1.amazonaws.com/w4p-merch/button/bg6x2.png') no-repeat center right;background-size:cover;width: 256px!important;height:54px!important;border:none!important;border-radius:14px!important;padding:18px!important;text-decoration:none!important;box-shadow:3px 2px 8px rgba(71,66,66,0.22)!important;text-align:left!important;box-sizing:border-box!important;\" onmouseover=\"this.style.opacity='0.8';\" onmouseout=\"this.style.opacity='1';\"\u003e\u003cspan style=\"font-family:Verdana,Arial,sans-serif!important;font-weight:bold!important;font-size:14px!important;color:#ffffff!important;line-height:18px!important;vertical-align:middle!important;\"\u003eDonate\u003c/span\u003e\u003c/a\u003e\n\n## Release Setup\n1. Download  keycloak-radius.zip asset from [github releases](https://github.com/vzakharchenko/keycloak-radius-plugin/releases)\n2. unzip release \u003cpre\u003e\u003ccode\u003eunzip keycloak-radius.zip -d keycloak-radius\u003c/pre\u003e\u003c/code\u003e\n3. run keycloak  \u003cpre\u003e\u003ccode\u003esh keycloak-radius/bin/standalone.sh  -c standalone.xml -b 0.0.0.0 -Djboss.bind.address.management=0.0.0.0 --debug 8190 -Djboss.http.port=8090\u003c/pre\u003e\u003c/code\u003e\n4. open http://localhost:8090\n5. initialize keycloak master realm\n## Docker Container\n[Run inside Docker Container](docker/README.md)\n## Manual Setup\n### build project\n***requirements***: java jdk 11 and above, maven 3.5 and above\n - ```cd keycloak-plugins```\n - ```mvn clean install```\n### Configure Keycloak (based on Quarkus)\n***requirements***: [keycloak 21.0.0](https://github.com/keycloak/keycloak/releases/download/21.0.0/keycloak-21.0.0.zip)\n```bash\ncp ${SOURCE}/keycloak-plugins/radius-plugin/target/radius-plugin-1.5.0-SNAPSHOT.jar ${KEYCLOAK_PATH}/providers/radius-plugin-1.5.0-SNAPSHOT.jar\ncp ${SOURCE}/keycloak-plugins/rad-sec-plugin/target/rad-sec-plugin-1.5.0-SNAPSHOT.jar ${KEYCLOAK_PATH}/providers/rad-sec-plugin-1.5.0-SNAPSHOT.jar\ncp ${SOURCE}/keycloak-plugins/mikrotik-radius-plugin/target/mikrotik-radius-plugin-1.5.0-SNAPSHOT.jar ${KEYCLOAK_PATH}/providers/mikrotik-radius-plugin-1.5.0-SNAPSHOT.jar\ncp ${SOURCE}/keycloak-plugins/cisco-radius-plugin/target/cisco-radius-plugin-1.5.0-SNAPSHOT.jar ${KEYCLOAK_PATH}/providers/cisco-radius-plugin-1.5.0-SNAPSHOT.jar\ncp ${SOURCE}/keycloak-plugins/chillispot-radius-plugin/target/chillispot-radius-plugin-1.5.0-SNAPSHOT.jar ${KEYCLOAK_PATH}/providers/chillispot-radius-plugin-1.5.0-SNAPSHOT.jar\ncp ${SOURCE}/keycloak-plugins/radius-disconnect-plugin/target/radius-disconnect-plugin-1.5.0-SNAPSHOT.jar ${KEYCLOAK_PATH}/providers/radius-disconnect-plugin-1.5.0-SNAPSHOT.jar\ncp ${SOURCE}/keycloak-plugins/proxy-radius-plugin/target/proxy-radius-plugin-1.5.0-SNAPSHOT.jar ${KEYCLOAK_PATH}/providers/proxy-radius-plugin-1.5.0-SNAPSHOT.jar\ncp ${SOURCE}/keycloak-radius-plugin/keycloak-plugins/radius-theme/target/radius-theme-1.5.0-SNAPSHOT.zip ${KEYCLOAK_PATH}/providers/radius-theme-1.5.0-SNAPSHOT.jar\n```\nwhere\n- **KEYCLOAK_PATH** - Path where you are unpacked keycloak-21.0.0.zip [(you can use RADIUS_CONFIG_PATH instead of KEYCLOAK_PATH)](#environment-variables)\n- **SOURCE** - Path where you checked out the code and built the project\n\n### Environment Variables\n\n| Variable Name      | Variable Value                         | Config file Location                         |\n|--------------------|----------------------------------------|----------------------------------------------|\n| KEYCLOAK_PATH      | Path where you are unpacked keycloak   | ${KEYCLOAK_PATH}/config/radius.config        |\n| RADIUS_CONFIG_PATH | Path where you store radius.config     | ${RADIUS_CONFIG_PATH}/radius.config          |\n\nExamples:\n```\nexport RADIUS_CONFIG_PATH= /opt/keycloak/radius/config\n```\nor\n```\nexport KEYCLOAK_PATH= /opt/keycloak/\n```\n\n## Configuration\n### Radius server config file\n-  create file ${KEYCLOAK_PATH}config/radius.config or ${RADIUS_CONFIG_PATH}/radius.config\n-  example \u003cpre\u003e\u003ccode\u003e{\n  \"sharedSecret\": \"radsec\",\n  \"authPort\": 1812,\n  \"accountPort\": 1813,\n  \"numberThreads\": 8,\n  \"useUdpRadius\": true,\n  \"externalDictionary\": \"/opt/dictionary\",\n  \"otp\": false,\n  \"radsec\": {\n    \"privateKey\": \"config/private.key\",\n    \"certificate\": \"config/public.crt\",\n    \"numberThreads\": 8,\n    \"useRadSec\": true\n  },\n   \"coa\":{\n      \"port\":3799,\n      \"useCoA\":true\n   }\n}\n\u003c/code\u003e\u003c/pre\u003e\nwhere\n\n -  **sharedSecret** - Used to secure communication between a RADIUS server and a RADIUS client.\n   -  **authPort** - Authentication and authorization port\n   -  **accountPort** - Accounting port\n   -  **useUdpRadius** - if true, then listen to authPort and accountPort\n   -  **radsec** - radsec configuration\n   -  **privateKey** - private SSL key (https://netty.io/wiki/sslcontextbuilder-and-private-key.html)\n   -  **certificate** - certificates chain\n   -  **useRadSec** - if true, then listen  radsec port\n   -  **numberThreads** - number of connection threads\n   -  **coa** - CoA request configuration\n   -  **port** - CoA port (Mikrotik:3799, Cisco:1700)\n   -  **useCoA** - use CoA request\n   -  **otp** - use OTP without password\n   -  **externalDictionary** - path to the dictionary file in freeradius format\n##\n Run Keycloak Locally\n```bash\n#!/usr/bin/env bash\nset -e\ncd keycloak-21.0.0\nsh bin/kc.sh --debug 8190 start-dev --http-port=8090\n```\n\n### Keycloak Client with Radius Protocol\n![radiusProtocol](docs/radiusProtocol.png)\n\n### Mapping Radius Password to Keycloak Credentials\n\n| Radius Protocol | Keycloak credentials | Keycloak credentials with OTP | Kerberos credentials | Ldap credentials | [Keycloak Radius credentials](#keycloak-radius-credentials) | [Keycloak Radius credentials](#keycloak-radius-credentials) with OTP | Keycloak OTP(if config file contains \"otp\":true) |\n|-----------------|----------------------|-------------------------------|----------------------|------------------|-----------------------------|--------------------------------------|--------------------------------------------------|\n| PAP             | Yes                  | Yes                           | Yes                  | Yes              | Yes                         | Yes                                  | NO                                              |\n| CHAP            | No                   | No                            | No                   | No               | Yes                         | Yes                                  | Yes                                              |\n| MSCHAPV2        | No                   | No                            | No                   | No               | Yes                         | Yes                                  | Yes                                              |\n\n### Assign Radius Attributes to Role\n\u003e **_NOTE:_**  Composite roles supported\n\n![RoleAttributes](docs/RoleAttributes.png)\n#### Role Conditional Attributes\nif conditional Attribute is present and has valid value then all other attributes will be applied.\n(Example: apply role attributes only if NAS-IP-Address= 192.168.88.1)\n\n**Structure of Attribute:** \u003cpre\u003e\\\u003cPREFIX\\\u003e\\\u003cATTRIBUTE_NAME\\\u003e=\\\u003cvalues\\\u003e\u003c/pre\u003e\n\n- **PREFIX** = \u003cpre\u003eCOND_\u003c/pre\u003e\n- **ATTRIBUTE_NAME** attribute name from access-request\n- **VALUES** Comma-separated list of attribute values\n\nExample:\n\u003cpre\u003eCOND_NAS-IP-Address = \"192.168.88.1, 192.168.88.2\"\u003c/pre\u003e\n![ConditionalRole](docs/ConditionalRole.png)\nThe role will only be applied if the NAS server address is 192.168.88.1 or 192.168.88.2.\n#### Role REJECT Attributes ([Example](Examples/ConditionAccessRequestJSExample))\nif reject Attribute is present and has valid value then access request will be rejected.\n(Example: reject user request if access request contains attribute NAS-IP-Address= 192.168.88.1)\n\n**Structure of Attribute:** \u003cpre\u003e\\\u003cPREFIX\\\u003e\\\u003cATTRIBUTE_NAME\\\u003e=\\\u003cvalues\\\u003e\u003c/pre\u003e\n\n- **PREFIX** = \u003cpre\u003eREJECT_\u003c/pre\u003e\n- **ATTRIBUTE_NAME** attribute name from access-request\n- **VALUES** Comma-separated list of attribute values\n\nExample:\n\u003cpre\u003eREJECT_NAS-IP-Address = \"192.168.88.2\"\u003c/pre\u003e\n![reject_conditional](docs/reject_conditional.png)\nThe role will only be applied if the NAS server address is not 192.168.88.2, otherwise request will be rejected\n\n#### Role REJECT WITHOUT CONDITION\nIf Reject Attribute is present then access request will be rejected.\n**Structure of Attribute:** ```REJECT_RADIUS=\u003cANY VALUE\u003e```\nExample:\n\u003cpre\u003eREJECT_RADIUS = \"true\"\u003c/pre\u003e\n\n#### Role ACCEPT Attributes ([Example](Examples/ConditionAccessRequestJSExample))\nif accept Attribute is present and has valid value then access request will be accepted, otherwise rejected.\n(Example: accept user request if access request contains attribute NAS-IP-Address= 192.168.88.1,192.168.88.2)\n\n**Structure of Attribute:** \u003cpre\u003e\\\u003cPREFIX\\\u003e\\\u003cATTRIBUTE_NAME\\\u003e=\\\u003cvalues\\\u003e\u003c/pre\u003e\n\n- **PREFIX** = \u003cpre\u003eACCEPT_\u003c/pre\u003e\n- **ATTRIBUTE_NAME** attribute name from access-request\n- **VALUES** Comma-separated list of attribute values\n\nExample:\n\u003cpre\u003eACCEPT_NAS-IP-Address = \"192.168.88.1\"\u003c/pre\u003e\n![acceptConditional](docs/acceptConditional.png)\nThe role will only be applied if the NAS server address is not 192.168.88.2, otherwise request will be rejected\n\n### Assign Radius Attributes to Group\n\u003e **_NOTE:_**  SubGroups supported\n![groupAttributes](docs/groupAttributes.png)\n#### Group Conditional Attributes\nif conditional Attribute is present and has valid value then all other attributes will be applied.\n(Example: apply group attributes only if NAS-IP-Address= 192.168.88.1)\n\n**Structure of Attribute:** \u003cpre\u003e\\\u003cPREFIX\\\u003e\\\u003cATTRIBUTE_NAME\\\u003e=\\\u003cvalues\\\u003e\u003c/pre\u003e\n\n- **PREFIX** = \u003cpre\u003eCOND_\u003c/pre\u003e\n- **ATTRIBUTE_NAME** attribute name from access-request\n- **VALUES** Comma-separated list of attribute values\n\nExample:\n[Role Conditional Attributes](#role-conditional-attributes)/README.md:1\n#### Group REJECT Attributes\nif reject Attribute is present and has valid value then access request will be rejected.\n(Example: reject user request if access request contains attribute NAS-IP-Address= 192.168.88.1)\n\n**Structure of Attribute:** \u003cpre\u003e\\\u003cPREFIX\\\u003e\\\u003cATTRIBUTE_NAME\\\u003e=\\\u003cvalues\\\u003e\u003c/pre\u003e\n\n- **PREFIX** = \u003cpre\u003eREJECT_\u003c/pre\u003e\n- **ATTRIBUTE_NAME** attribute name from access-request\n- **VALUES** Comma-separated list of attribute values\n\nExample:\n[Role REJECT Attributes](#role-reject-attributes)\n\n\n#### Group REJECT WITHOUT CONDITION\nIf Reject Attribute is present then access request will be rejected.\n**Structure of Attribute:** ```REJECT_RADIUS=\u003cANY VALUE\u003e```\nExample:\n\u003cpre\u003eREJECT_RADIUS = \"true\"\u003c/pre\u003e\n\n#### Group ACCEPT Attributes\nif accept Attribute is present and has valid value then access request will be accepted, otherwise rejected.\n(Example: accept user request if access request contains attribute NAS-IP-Address= 192.168.88.1,192.168.88.2)\n\n**Structure of Attribute:** \u003cpre\u003e\\\u003cPREFIX\\\u003e\\\u003cATTRIBUTE_NAME\\\u003e=\\\u003cvalues\\\u003e\u003c/pre\u003e\n\n- **PREFIX** = \u003cpre\u003eACCEPT_\u003c/pre\u003e\n- **ATTRIBUTE_NAME** attribute name from access-request\n- **VALUES** Comma-separated list of attribute values\n\nExample:\n[Role ACCEPT Attributes](#role-accept-attributes)\n### Assign Radius Attributes to User\n![userAttributes](docs/userAttributes.png)\n#### User Conditional Attributes\nif conditional Attribute is present and has valid value then all other attributes will be applied.\n(Example: apply user attributes only if NAS-IP-Address= 192.168.88.1)\n\n**Structure of Attribute:** \u003cpre\u003e\\\u003cPREFIX\\\u003e\\\u003cATTRIBUTE_NAME\\\u003e=\\\u003cvalues\\\u003e\u003c/pre\u003e\n\n- **PREFIX** = \u003cpre\u003eCOND_\u003c/pre\u003e\n- **ATTRIBUTE_NAME** attribute name from access-request\n- **VALUES** Comma-separated list of attribute values\n\nExample:\n[Role Conditional Attributes](#role-conditional-attributes)/README.md:1\n#### User REJECT Attributes\nif reject Attribute is present and has valid value then access request will be rejected.\n(Example: reject user request if access request contains attribute NAS-IP-Address= 192.168.88.1)\n\n**Structure of Attribute:** \u003cpre\u003e\\\u003cPREFIX\\\u003e\\\u003cATTRIBUTE_NAME\\\u003e=\\\u003cvalues\\\u003e\u003c/pre\u003e\n\n- **PREFIX** = \u003cpre\u003eREJECT_\u003c/pre\u003e\n- **ATTRIBUTE_NAME** attribute name from access-request\n- **VALUES** Comma-separated list of attribute values\n\nExample:\n[Role REJECT Attributes](#role-reject-attributes)\n#### User ACCEPT Attributes\nif accept Attribute is present and has valid value then access request will be accepted, otherwise rejected.\n(Example: accept user request if access request contains attribute NAS-IP-Address= 192.168.88.1,192.168.88.2)\n\n**Structure of Attribute:** \u003cpre\u003e\\\u003cPREFIX\\\u003e\\\u003cATTRIBUTE_NAME\\\u003e=\\\u003cvalues\\\u003e\u003c/pre\u003e\n\n- **PREFIX** = \u003cpre\u003eACCEPT_\u003c/pre\u003e\n- **ATTRIBUTE_NAME** attribute name from access-request\n- **VALUES** Comma-separated list of attribute values\n\nExample:\n[Role ACCEPT Attributes](#role-accept-attributes)\n\n### Assign Radius Attributes to Authorization Resource\n#### Change admin theme to \"Radius\"\n![radiusTheme](docs/radiusTheme.png)\n#### Enable Authorization on Radius Client\n![Authorization](docs/Authorization.png)\n#### [Create Resource](https://www.keycloak.org/docs/latest/authorization_services/#_resource_overview)\n![Authorization](docs/createResource.png)\n#### [Assign Attributes to Resource](https://www.keycloak.org/docs/latest/authorization_services/#resource-attributes)\n![assignAttributesToResource](docs/assignAttributesToResource.png)\n#### Create policy and permissions\n- [authorization policies](https://www.keycloak.org/docs/latest/authorization_services/#_policy_overview)\n![policies](docs/policies.png)\n- [authorization permissions](https://www.keycloak.org/docs/latest/authorization_services/#_permission_overview)\n![Permissions](docs/Permissions.png)\n#### Resource Conditional Attributes\nif conditional Attribute is present and has valid value then all other attributes will be applied.\n(Example: apply user attributes only if NAS-IP-Address= 192.168.88.1)\n\n**Structure of Attribute:** \u003cpre\u003e\\\u003cPREFIX\\\u003e\\\u003cATTRIBUTE_NAME\\\u003e=\\\u003cvalues\\\u003e\u003c/pre\u003e\n\n- **PREFIX** = \u003cpre\u003eCOND_\u003c/pre\u003e\n- **ATTRIBUTE_NAME** attribute name from access-request\n- **VALUES** Comma-separated list of attribute values\n\nExample:\n[Role Conditional Attributes](#role-conditional-attributes)/README.md:1\n#### Resource REJECT Attributes\nif reject Attribute is present and has valid value then access request will be rejected.\n(Example: reject user request if access request contains attribute NAS-IP-Address= 192.168.88.1)\n\n**Structure of Attribute:** \u003cpre\u003e\\\u003cPREFIX\\\u003e\\\u003cATTRIBUTE_NAME\\\u003e=\\\u003cvalues\\\u003e\u003c/pre\u003e\n\n- **PREFIX** = \u003cpre\u003eREJECT_\u003c/pre\u003e\n- **ATTRIBUTE_NAME** attribute name from access-request\n- **VALUES** Comma-separated list of attribute values\n\nExample:\n[Role REJECT Attributes](#role-reject-attributes-example)\n#### Resource REJECT without condition\nIf Reject Attribute is present then access request will be rejected.\n**Structure of Attribute:** ```REJECT_RADIUS=\u003cANY VALUE\u003e```\nExample:\n\u003cpre\u003eREJECT_RADIUS = \"true\"\u003c/pre\u003e\n\n#### Resource ACCEPT Attributes\nif accept Attribute is present and has valid value then access request will be accepted, otherwise rejected.\n(Example: accept user request if access request contains attribute NAS-IP-Address= 192.168.88.1,192.168.88.2)\n\n**Structure of Attribute:** \u003cpre\u003e\\\u003cPREFIX\\\u003e\\\u003cATTRIBUTE_NAME\\\u003e=\\\u003cvalues\\\u003e\u003c/pre\u003e\n\n- **PREFIX** = \u003cpre\u003eACCEPT_\u003c/pre\u003e\n- **ATTRIBUTE_NAME** attribute name from access-request\n- **VALUES** Comma-separated list of attribute values\n\nExample:\n[Role ACCEPT Attributes](#role-accept-attributes-example)\n\n\n###  Hotspot Example (with Facebook login)\n\n[Hotspot Example (with Facebook login)](hotspot)\n\n### Example CoA Configuration\n[Radius Disconnect Message](keycloak-plugins/radius-disconnect-plugin)\n\n### Radius Proxy\n\n[Radius Proxy Module](keycloak-plugins/proxy-radius-plugin)\n\n### Keycloak Radius credentials\n - Setup Radius Credentials during first time login\n     1. set Action \"Update Radius Password\" (or send this event to user be email) ![updateRadiusPassword](./docs/updateRadiusPassword.png)\n     2. User sets his own Radius password ![RadiusUserPassword](./docs/RadiusUserPassword.png)\n\n\n### Otp Password\n\n1. enable Otp Password on Keycloak side. https://www.keycloak.org/docs/latest/server_admin/\n![impersonateUserExample3](./docs/impersonateUserExample3.png) ![impersonateUserExample4](./docs/impersonateUserExample4.png)\n2.  password in request must contain the password and otp.\n3. Structure Password in request:\n    -  PAP password: ```\u003cKeycloak Password/RADIUS Password\u003e\u003cOTP\u003e```\n           example: testPassword123456, where testPassword is password, 123456 is otp\n    -  MSCHAP/CHAP: ```\u003cRADIUS Password\u003e\u003cOTP\u003e```\n           example: testPassword123456, where testPassword is password, 123456 is otp\n    -  PAP password with Otp (if config file contains \"otp\":true) : ```\u003cOTP\u003e```\n           example: 123456, where 123456 is otp\n\n[OTP Password example](Examples/OTPPasswordJSExample)\n\n### WebAuthn Authentication\n[wiki page](https://github.com/vzakharchenko/keycloak-radius-plugin/wiki/WebAuthnRadius)\n\n## Add custom Radius Dictionary(example for Fortinet)\n - create dictionary Fortinet.dictionary:\n```\nVENDOR\t\t12356   Fortinet\n\nVENDORATTR\t12356 Fortinet-Group-Name\t\t\t1\tstring\nVENDORATTR\t12356 Fortinet-Client-IP-Address\t\t2\tipaddr\nVENDORATTR\t12356 Fortinet-Vdom-Name\t\t\t3\tstring\nVENDORATTR\t12356 Fortinet-Client-IPv6-Address\t\t4\toctets\nVENDORATTR\t12356 Fortinet-Interface-Name\t\t\t5\tstring\nVENDORATTR\t12356 Fortinet-Access-Profile\t\t\t6\tstring\n```\n - run as docker container\n```\n  docker run -p 8090:8080 -e  -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true\" -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -e RADIUS_DICTIONARY=/opt/dictionary -v `pwd`/Fortinet.dictionary:/opt/dictionary   vassio/keycloak-radius-plugin\n```\n\n### Development\n[wiki page](https://github.com/vzakharchenko/keycloak-radius-plugin/wiki/Development)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvzakharchenko%2Fkeycloak-radius-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvzakharchenko%2Fkeycloak-radius-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvzakharchenko%2Fkeycloak-radius-plugin/lists"}