{"id":13596268,"url":"https://github.com/uchicago/shibboleth-oidc","last_synced_at":"2025-04-09T16:32:00.666Z","repository":{"id":34172729,"uuid":"38020074","full_name":"uchicago/shibboleth-oidc","owner":"uchicago","description":"OpenID Connect support for the Shibboleth Identity Provider  v3","archived":false,"fork":false,"pushed_at":"2020-10-13T00:47:27.000Z","size":4145,"stargazers_count":81,"open_issues_count":9,"forks_count":19,"subscribers_count":22,"default_branch":"master","last_synced_at":"2024-11-06T19:42:31.440Z","etag":null,"topics":["authentication","federation","mitreid","openid-connect","saml2","shibboleth-identity-provider"],"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/uchicago.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-06-25T01:13:03.000Z","updated_at":"2024-03-30T21:01:48.000Z","dependencies_parsed_at":"2022-09-03T08:52:03.192Z","dependency_job_id":null,"html_url":"https://github.com/uchicago/shibboleth-oidc","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uchicago%2Fshibboleth-oidc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uchicago%2Fshibboleth-oidc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uchicago%2Fshibboleth-oidc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uchicago%2Fshibboleth-oidc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/uchicago","download_url":"https://codeload.github.com/uchicago/shibboleth-oidc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248067840,"owners_count":21042362,"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":["authentication","federation","mitreid","openid-connect","saml2","shibboleth-identity-provider"],"created_at":"2024-08-01T16:02:13.886Z","updated_at":"2025-04-09T16:31:55.647Z","avatar_url":"https://github.com/uchicago.png","language":"Java","funding_links":[],"categories":["Java"],"sub_categories":[],"readme":"# OpenId Connect for Shibboleth Identity Provider v3 [![License](https://img.shields.io/hexpm/l/plug.svg)](https://github.com/uchicago/shibboleth-oidc/blob/master/LICENSE) \n\n## Contents\n\n- [Scope](#scope)\n- [Design](#design)\n- [Default IdP Configuration](#default-idp-configuration)\n- [Overlay IdP Configuration](#overlay-idp-configuration)\n\n## Heroku [![](https://heroku-badge.herokuapp.com/?app=shibboleth-oidc)](https://shibboleth-oidc.herokuapp.com/idp)\n\nAn instance of this codebase is presently running on [Heroku](https://shibboleth-oidc.herokuapp.com/idp). \nYou may need to refresh the page twice to wake up the instance as idle timeouts may cause it to go down.\n\n## Scope\n\nWe are working on adding support for the OpenID Connect protocol to the Shibboleth Identity Provider v3. Realistically, these\nare the items we are planning to address:\n\n* Authorization code workflow\n* Dynamic discovery\n* Administration and registration of OIDC RPs with the IdP. \n* Ability to resolve, consume and release OIDC claims, taking advantage of IdP's machinery to release attributes. \n* Ability to configure an expiration and revocation policy around OIDC access and refresh tokens from an admin perspective. \n\nNote that no significant UI enhancements are taken into account. All configuration and changes are directly assumed to be applied to the IdP config without the presence of a web interface to facilitate. This includes administration and management of metadata, authZ codes and more.\n\n### Resources\n\n* [OpenID Connect Basic](http://openid.net/specs/openid-connect-basic-1_0.html)\n* [OpenID Connect Implicit](http://openid.net/specs/openid-connect-implicit-1_0.html)\n \n### Planned\n\nThe following may be considered in future versions:\n\n* Hybrid flow\n* Implicit flow\n* Dynamic RP registration\n* Logout\n* Web UIs that facilitate managing tokens, whitelisted/blacklisted RPs, etc. \n\n### Toolkit\n\n- Apache Maven v3.5+\n- JDK 8+\n- [MITREid Connect v1.3.1](https://github.com/mitreid-connect/) handles the OIDC implementation.\n- [Shibboleth Identity Provider v3.3.2](https://wiki.shibboleth.net/confluence/display/IDP30/Home)\n\n## Design\n\nThe OIDC support is provided via the [MITREid Connect](https://github.com/mitreid-connect/) project. \nIt is itself based on Spring Security OAuth which itself in turn is based on Spring Security. So, \nthe design principal of this extension is to mostly adapt the above frameworks to what the Shibboleth \nIdP framework provides in terms of authentication and attribute resolution. Also note that that MITREid \nConnect is entirely Spring annotations-based when it comes to wiring up the components. Spring Security \nOAuth also uses various annotations to respond to endpoint requests. Such changes also need to be accounted \nfor in the IdP as it does not presently use a native model for annotation-based configuration of components. \n\n### Endpoints\n\nThe following endpoints are exposed by this extension:\n\n- `/idp/profile/oidc/token`\n- `/idp/profile/oidc/authorize`\n- `/idp/profile/oidc/jwk`\n- `/idp/profile/oidc/userinfo`\n- `/idp/.well-known`\n\nEach of these endpoints is protected via Spring Security, and configured in `oidc-protocol-endpoints.xml`. \nSpring Security OAuth itself presents various components that respond to framework endpoints and handles \nthe OAuth functionality. In this extension, these endpoints are merely registered to note the new URL endpoint within the IdP framework. \n\n### Storage\n\nMITREid Connect ships with a JPA implementation already that is responsible for managing the persistence \nof various tokens and the configuration of available/supported scopes, clients, etc. This extension \nleverages that functionality and configures a by-default inmemory database instance inside `oidc-protocol-storage.xml`. \nThe database choice and driver are controllable via IdP settings inside `oidc.properties`. \n\n```properties\noidc.db.schema.type=hsql\noidc.db.driver=org.hsqldb.jdbcDriver\noidc.db.url=jdbc:hsqldb:mem:oic;sql.syntax_mys=true\noidc.db.uid=sa\noidc.db.psw=\n```\n\n#### Schema \n\nNote that the default schema provided by this extension assumes a HSQLDB database. If you wish to use a different database, you will need to provide an different schema. Additional schemas are provieded in the `conf` directory for various databases. The following databases are supported:\n \n 1. HSQL\n 2. Postgres\n 3. MySQL\n 4. Oracle\n\n#### System Scopes\n\nSystems scopes are directly provided in the IdP configuration inside the `oidc-protocol-scopes.xml`. An adopter \nmay choose to ignore/remove scopes that are deemed unsupported. \n\n#### Clients\n\nRegistration of clients is now directly provided in the IdP configuration inside the `oidc-protocol.xml`. \n\n### Issuer\n\nThe OIDC issuer is controlled via the `oidc.properties` file:\n\n```properties\noidc.issuer=\n```\n\n### System\n\nThere are various other authentication manager/provider components registered in `oidc-protocol-system.xml` \nthat handle backchannel authentication requests for tokens and userinfo data. These are primarily based on \nSpring Security and MITREid Connect extensions of Spring Security. Additionally, auto-registration of MITREid Connect \nannotation-aware components  as well as all other components registered in this extension is handled here. \n\n### Encryption/Signing\n\nThis extension ships with a default encryption/signing components defined in the `oidc-protocol-system.xml`. \nA default JWKS is also provided which can be controlled via `oidc.properties` at:\n\n```properties\noidc.jwtset.keystore=%{idp.home}/credentials/keystore.jwks\n```\n\nThis file is presently not reloaded on changes, and its associated context is also not yet reloadable. Key \nrotations for the default keystore must happen manually, and require a restart for the time being. \n\nNote that every client registered in the IdP is also able to specify an endpoint for its JWKS. \n\n### Clients\n\nClient definitions are managed in the database by default. They may also be defined in `oidc-protocol.xml` and upon startup, they will be imported into the running database of choice where definitions will either be saved or updated.\n\n```xml\n\u003cutil:set id=\"oidcClients\"\u003e\n    \u003cbean class=\"org.mitre.oauth2.model.ClientDetailsEntity\"\n            p:id=\"1000\"\n            p:clientId=\"client\"\n            p:clientSecret=\"secret\"\n            p:clientName=\"Sample Client\"\u003e\n\n        \u003cproperty name=\"scope\"\u003e\n            \u003cbean class=\"org.springframework.util.StringUtils\" factory-method=\"commaDelimitedListToSet\"\u003e\n                \u003cconstructor-arg type=\"java.lang.String\" value=\"openid,profile,email,address,phone,offline_access\"/\u003e\n            \u003c/bean\u003e\n        \u003c/property\u003e\n        \u003cproperty name=\"grantTypes\"\u003e\n            \u003cbean class=\"org.springframework.util.StringUtils\" factory-method=\"commaDelimitedListToSet\"\u003e\n                \u003cconstructor-arg type=\"java.lang.String\" value=\"authorization_code,implicit,refresh_token\"/\u003e\n            \u003c/bean\u003e\n        \u003c/property\u003e\n        \u003cproperty name=\"redirectUris\"\u003e\n            \u003cset\u003e\n                \u003cvalue\u003ehttp://localhost:8080/simple-web-app/openid_connect_login\u003c/value\u003e\n            \u003c/set\u003e\n        \u003c/property\u003e\n    \u003c/bean\u003e\n\u003c/util:set\u003e\n```\n\n### Claims\n\nClaims can be configured as normal attribute definitions in the IdP. All standard claims that are present in the specification \nare supported. Here is an example of a claim:\n\n```xml\n\u003cAttributeDefinition xsi:type=\"Simple\" id=\"family_name\" sourceAttributeID=\"family_name\"\u003e\n    \u003cDependency ref=\"staticAttributes\" /\u003e\n    \u003cDisplayName\u003eFamily Name\u003c/DisplayName\u003e\n\u003c/AttributeDefinition\u003e\n```\n\nNote that attribute encoders are not needed since the JSON transformation is handled directly via the underlying \nframeworks. Also, claims can be filtered in turn by the IdP itself via the normal attribute filtering policy. Here is an example:\n\n```xml\n\u003cAttributeFilterPolicy id=\"default\"\u003e\n    \u003cPolicyRequirementRule xsi:type=\"Requester\" value=\"client\" /\u003e\n\n    \u003cAttributeRule attributeID=\"family_name\"\u003e\n        \u003cPermitValueRule xsi:type=\"ANY\" /\u003e\n    \u003c/AttributeRule\u003e\n\u003c/AttributeFilterPolicy\u003e\n```\n\nThe requester (i.e. EntityID) is always the `clientId` of the client registered in the IdP.\n\nNote that each client is able to specify which scopes it supports. This allows a second level of granularity where an \nadopter may choose to support only specific claims within a system scope. \n\n### Flows\n\n#### Authorization Code Flow\n\nThis extension registered an authentication flow for OIDC inside `oidc/login/login-flow.xml` whose beans are \nconfigured inside `oidc/login/login-beans.xml`. A typical walkthrough of the authentication flow is as such:\n\n- The client makes a request to `/idp/.well-known` to discover endpoints for OIDC conversation.\n- The IdP's `/idp/.well-known` endpoint presents a JSON envelope that contains everything the client needs to know for dynamic discovery.\n- The client makes a request to `/idp/profile/oidc/authorize` endpoint which is first handled by Spring Security OAuth. \n- Since the request requires an existing authentication to succeed, Spring Security OAuth throws a `InsufficientAuthenticationException`.\n- The IdP is configured to ignore the this exception so that downstream Spring Security components/filters can process it later. This is done via `mvc-beans.xml`. \n- `ExceptionTranslationFilter` of Spring Security kicks in and attempts to handle the request. The request is then routed to Spring Security for authentication.\n- The Idp has configured Spring Security for form-based authentication, which allows the request to be routed to a `login` endpoint for authentication.\n- The `login` endpoints invokes Spring Webflow to recall the OIDC login flow to start the flow.\n- The `login` flow eventually reaches the authentication state allowing for end-user login.\n- Once the authentication is successful, the result is then `POST`ed back to Spring Security to resume the `/idp/profile/oidc/authorize` endpoint functionality.\n- The `/idp/profile/oidc/authorize` will proceed to issue a `code` for the given request does a `POST` back to the client.\n- The client asks the `/idp/profile/oidc/token` endpoint for an access token, via the `code` received.\n- Spring Security OAuth, having recognized an existing authentication session issues an access token back along with an `idToken` in a JWT format. \n- The client validates the access token and the idToken, optionally invoking the `/idp/profile/oidc/jwk` endpoint to verify the `idToken`.\n- The client will use the access token to issue a request to `/idp/profile/oidc/userinfo` to grab claims. \n\nThere are many many other permutations of this flow, and many additional extension parameters that could be passed. \nTo learn about all that is possible in this flow, Study [the basics of the specification](http://openid.net/specs/openid-connect-basic-1_0.html).\n\n#### Hybrid Flow\n\nThe hybrid flow is virtually identical to the authorication code flow, except that upon authorization \nrequests the `response_type` parameter must be set to `id_token token`. \n\n#### Authentication Context/Method Ref\n\nThis extension supports the `acr/amr` claims. If the client requests a specific `acr_value` in the \noriginal request, the IdP attempts to calculate whether that value is indeed supported by any of the authentication \nflows. If none is deemed viable, the authentication context weight map of the IdP is consulted to figure out the appropriate `acr`. \nThe result is passed onto the IdP for authentication. \n\nSince MITREid Connect at this point does not natively support `acr/amr` claims, an implementation of a \nclaim service is provided by this extension to handle `acr/amr` claims for the client. \n\n#### Max-Age, AuthN Time\n\nThis extension supports the `max_age` and `auth_time` claims. If `max_age` is provided in the original \nrequest, the IdP attempts to calculate the authentication creation instant and may simulate a `forcedAuthN` so the end-user is actively reauthenticated. \n\nSince MITREid Connect's support for these claims is strictly tied to an authentication that is very much \nhandled by Spring Security ( as a requirement for Spring Security OAuth), a custom service is provided by \nthis extension to handle the production of `max_age` and `auth_time`. \n\n\n## Default IdP Configuration\n\nFollow the below steps if you wish to enable this extension inside a vanilla IdP v3 deployment. Note \nthat synchronization of changes, as we make progress here, is entirely manual at this point.\n\n### Build\n\n```bash\ngit clone git@github.com:uchicago/shibboleth-oidc.git\n```\n\nOr download [a zip distribution](https://github.com/uchicago/shibboleth-oidc/archive/master.zip).\n\nBuild the codebase via:\n\n```bash\n./mvn[w] clean package -P new\n```\n\n### Cross Examine Changes\n\nUnzip the `idp-webapp-overlay/target/idp.war` artifact into an `idp-temp`. \nThis will be used as a reference to copy configuration into your IdP deployment.\n\n- Cross examine the `idp-temp/WEB-INF/web.xml` with your IdP and apply all differences. \n- Cross examine the `idp-temp/idp/views/login.vm` and `idp-temp/idp/views/intercept/attribute-release.vm` with your IdP and apply all differences. \n- Cross examine the `idp-temp/idp/system/conf/global-system.xml` with your IdP and apply all differences. \n- Cross examine the `idp-temp/idp/system/conf/webflow-config.xml` with your IdP and apply all differences. \n- Cross examine the `idp-temp/idp/conf/mvc-beans.xml` with your IdP and apply all differences. \n- Cross examine the `idp-temp/idp/conf/idp.properties` with your IdP and apply all differences. \n- Cross examine the `idp-temp/idp/conf/attribute-resolver.xml` with your IdP and apply all differences. \n- Cross examine the `idp-temp/idp/conf/attribute-filter.xml` with your IdP and apply all differences. \n- Cross examine the `idp-temp/idp/conf/relying-party.xml` with your IdP and apply all differences. \n\n### Copy Configuration\n\n- Copy `idp-temp/idp/conf/oidc.properties`, `idp-temp/idp/conf/oidc-protocol.xml` into `$IDP_HOME/conf`\n- Copy the directory `idp-temp/idp/conf/schema` to `$IDP_HOME/conf/`\n- Copy `idp-temp/idp/credentials/keystore.jwks` into `$IDP_HOME/credentials`\n- Copy `idp-temp/idp/system/conf/oidc-protocol-*.xml` into `$IDP_HOME/system/conf`\n- Copy `idp-temp/idp/system/flows/oidc` into `$IDP_HOME/system/flows`\n- Copy `idp-temp/idp/system/views/oidc` into `$IDP_HOME/system/views`\n\n### Copy JARs\n\nCross examine the `idp-temp/WEB-INF/lib` directory with your IdP and copy all JARs that are not present. \n\n### Logging\n\nThe following packages may be used for log configuration:\n\n```xml\n\u003clogger name=\"org.mitre\" level=\"WARN\" /\u003e\n\u003clogger name=\"org.hibernate\" level=\"WARN\" /\u003e\n\n\u003clogger name=\"org.springframework.web\" level=\"WARN\" /\u003e\n\u003clogger name=\"org.springframework.webflow\" level=\"WARN\" /\u003e\n\u003clogger name=\"org.springframework.security\" level=\"WARN\" /\u003e\n\u003clogger name=\"org.springframework.security.oauth2\" level=\"WARN\" /\u003e\n\u003clogger name=\"net.shibboleth.idp.oidc\" level=\"WARN\" /\u003e\n```\n\n## Overlay IdP Configuration\n\nThe project itself follows an overlay-module where the IdP is configured to embed all of its configuration \ninside the final war artifact. In doing so, the following changes are then overlaid into the IdP context and \nneed to be accounted for during IdP upgrades. \n\n* `login.vm` and `attribute-release.vm` are overlaid to account for CSRF changes\n* `password-authn-config.xml` is overlaid to indicate JAAS is used for authN. \n* `global-system.xml` registers the `oidc-protocol-system` file\n* `webflow-config.xml` is overlaid to add the OIDC flow configuration.\n* `mvc-beans.xml` is used in the overlay `conf` directory to override the default beans and config.\n - This is used to define a new view resolver based on Spring bean names and remaps the excluded exceptions from the view resolver. \n* A custom JAR is dropped into the overlay's `WEB-INF/lib` that mocks authentication. This is configured via the `jaas.config` file.\n* `oidc.properties` controls the OIDC module configuration. This is appended to the list of property files loaded by \nthe IdP via `idp.properties`. \n* `web.xml` is modified to register the `.well-known` endpoint and also registers the spring security filters.\n\n### Build [![Build Status](https://travis-ci.org/uchicago/shibboleth-oidc.svg?branch=master)](https://travis-ci.org/uchicago/shibboleth-oidc)\nIn order to run the overlay build, examine the `/conf/idp.properties` inside the `idp-webapp-overlay` module,\nand adjust the values of hostname, entityId, passwords, etc. Then from the command prompt, execute:\n\n#### Initial installs\n\n```bash\n./mvn[w] clean install -P new\n```\n\nThis will wipe out any previous files inside `credentials` and `metadata` directories and start anew.\n\n#### Subsequent installs\n\n```bash\n./mvn[w] clean install\n```\n\n### Run IdP\n\n#### Prepare HTTPS\n\nYou will also need to set up a keystore under `/etc/jetty` and name it `thekeystore`. The keystore password and the \nkey password should both be `changeit`.\n \nA sample keystore is provided under the `idp-webapp-overlay/etc/jetty` directory that is empty, and can be used to set up the environment. \n\n#### Run Jetty\n\nFrom the root directory, run the following command:\n\n```bash\n./mvn[w] clean package verify -Dhost=jetty\n```\n\nThis will spin up an embedded Jetty server to load the IdP context. Remote debugging is available under port 5000 from your IDE.\n\nIf you want a somewhat faster build, run:\n\n```bash\n./mvn[w] clean package verify -Dhost=jetty --projects idp-oidc-impl,idp-webapp-overlay\n```\n\nScripted as:\n\n```bash\n./runidp.[sh|cmd]\n```\n\n### Run Client Application\n\n```bash\n./runclient.[sh|cmd]\n```\n\nThe client is automatically and by default pre=registered with IdP under `https://mmoayyed.unicon.net:9443/simple-web-app`.\nIt runs inside a Jetty instance that is configured to use port `9443` and the same keystore the IdP uses for simplicity. \n\n## Dockerized IdP Configuration\n\nThe Shibboleth IdP along with a sample PHP application protected by the Shibboleth SP and a sample OpenID Connect enabled application are all put together inside docker containers, controlled mostly via the `docker-compose.yml` file.\n\nThe Shibboleth IdP that runs inside the docker container is itself an overlay of the `idp-webapp-overlay` project that only overrides what is needed for the docker build to run successfully.\n\n### Build\n\n```bash\ngit clone git@github.com:uchicago/shibboleth-oidc.git\n```\n\nBuild the codebase via:\n\n```bash\n./mvn[w] clean package -P new\n```\n\n### Configure\n\n- Copy and overwrite the generated `idp-metadata.xml` from the `idp-webapp-overlay` project over to then `idp-webapp-overlay-docker` project.\n- Adjust the newly copied `idp-metadata.xml` file, changing entityId and endpoint references to `idptestbed`.\n- Exchange the newly adjusted `idp-metadata.xml` file with the `sp`.\n- Add `127.0.0.1 idptestbed` to your hosts file.\n\n### Run\n\nThe run the container:\n\n```bash\n./rundocker.sh\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuchicago%2Fshibboleth-oidc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuchicago%2Fshibboleth-oidc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuchicago%2Fshibboleth-oidc/lists"}