├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── dependencies.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── openid-connect-server-spring-boot-config ├── README.md ├── build.gradle ├── gradle.properties └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── mitre │ │ │ └── springboot │ │ │ └── config │ │ │ ├── ApiResourceServerConfig.java │ │ │ ├── CommonResourceServerConfig.java │ │ │ ├── CommonWebSecurityConfig.java │ │ │ ├── CryptoConfig.java │ │ │ ├── DisableProtectedResourceRegistrationResourceServerConfig.java │ │ │ ├── EclipseLinkJpaConfig.java │ │ │ ├── JdbcDataSourceAuthenticationConfig.java │ │ │ ├── OpenIDConnectAuthorizationServerConfig.java │ │ │ ├── OpenIDConnectServerConfig.java │ │ │ ├── ProtectedResourceRegistrationResourceServerConfig.java │ │ │ ├── ScheduledTaskConfig.java │ │ │ ├── annotation │ │ │ └── EnableOpenIDConnectServer.java │ │ │ ├── oauth2 │ │ │ ├── AuthorizationWebSecurityConfig.java │ │ │ └── TokenWebSecurityConfig.java │ │ │ └── openid │ │ │ └── connect │ │ │ ├── DynamicClientRegistrationResourceServerConfig.java │ │ │ ├── JwkWebSecurityConfig.java │ │ │ ├── UserInfoResourceServerConfig.java │ │ │ └── WellKnownWebSecurityConfig.java │ └── resources │ │ ├── application.yml │ │ ├── db │ │ ├── oracle │ │ │ └── entity_mappings_oracle.xml │ │ └── tables │ │ │ ├── hsql_database_tables.sql │ │ │ ├── mysql_database_tables.sql │ │ │ ├── oracle_database_tables.sql │ │ │ ├── psql_database_tables.sql │ │ │ └── security-schema.sql │ │ └── keystore.jwks │ └── test │ ├── java │ └── org │ │ └── mitre │ │ └── boot │ │ └── security │ │ ├── TestBootApplication.java │ │ └── TestBootApplicationTests.java │ └── resources │ ├── application.yml │ └── keystore.jwks ├── openid-connect-server-spring-boot-test ├── README.md ├── build.gradle ├── gradle.properties └── src │ └── test │ ├── java │ └── org │ │ └── mitre │ │ ├── boot │ │ └── security │ │ │ ├── oidc │ │ │ └── JwtAuthorizeEndpointFlowTests.java │ │ │ └── ui │ │ │ └── LoginEndpointTests.java │ │ └── springboot │ │ ├── DisabledEndpointsTests.java │ │ ├── EndpointTestsBase.java │ │ ├── TestBootApplication.java │ │ ├── discovery │ │ └── web │ │ │ └── DiscoveryEndpointAuthorizationTests.java │ │ ├── oauth2 │ │ └── web │ │ │ ├── BCryptTokenEndpointAuthorizationTests.java │ │ │ ├── IntrospectEndpointAuthorizationTests.java │ │ │ ├── OAuthAuthorizationTestsBase.java │ │ │ ├── OAuthConfirmationControllerAuthorizationTests.java │ │ │ ├── Pbkdf2TokenEndpointAuthorizationTests.java │ │ │ ├── RevocationEndpointAuthorizationTests.java │ │ │ ├── SCryptTokenEndpointAuthorizationTests.java │ │ │ ├── ScopeApiAuthorizationTests.java │ │ │ ├── StandardTokenEndpointAuthorizationTests.java │ │ │ ├── TokenApiAuthorizationTests.java │ │ │ └── TokenEndpointAuthorizationTests.java │ │ └── openid │ │ └── connect │ │ └── web │ │ ├── ApiAuthorizationTestsBase.java │ │ ├── ApprovedSiteApiAuthorizationTests.java │ │ ├── BlacklistApiAuthorizationTests.java │ │ ├── ClientApiAuthorizationTests.java │ │ ├── DataApiAuthorizationTests.java │ │ ├── DynamicClientRegistrationEndpointAuthorizationTests.java │ │ ├── StatsApiAuthorizationTests.java │ │ ├── UserInfoEndpointAuthorizationTests.java │ │ └── WhitelistApiAuthorizationTests.java │ └── resources │ ├── application-bcrypt.yml │ ├── application-endpoints-disabled.yml │ ├── application-pbkdf2.yml │ ├── application-scrypt.yml │ ├── application-standard.yml │ ├── application.yml │ ├── db │ └── test │ │ └── data │ │ ├── clients.sql │ │ ├── scopes.sql │ │ └── users.sql │ └── keystore.jwks ├── openid-connect-server-spring-boot-ui-thymeleaf ├── README.md ├── build.gradle ├── gradle.properties └── src │ └── main │ ├── java │ └── org │ │ └── mitre │ │ └── springboot │ │ └── config │ │ └── ui │ │ ├── StaticResourcesWebSecurityConfig.java │ │ ├── UserLoginConfig.java │ │ └── WebMvcConfig.java │ └── resources │ ├── static │ └── resources │ │ ├── bootstrap2 │ │ ├── css │ │ │ ├── bootstrap-responsive.css │ │ │ ├── bootstrap-responsive.min.css │ │ │ ├── bootstrap.css │ │ │ └── bootstrap.min.css │ │ ├── img │ │ │ ├── glyphicons-halflings-white.png │ │ │ └── glyphicons-halflings.png │ │ └── js │ │ │ ├── bootstrap.js │ │ │ └── bootstrap.min.js │ │ ├── css │ │ ├── bootstrap-sheet.css │ │ ├── mitreid-connect-local.css │ │ ├── mitreid-connect-responsive-local.css │ │ ├── mitreid-connect-responsive.css │ │ └── mitreid-connect.css │ │ ├── images │ │ ├── heart_mode.png │ │ ├── heart_mode@2x.png │ │ ├── logo_placeholder.gif │ │ ├── mitreid-connect.ico │ │ ├── openid_connect_large.png │ │ ├── openid_connect_large@2x.png │ │ ├── openid_connect_small.png │ │ └── openid_connect_small@2x.png │ │ ├── js │ │ ├── admin.js │ │ ├── blacklist.js │ │ ├── client.js │ │ ├── dynreg.js │ │ ├── grant.js │ │ ├── lib │ │ │ ├── backbone.js │ │ │ ├── backbone.validations.js │ │ │ ├── bootpag.js │ │ │ ├── bootstrap-sheet.js │ │ │ ├── bootstrapx-clickover.js │ │ │ ├── html5.js │ │ │ ├── i18next.js │ │ │ ├── jquery.js │ │ │ ├── moment-with-locales.js │ │ │ ├── purl.js │ │ │ ├── retina.js │ │ │ └── underscore.js │ │ ├── locale │ │ │ ├── en │ │ │ │ └── messages.json │ │ │ ├── sv │ │ │ │ └── messages.json │ │ │ ├── zh │ │ │ │ └── messages.json │ │ │ ├── zh_CN │ │ │ │ └── messages.json │ │ │ └── zh_TW │ │ │ │ └── messages.json │ │ ├── profile.js │ │ ├── rsreg.js │ │ ├── scope.js │ │ ├── token.js │ │ └── whitelist.js │ │ └── template │ │ ├── admin.html │ │ ├── blacklist.html │ │ ├── client.html │ │ ├── dynreg.html │ │ ├── grant.html │ │ ├── rsreg.html │ │ ├── scope.html │ │ ├── token.html │ │ └── whitelist.html │ └── templates │ ├── about.html │ ├── approve.html │ ├── approveDevice.html │ ├── contact.html │ ├── deviceApproved.html │ ├── error.html │ ├── error.jsp │ ├── fragments │ ├── aboutContent.html │ ├── actionmenu.html │ ├── contactContent.html │ ├── copyright.html │ ├── footer.html │ ├── header.html │ ├── landingPageAbout.html │ ├── landingPageContact.html │ ├── landingPageStats.html │ ├── landingPageWelcome.html │ ├── sidebar.html │ ├── statsContent.html │ └── topbar.html │ ├── home.html │ ├── login.html │ ├── manage.html │ ├── requestUserCode.html │ └── stats.html ├── publish.sh ├── samples ├── default │ ├── README.md │ ├── build.gradle │ ├── dependencies.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── org │ │ │ └── mitre │ │ │ └── springboot │ │ │ └── samples │ │ │ └── DefaultApplication.java │ │ └── resources │ │ ├── application.yml │ │ ├── db │ │ ├── clients.sql │ │ ├── scopes.sql │ │ └── users.sql │ │ └── keystore.jwks └── simple-ui │ ├── README.md │ ├── build.gradle │ ├── dependencies.gradle │ ├── gradle.properties │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ └── main │ ├── java │ └── org │ │ └── mitre │ │ └── springboot │ │ └── samples │ │ └── SimpleUIApplication.java │ └── resources │ ├── application.yml │ ├── db │ ├── clients.sql │ ├── scopes.sql │ └── users.sql │ ├── keystore.jwks │ └── templates │ ├── sampleclient.html │ └── session.html └── settings.gradle /.gitattributes: -------------------------------------------------------------------------------- 1 | /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/js/lib/* linguist-vendored 2 | /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/bootstrap2/* linguist-vendored -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/java,eclipse,intellij,gradle 3 | 4 | ### Eclipse ### 5 | 6 | .metadata 7 | bin/ 8 | tmp/ 9 | *.tmp 10 | *.bak 11 | *.swp 12 | *~.nib 13 | local.properties 14 | .settings/ 15 | .loadpath 16 | .recommenders 17 | 18 | .README.md.html 19 | 20 | # Eclipse Core 21 | .project 22 | 23 | # External tool builders 24 | .externalToolBuilders/ 25 | 26 | # Locally stored "Eclipse launch configurations" 27 | *.launch 28 | 29 | # PyDev specific (Python IDE for Eclipse) 30 | *.pydevproject 31 | 32 | # CDT-specific (C/C++ Development Tooling) 33 | .cproject 34 | 35 | # JDT-specific (Eclipse Java Development Tools) 36 | .classpath 37 | 38 | # Java annotation processor (APT) 39 | .factorypath 40 | 41 | # PDT-specific (PHP Development Tools) 42 | .buildpath 43 | 44 | # sbteclipse plugin 45 | .target 46 | 47 | # Tern plugin 48 | .tern-project 49 | 50 | # TeXlipse plugin 51 | .texlipse 52 | 53 | # STS (Spring Tool Suite) 54 | .springBeans 55 | 56 | # Code Recommenders 57 | .recommenders/ 58 | 59 | 60 | ### Intellij ### 61 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 62 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 63 | .idea/ 64 | 65 | # Gradle: 66 | build/ 67 | 68 | ## File-based project format: 69 | *.iws 70 | 71 | ## Plugin-specific files: 72 | 73 | # IntelliJ 74 | /out/ 75 | 76 | # mpeltonen/sbt-idea plugin 77 | .idea_modules/ 78 | 79 | # JIRA plugin 80 | atlassian-ide-plugin.xml 81 | 82 | # Crashlytics plugin (for Android Studio and IntelliJ) 83 | com_crashlytics_export_strings.xml 84 | crashlytics.properties 85 | crashlytics-build.properties 86 | fabric.properties 87 | 88 | ### Intellij Patch ### 89 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 90 | 91 | # *.iml 92 | # modules.xml 93 | # .idea/misc.xml 94 | # *.ipr 95 | 96 | 97 | ### Java ### 98 | *.class 99 | 100 | # Mobile Tools for Java (J2ME) 101 | .mtj.tmp/ 102 | 103 | # Package Files # 104 | *.jar 105 | *.war 106 | *.ear 107 | 108 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 109 | hs_err_pid* 110 | 111 | 112 | ### Gradle ### 113 | .gradle 114 | /build/ 115 | 116 | # Ignore Gradle GUI config 117 | gradle-app.setting 118 | 119 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 120 | !gradle-wrapper.jar 121 | 122 | # Cache of project 123 | .gradletasknamecache 124 | 125 | # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 126 | # gradle/wrapper/gradle-wrapper.properties 127 | /.idea/ 128 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spring Boot MITREid Connect 2 | --- 3 | 4 | A Spring Boot Configuration for the [MITREid OpenID Connect Server](https://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server). 5 | 6 | This project separates the OpenID Connect Server [configuration](openid-connect-server-spring-boot-config) from the [UI](openid-connect-server-spring-boot-ui-thymeleaf), and includes [sample applications](samples). 7 | 8 | The [default](samples/default) sample application attempts to be as close as possible to the [maven overlay web application](https://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server/tree/master/openid-connect-server-webapp) from MITREid, while other samples give examples of how to customize the OpenID Connect server to fit your needs. 9 | 10 | Pull requests and feature improvements are welcome. 11 | 12 | Currently supports Spring Boot 1.5.21, MitreId Connect 1.3.3, and Spring Security 4.3.22 13 | 14 | ## Password Encoders 15 | 16 | The possibility of using a different password encoders for users and clients has been added through configuration. From now on you can configure MIDTREID Connect with some of the four types of encoders that come out-of-the-box in Spring. 17 | 18 | To configure a different encoder type (the default encoder NoOpPasswordEncoder), the following configuration must be added to the yml file: 19 | 20 | ```yaml 21 | openid: 22 | connect: 23 | crypto: 24 | password-encoder: 25 | clients: 26 | bcrypt: 27 | enabled: true 28 | strength: -1 29 | users: 30 | bcrypt: 31 | enabled: true 32 | strength: -1 ` 33 | ``` 34 | 35 | openid.connect.crypto.password-encoder.clients defines the password encoder for clients and in openid.crypto.password-encoder.users for users. 36 | 37 | The configuration of the different types of encoders is shown below. 38 | 39 | ### BCrypt Password Encoder 40 | To configure a BCrypt password encoder you will need to add the bcrypt property with the following properties: 41 | 42 | * enabled: enables (true) or disables (false) the encoder 43 | * strength: the log rounds to use, between 4 and 31 44 | 45 | ```yaml 46 | openid: 47 | connect: 48 | crypto: 49 | password-encoder: 50 | clients: 51 | bcrypt: 52 | enabled: true 53 | strength: -1 54 | users: 55 | bcrypt: 56 | enabled: true 57 | strength: -1 58 | ``` 59 | 60 | ### SCrypt Password Encoder 61 | To configure a SCrypt password encoder you will need to add the scrypt property with the following properties: 62 | 63 | * enabled: enables (true) or disables (false) the encoder 64 | * cpu-cost: cpu cost of the algorithm (as defined in scrypt this is N). must be power of 2 greater than 1. Default is currently 16,348 or 2^14) 65 | * memory-cost: memory cost of the algorithm (as defined in scrypt this is r) Default is currently 8. 66 | * parallelization: the parallelization of the algorithm (as defined in scrypt this is p) Default is currently 1. Note that the implementation does not currently take advantage of parallelization. 67 | * key-length: key length for the algorithm (as defined in scrypt this is dkLen). The default is currently 32. 68 | * salt-length: salt length (as defined in scrypt this is the length of S). The default is currently 64. 69 | 70 | ```yaml 71 | openid: 72 | connect: 73 | crypto: 74 | password-encoder: 75 | clients: 76 | scrypt: 77 | enabled: true 78 | cpu-cost: 16384 79 | memory-cost: 8 80 | parallelization: 1 81 | key-length: 32 82 | salt-length: 64 83 | users: 84 | scrypt: 85 | enabled: true 86 | cpu-cost: 16384 87 | memory-cost: 8 88 | parallelization: 1 89 | key-length: 32 90 | salt-length: 64 91 | ``` 92 | 93 | ### Standard Password Encoder 94 | To configure a Standard password encoder you will need to add the standard property with the following properties: 95 | 96 | * enabled: enables (true) or disables (false) the encoder 97 | * secret: the secret key used in the encoding process (should not be shared). Default "" 98 | 99 | ```yaml 100 | openid: 101 | connect: 102 | crypto: 103 | password-encoder: 104 | clients: 105 | standard: 106 | enabled: true 107 | secret: a_secret_word 108 | users: 109 | standard: 110 | enabled: true 111 | secret: a_secret_word 112 | ``` 113 | ### Pbkdf2 Password Encoder 114 | To configure a Pbkdf2 password encoder you will need to add the pbkdf2 property with the following properties: 115 | 116 | * enabled: enables (true) or disables (false) the encoder 117 | * secret: the secret key used in the encoding process (should not be shared) 118 | 119 | ```yaml 120 | openid: 121 | connect: 122 | crypto: 123 | password-encoder: 124 | clients: 125 | pbkdf2: 126 | enabled: true 127 | secret: a_secret_word 128 | users: 129 | pbkdf2: 130 | enabled: true 131 | secret: a_secret_word 132 | ``` -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | apply from:"dependencies.gradle" 2 | 3 | subprojects { 4 | apply plugin: "eclipse" 5 | apply plugin: "idea" 6 | apply plugin: "java" 7 | apply plugin: "maven" 8 | apply plugin: "signing" 9 | 10 | buildscript { 11 | repositories { 12 | mavenCentral() 13 | jcenter() 14 | maven {url "http://repo.spring.io/plugins-snapshot"} 15 | maven {url "http://repo.spring.io/milestone"} 16 | maven {url "http://repo.spring.io/release"} 17 | } 18 | } 19 | 20 | ext { 21 | baseVersion = "0.1.6" 22 | isSnapshot = true 23 | snapshotSuffix = "-SNAPSHOT" 24 | projectVersion = baseVersion + (isSnapshot ? snapshotSuffix : "") 25 | } 26 | 27 | group = "net.simpledynamics" 28 | version = projectVersion 29 | 30 | sourceCompatibility = 1.8 31 | targetCompatibility = 1.8 32 | 33 | repositories { 34 | mavenCentral() 35 | } 36 | 37 | task javadocJar(type: Jar) { 38 | classifier = 'javadoc' 39 | from javadoc 40 | } 41 | 42 | task sourcesJar(type: Jar) { 43 | classifier = 'sources' 44 | from sourceSets.main.allSource 45 | } 46 | 47 | artifacts { 48 | archives javadocJar, sourcesJar 49 | } 50 | 51 | signing { 52 | required {!isSnapshot && gradle.taskGraph.hasTask("uploadArchives") } 53 | sign configurations.archives 54 | } 55 | 56 | project.ext.set("githubAutentiaUsername", project.hasProperty("githubAutentiaUsername") ? githubAutentiaUsername : System.getenv("GITHUB_AUTENTIA_USERNAME")) 57 | project.ext.set("githubAutentiaToken", project.hasProperty("githubAutentiaToken") ? githubAutentiaToken : System.getenv("GITHUB_AUTENTIA_TOKEN")) 58 | 59 | 60 | uploadArchives { 61 | repositories { 62 | mavenDeployer { 63 | beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } 64 | 65 | if(githubAutentiaUsername != null && githubAutentiaToken != null) { 66 | repository(url: "https://maven.pkg.github.com/autentia/openid-connect-server-spring-boot") { 67 | authentication(userName: githubAutentiaUsername, password: githubAutentiaToken) 68 | } 69 | } else { 70 | //for local maven deploy testing 71 | repository(url: mavenLocal().url) 72 | } 73 | 74 | pom.project { 75 | name project.name 76 | description project.description 77 | packaging 'jar' 78 | url 'https://github.com/autentia/openid-connect-server-spring-boot' 79 | 80 | scm { 81 | connection 'scm:git:https://github.com/autentia/openid-connect-server-spring-boot' 82 | developerConnection 'scm:git:https://github.com/autentia/openid-connect-server-spring-boot' 83 | url 'https://github.com/autentia/openid-connect-server-spring-boot' 84 | } 85 | 86 | licenses { 87 | license { 88 | name 'The Apache License, Version 2.0' 89 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 90 | } 91 | } 92 | 93 | organization { 94 | name 'Simple Dynamics' 95 | url 'http://www.simpledynamics.net/' 96 | } 97 | 98 | developers { 99 | developer { 100 | id 'barretttucker' 101 | name 'Barrett Tucker' 102 | email 'barrett@simpledynamics.net' 103 | } 104 | developer { 105 | id 'nategrover' 106 | name 'Nate Grover' 107 | email 'nate@simpledynamics.net' 108 | } 109 | } 110 | } 111 | } 112 | } 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /dependencies.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | springVersion = "4.3.22.RELEASE" 3 | springBootVersion = "1.5.21.RELEASE" 4 | springSecurityOauthVersion = "2.0.13.RELEASE" 5 | springSecurityTestVersion = "4.2.13.RELEASE" 6 | openIdConnectVersion = "1.3.3" 7 | h2DatabaseVersion = "1.4.192" 8 | jsonPathVersion = "2.0.0" 9 | httpClientVersion = "4.5.3" 10 | bouncyCastleVersion = "1.56" 11 | thymeleafSpringSecurityVersion = "2.1.3.RELEASE" 12 | eclipsePersistenceJpaVersion = "2.5.2" 13 | hikariCPVersion = "2.4.3" 14 | 15 | 16 | libs = [ 17 | springBootStarterWeb : "org.springframework.boot:spring-boot-starter-web:${springBootVersion}", 18 | springBootStarterSecurity : "org.springframework.boot:spring-boot-starter-security:${springBootVersion}", 19 | springSecurityOauth2 : "org.springframework.security.oauth:spring-security-oauth2:${springSecurityOauthVersion}", 20 | springBootStarterDataJPA : "org.springframework.boot:spring-boot-starter-data-jpa:${springBootVersion}", 21 | springSecurityTest : "org.springframework.security:spring-security-test:${springSecurityTestVersion}", 22 | h2Database : "com.h2database:h2:${h2DatabaseVersion}", 23 | jsonPath : "com.jayway.jsonpath:json-path:${jsonPathVersion}", 24 | httpClient : "org.apache.httpcomponents:httpclient:${httpClientVersion}", 25 | bouncyCastle : "org.bouncycastle:bcprov-jdk15on:${bouncyCastleVersion}", 26 | mitreOpenIdConnectServer : "org.mitre:openid-connect-server:${openIdConnectVersion}", 27 | springBootStarterThymeleaf : "org.springframework.boot:spring-boot-starter-thymeleaf:${springBootVersion}", 28 | thymeleafSpringSecurity : "org.thymeleaf.extras:thymeleaf-extras-springsecurity4:${thymeleafSpringSecurityVersion}", 29 | eclipsePersistenceJpa : "org.eclipse.persistence:org.eclipse.persistence.jpa:${eclipsePersistenceJpaVersion}", 30 | hikariCP : "com.zaxxer:HikariCP:${hikariCPVersion}", 31 | springBootStarterLogging : "org.springframework.boot:spring-boot-starter-logging:${springBootVersion}", 32 | springBootStarterTest : "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tntconcept/openid-connect-server-spring-boot/b2214d6c0bdd4e227dd9440f080fd8419e97d28b/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Jul 04 10:22:36 CEST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.5-bin.zip 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "java-library" 2 | 3 | dependencies { 4 | // Spring Boot Starters 5 | compile libs.springBootStarterWeb 6 | compile libs.springBootStarterSecurity 7 | compile libs.springSecurityOauth2 8 | compile(libs.springBootStarterDataJPA) { 9 | exclude group: 'org.hibernate', module: 'hibernate-entitymanager' 10 | } 11 | 12 | // OpenID Connect 13 | compile libs.mitreOpenIdConnectServer 14 | compile libs.bouncyCastle 15 | 16 | runtime libs.eclipsePersistenceJpa 17 | runtime libs.hikariCP 18 | runtime libs.springBootStarterLogging 19 | 20 | testImplementation libs.springBootStarterTest 21 | testImplementation libs.springSecurityTest 22 | testImplementation libs.jsonPath 23 | testImplementation libs.httpClient 24 | 25 | //Embedded test db 26 | // testRuntimeOnly libs.h2Database 27 | 28 | runtimeOnly libs.h2Database 29 | } 30 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/gradle.properties: -------------------------------------------------------------------------------- 1 | description = A spring boot autoconfiguration library that simplifies getting started with the OpenID Connect Server reference implementation at https://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/main/java/org/mitre/springboot/config/CommonResourceServerConfig.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.config; 2 | 3 | import org.mitre.oauth2.service.OAuth2TokenEntityService; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.core.annotation.Order; 8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 9 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; 10 | import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; 11 | 12 | @Configuration 13 | @Order(170) 14 | public class CommonResourceServerConfig extends ResourceServerConfigurerAdapter{ 15 | 16 | @Autowired 17 | private final OAuth2TokenEntityService oAuth2TokenEntityService; 18 | 19 | public CommonResourceServerConfig(final OAuth2TokenEntityService oAuth2TokenEntityService, 20 | final ResourceServerProperties resourceServerConfiguration){ 21 | this.oAuth2TokenEntityService = oAuth2TokenEntityService; 22 | 23 | //Change order of filter ResourceServer 24 | resourceServerConfiguration.setFilterOrder(170); 25 | } 26 | 27 | @Override 28 | public void configure(final ResourceServerSecurityConfigurer resources) throws Exception{ 29 | resources.stateless(false); 30 | resources.tokenServices(oAuth2TokenEntityService); 31 | } 32 | 33 | @Override 34 | public void configure(final HttpSecurity http) throws Exception{ 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/main/java/org/mitre/springboot/config/CommonWebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.config; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.core.annotation.Order; 7 | import org.springframework.security.authentication.AuthenticationManager; 8 | import org.springframework.security.config.annotation.web.builders.WebSecurity; 9 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 10 | import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler; 11 | 12 | @Order(700) 13 | @Configuration 14 | public class CommonWebSecurityConfig extends WebSecurityConfigurerAdapter { 15 | 16 | @Autowired 17 | private OAuth2WebSecurityExpressionHandler oAuth2WebSecurityExpressionHandler; 18 | 19 | @Override 20 | public void configure(WebSecurity web) throws Exception { 21 | web.expressionHandler(oAuth2WebSecurityExpressionHandler); 22 | } 23 | 24 | @Bean(name = "org.springframework.security.authenticationManager") 25 | public AuthenticationManager authenticationManagerBean() 26 | throws Exception { 27 | return super.authenticationManagerBean(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/main/java/org/mitre/springboot/config/DisableProtectedResourceRegistrationResourceServerConfig.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.config; 2 | 3 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.core.annotation.Order; 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 | import org.springframework.security.config.http.SessionCreationPolicy; 8 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; 9 | 10 | /** 11 | * 12 | * This configuration is necessary because the application doesn´t work if the protectedresourcesregistration endpoint is disabled. 13 | * 14 | */ 15 | @Configuration 16 | @ConditionalOnProperty(havingValue = "false", name = "openid.connect.endpoints.protectedresourceregistration.enabled", matchIfMissing = true) 17 | @Order(210) 18 | public class DisableProtectedResourceRegistrationResourceServerConfig extends ResourceServerConfigurerAdapter{ 19 | 20 | @Override 21 | public void configure(final HttpSecurity http) throws Exception{ 22 | // @formatter:off 23 | http 24 | .sessionManagement() 25 | .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) 26 | .and() 27 | .authorizeRequests() 28 | .anyRequest().authenticated(); 29 | // @formatter:on 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/main/java/org/mitre/springboot/config/EclipseLinkJpaConfig.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.config; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.Map; 5 | 6 | import javax.persistence.EntityManagerFactory; 7 | import javax.sql.DataSource; 8 | 9 | import org.springframework.beans.factory.ObjectProvider; 10 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 11 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 12 | import org.springframework.boot.autoconfigure.domain.EntityScan; 13 | import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 14 | import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration; 15 | import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; 16 | import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers; 17 | import org.springframework.boot.context.properties.ConfigurationProperties; 18 | import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; 19 | import org.springframework.context.annotation.Bean; 20 | import org.springframework.context.annotation.Configuration; 21 | import org.springframework.context.annotation.Primary; 22 | import org.springframework.orm.jpa.JpaTransactionManager; 23 | import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; 24 | import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter; 25 | import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter; 26 | import org.springframework.transaction.PlatformTransactionManager; 27 | import org.springframework.transaction.annotation.EnableTransactionManagement; 28 | import org.springframework.transaction.jta.JtaTransactionManager; 29 | 30 | @Configuration 31 | @EnableTransactionManagement 32 | @EntityScan(basePackages = {"org.mitre.oauth2.model", "org.mitre.openid.connect.model", "org.mitre.uma.model"}) 33 | @AutoConfigureAfter(DataSourceAutoConfiguration.class) 34 | public class EclipseLinkJpaConfig extends JpaBaseConfiguration{ 35 | 36 | public EclipseLinkJpaConfig(final DataSource dataSource, final JpaProperties properties, 37 | final ObjectProvider jtaTransactionManager, 38 | final ObjectProvider transactionManagerCustomizers){ 39 | super(dataSource, properties, jtaTransactionManager, transactionManagerCustomizers); 40 | } 41 | 42 | @Override 43 | protected AbstractJpaVendorAdapter createJpaVendorAdapter(){ 44 | return new EclipseLinkJpaVendorAdapter(); 45 | } 46 | 47 | /* 48 | * Explicitly defining this bean as MITREid code looks for a TransactionManager named "defaultTransactionManager" 49 | * */ 50 | @Bean(name = "defaultTransactionManager") 51 | @Override 52 | public PlatformTransactionManager transactionManager(){ 53 | return new JpaTransactionManager(); 54 | } 55 | 56 | /* 57 | * Explicitly defining this bean as MITRE code looks for a persistenceUnit named "defaultPersistenceUnit" 58 | * 59 | * */ 60 | @Bean 61 | @Primary 62 | @Override 63 | @ConditionalOnMissingBean({LocalContainerEntityManagerFactoryBean.class, EntityManagerFactory.class}) 64 | @ConfigurationProperties(prefix = "openid.connect.jpa") 65 | public LocalContainerEntityManagerFactoryBean entityManagerFactory( 66 | final EntityManagerFactoryBuilder factoryBuilder){ 67 | final LocalContainerEntityManagerFactoryBean factory = super.entityManagerFactory(factoryBuilder); 68 | factory.getJpaPropertyMap().put("eclipselink.weaving", "false"); 69 | factory.getJpaPropertyMap().put("eclipselink.cache.shared.default", "false"); 70 | factory.setPersistenceUnitName("defaultPersistenceUnit"); 71 | return factory; 72 | } 73 | 74 | @Override 75 | protected Map getVendorProperties(){ 76 | final Map vendorProperties = new LinkedHashMap(); 77 | return vendorProperties; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/main/java/org/mitre/springboot/config/JdbcDataSourceAuthenticationConfig.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.config; 2 | 3 | import javax.sql.DataSource; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.annotation.Qualifier; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.core.annotation.Order; 9 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 10 | import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication; 11 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 12 | import org.springframework.security.crypto.password.PasswordEncoder; 13 | 14 | /** 15 | * Sets source of User information as the spring security stock JDBC User Details 16 | * @author barretttucker 17 | * 18 | */ 19 | @Order(610) 20 | @Configuration 21 | @EnableGlobalAuthentication 22 | public class JdbcDataSourceAuthenticationConfig extends WebSecurityConfigurerAdapter{ 23 | 24 | @Autowired 25 | private DataSource dataSource; 26 | 27 | @Autowired 28 | @Qualifier("userPasswordEncoder") 29 | private PasswordEncoder userPasswordEncoder; 30 | 31 | @Autowired 32 | public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception{ 33 | auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(userPasswordEncoder); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/main/java/org/mitre/springboot/config/OpenIDConnectAuthorizationServerConfig.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.config; 2 | 3 | import java.util.Arrays; 4 | 5 | import org.mitre.oauth2.service.ClientDetailsEntityService; 6 | import org.mitre.oauth2.service.OAuth2TokenEntityService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.beans.factory.annotation.Qualifier; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.core.annotation.Order; 11 | import org.springframework.security.crypto.password.PasswordEncoder; 12 | import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; 13 | import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; 14 | import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; 15 | import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; 16 | import org.springframework.security.oauth2.provider.CompositeTokenGranter; 17 | import org.springframework.security.oauth2.provider.OAuth2RequestFactory; 18 | import org.springframework.security.oauth2.provider.OAuth2RequestValidator; 19 | import org.springframework.security.oauth2.provider.TokenGranter; 20 | import org.springframework.security.oauth2.provider.approval.UserApprovalHandler; 21 | import org.springframework.security.oauth2.provider.client.ClientCredentialsTokenGranter; 22 | import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices; 23 | import org.springframework.security.oauth2.provider.code.AuthorizationCodeTokenGranter; 24 | import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator; 25 | import org.springframework.security.oauth2.provider.implicit.ImplicitTokenGranter; 26 | import org.springframework.security.oauth2.provider.refresh.RefreshTokenGranter; 27 | /** 28 | * Wires in the MitreID OpenID Connect implementations into the Spring Security Oauth 2.0 stack, overrides OAuth2AuthorizationServerConfiguration 29 | * 30 | */ 31 | 32 | @Configuration 33 | @Order(500) 34 | public class OpenIDConnectAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { 35 | 36 | @Autowired 37 | private ClientDetailsEntityService clientDetailsService; 38 | 39 | @Autowired 40 | @Qualifier("defaultOAuth2ProviderTokenService") 41 | private OAuth2TokenEntityService tokenServices; 42 | 43 | @Autowired 44 | @Qualifier("tofuUserApprovalHandler") 45 | private UserApprovalHandler userApprovalHandler; 46 | 47 | @Autowired 48 | @Qualifier("connectOAuth2RequestFactory") 49 | private OAuth2RequestFactory requestFactory; 50 | 51 | @Autowired 52 | private AuthorizationCodeServices authorizationCodeServices; 53 | 54 | @Autowired 55 | @Qualifier("chainedTokenGranter") 56 | private TokenGranter chainedTokenGranter; 57 | 58 | @Autowired 59 | private WebResponseExceptionTranslator exceptionTranslator; 60 | 61 | @Autowired 62 | @Qualifier("jwtAssertionTokenGranter") 63 | private TokenGranter jwtAssertionTokenGranter; 64 | 65 | @Autowired 66 | private OAuth2RequestValidator oAuth2RequestValidator; 67 | 68 | @Autowired 69 | @Qualifier("clientPasswordEncoder") 70 | private PasswordEncoder clientPasswordEncoder; 71 | 72 | protected TokenGranter tokenGranter() { 73 | return new CompositeTokenGranter(Arrays.asList( 74 | new AuthorizationCodeTokenGranter(tokenServices, authorizationCodeServices, clientDetailsService, requestFactory), 75 | new ImplicitTokenGranter(tokenServices, clientDetailsService, requestFactory), 76 | new RefreshTokenGranter(tokenServices, clientDetailsService, requestFactory), 77 | new ClientCredentialsTokenGranter(tokenServices, clientDetailsService, requestFactory), 78 | chainedTokenGranter, 79 | jwtAssertionTokenGranter 80 | )); 81 | } 82 | 83 | //TODO Set this on AuthorizationEndpoint.setRedirectResolver() 84 | //redirect-resolver-ref="blacklistAwareRedirectResolver" 85 | 86 | @Override 87 | public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 88 | //TODO 89 | endpoints 90 | .requestValidator(oAuth2RequestValidator) 91 | .pathMapping("/oauth/token", "/token") 92 | .pathMapping("/oauth/authorize", "/authorize") 93 | .tokenServices(tokenServices) 94 | .userApprovalHandler(userApprovalHandler) 95 | .requestFactory(requestFactory) 96 | .exceptionTranslator(exceptionTranslator) 97 | .tokenGranter(tokenGranter()) 98 | .authorizationCodeServices(authorizationCodeServices) 99 | ; 100 | } 101 | 102 | @Override 103 | public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { 104 | oauthServer.passwordEncoder(clientPasswordEncoder); 105 | } 106 | 107 | @Override 108 | public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 109 | clients.withClientDetails(clientDetailsService); 110 | } 111 | 112 | 113 | } 114 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/main/java/org/mitre/springboot/config/ProtectedResourceRegistrationResourceServerConfig.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.config; 2 | 3 | import javax.servlet.Filter; 4 | 5 | import org.mitre.openid.connect.view.ClientInformationResponseView; 6 | import org.mitre.openid.connect.web.ProtectedResourceRegistrationEndpoint; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.beans.factory.annotation.Qualifier; 9 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 10 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | import org.springframework.core.annotation.Order; 14 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 15 | import org.springframework.security.config.http.SessionCreationPolicy; 16 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; 17 | import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint; 18 | import org.springframework.security.web.context.SecurityContextPersistenceFilter; 19 | 20 | @Configuration 21 | @ConditionalOnProperty(havingValue="true", name="openid.connect.endpoints.protectedresourceregistration.enabled", matchIfMissing=true) 22 | @Order(210) 23 | public class ProtectedResourceRegistrationResourceServerConfig extends ResourceServerConfigurerAdapter { 24 | String PATTERN = "/" + org.mitre.openid.connect.web.ProtectedResourceRegistrationEndpoint.URL + "/**"; 25 | 26 | @Autowired 27 | protected OAuth2AuthenticationEntryPoint authenticationEntryPoint; 28 | 29 | @Bean 30 | @ConditionalOnMissingBean(ProtectedResourceRegistrationEndpoint.class) 31 | protected ProtectedResourceRegistrationEndpoint ProtectedResourceRegistrationEndpoint() { 32 | return new ProtectedResourceRegistrationEndpoint(); 33 | } 34 | 35 | @Bean(name=ClientInformationResponseView.VIEWNAME) 36 | @ConditionalOnMissingBean(name=ClientInformationResponseView.VIEWNAME) 37 | protected ClientInformationResponseView clientInformationResponseView() { 38 | return new ClientInformationResponseView(); 39 | } 40 | 41 | @Override 42 | public void configure(HttpSecurity http) throws Exception { 43 | // @formatter:off 44 | http 45 | .requestMatchers() 46 | .antMatchers(PATTERN) 47 | .and() 48 | .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint) 49 | .and() 50 | .sessionManagement() 51 | .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) 52 | .and() 53 | .authorizeRequests() 54 | .antMatchers(PATTERN) 55 | .permitAll() 56 | ; 57 | // @formatter:on 58 | } 59 | 60 | } -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/main/java/org/mitre/springboot/config/ScheduledTaskConfig.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.config; 2 | 3 | import java.util.concurrent.Executor; 4 | import java.util.concurrent.Executors; 5 | 6 | import org.mitre.oauth2.service.impl.DefaultOAuth2AuthorizationCodeService; 7 | import org.mitre.oauth2.service.impl.DefaultOAuth2ProviderTokenService; 8 | import org.mitre.openid.connect.service.ApprovedSiteService; 9 | import org.mitre.springboot.config.ScheduledTaskConfig.SchedulingEnabledCondition; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.boot.autoconfigure.condition.ConditionOutcome; 12 | import org.springframework.boot.autoconfigure.condition.SpringBootCondition; 13 | import org.springframework.boot.bind.RelaxedPropertyResolver; 14 | import org.springframework.boot.context.properties.ConfigurationProperties; 15 | import org.springframework.context.annotation.*; 16 | import org.springframework.core.annotation.Order; 17 | import org.springframework.core.env.Environment; 18 | import org.springframework.core.type.AnnotatedTypeMetadata; 19 | import org.springframework.scheduling.annotation.EnableScheduling; 20 | import org.springframework.scheduling.annotation.Scheduled; 21 | import org.springframework.scheduling.annotation.SchedulingConfigurer; 22 | import org.springframework.scheduling.config.ScheduledTaskRegistrar; 23 | 24 | @Configuration 25 | @EnableScheduling 26 | @Conditional(SchedulingEnabledCondition.class) 27 | @ConfigurationProperties(prefix="openid.connect.scheduling") 28 | public class ScheduledTaskConfig implements SchedulingConfigurer { 29 | @Autowired 30 | private DefaultOAuth2ProviderTokenService defaultOAuth2ProviderTokenService; 31 | 32 | @Autowired 33 | private ApprovedSiteService approvedSiteService; 34 | 35 | protected Integer corePoolSize = 5; 36 | 37 | @Autowired 38 | private DefaultOAuth2AuthorizationCodeService defaultOAuth2AuthorizationCodeService; 39 | 40 | @Bean(destroyMethod="shutdown") 41 | public Executor taskScheduler() { 42 | return Executors.newScheduledThreadPool(corePoolSize); 43 | } 44 | 45 | @Scheduled(fixedDelayString = "${openid.connect.scheduling.tasks.clearExpiredTokens.fixedDelay:30000}", 46 | initialDelayString = "${openid.connect.scheduling.tasks.clearExpiredTokens.initialDelay:60000}") 47 | public void clearExpiredTokens() { 48 | defaultOAuth2ProviderTokenService.clearExpiredTokens(); 49 | } 50 | 51 | @Scheduled(fixedDelayString = "${openid.connect.scheduling.tasks.clearExpiredSites.fixedDelay:30000}", 52 | initialDelayString = "${openid.connect.scheduling.tasks.clearExpiredSites.initialDelay:60000}") 53 | public void clearExpiredSites() { 54 | approvedSiteService.clearExpiredSites(); 55 | } 56 | 57 | @Scheduled(fixedDelayString = "${openid.connect.scheduling.tasks.clearExpiredAuthorizationCodes.fixedDelay:30000}", 58 | initialDelayString = "${openid.connect.scheduling.tasks.clearExpiredAuthorizationCodes.initialDelay:60000}") 59 | public void clearExpiredAuthorizationCodes() { 60 | defaultOAuth2AuthorizationCodeService.clearExpiredAuthorizationCodes(); 61 | } 62 | 63 | @Override 64 | public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { 65 | taskRegistrar.setScheduler(taskScheduler()); 66 | } 67 | 68 | protected static class SchedulingEnabledCondition extends SpringBootCondition implements ConfigurationCondition { 69 | 70 | @Override 71 | public ConfigurationPhase getConfigurationPhase() { 72 | return ConfigurationPhase.REGISTER_BEAN; 73 | } 74 | @Override 75 | public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { 76 | Environment environment = context.getEnvironment(); 77 | RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(environment, 78 | "openid.connect.scheduling."); 79 | String enabled = resolver.getProperty("enabled"); 80 | if(enabled != null && Boolean.valueOf(enabled).equals(false)) { 81 | return ConditionOutcome.noMatch("Task Scheduling is disabled"); 82 | } 83 | return ConditionOutcome.match("Task Scheduling is enabled"); 84 | } 85 | 86 | } 87 | 88 | } -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/main/java/org/mitre/springboot/config/annotation/EnableOpenIDConnectServer.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.config.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | import org.mitre.springboot.config.OpenIDConnectServerConfig; 10 | import org.springframework.context.annotation.Import; 11 | 12 | /** 13 | * Enables OpenID Connect Server configuration facility. 14 | * To be used together with {@link org.springframework.context.annotation.Configuration Configuration} 15 | * or {@link org.springframework.boot.autoconfigure.SpringBootApplication SpringBootApplication} classes. 16 | * 17 | */ 18 | @Target(ElementType.TYPE) 19 | @Retention(RetentionPolicy.RUNTIME) 20 | @Documented 21 | @Import(OpenIDConnectServerConfig.class) 22 | public @interface EnableOpenIDConnectServer { 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/main/java/org/mitre/springboot/config/oauth2/AuthorizationWebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.config.oauth2; 2 | 3 | import javax.servlet.Filter; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.annotation.Qualifier; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.core.annotation.Order; 9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 10 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 11 | import org.springframework.security.web.context.SecurityContextPersistenceFilter; 12 | 13 | @Order(710) 14 | @Configuration 15 | public class AuthorizationWebSecurityConfig extends WebSecurityConfigurerAdapter { 16 | 17 | @Autowired 18 | @Qualifier("authRequestFilter") 19 | private Filter authRequestFilter ; 20 | 21 | @Override 22 | protected void configure(HttpSecurity http) throws Exception { 23 | // @formatter:off 24 | http 25 | .authorizeRequests() 26 | .antMatchers("/authorize") 27 | .hasRole("USER") 28 | .and() 29 | .addFilterAfter(authRequestFilter, SecurityContextPersistenceFilter.class) 30 | ; 31 | // @formatter:on 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/main/java/org/mitre/springboot/config/openid/connect/DynamicClientRegistrationResourceServerConfig.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.config.openid.connect; 2 | 3 | import javax.servlet.Filter; 4 | 5 | import org.mitre.openid.connect.view.ClientInformationResponseView; 6 | import org.mitre.openid.connect.web.DynamicClientRegistrationEndpoint; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.beans.factory.annotation.Qualifier; 9 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 10 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | import org.springframework.core.annotation.Order; 14 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 15 | import org.springframework.security.config.http.SessionCreationPolicy; 16 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; 17 | import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint; 18 | import org.springframework.security.web.context.SecurityContextPersistenceFilter; 19 | 20 | @Configuration 21 | @ConditionalOnProperty(havingValue="true", name="openid.connect.endpoints.oidc.dynamicclientregistration.enabled", matchIfMissing=true) 22 | @Order(200) 23 | public class DynamicClientRegistrationResourceServerConfig extends ResourceServerConfigurerAdapter { 24 | String PATTERN = "/" + org.mitre.openid.connect.web.DynamicClientRegistrationEndpoint.URL + "/**"; 25 | 26 | @Autowired 27 | protected OAuth2AuthenticationEntryPoint authenticationEntryPoint; 28 | 29 | @Bean 30 | @ConditionalOnMissingBean(DynamicClientRegistrationEndpoint.class) 31 | protected DynamicClientRegistrationEndpoint DynamicClientRegistrationEndpoint() { 32 | return new DynamicClientRegistrationEndpoint(); 33 | } 34 | 35 | @Bean(name=ClientInformationResponseView.VIEWNAME) 36 | @ConditionalOnMissingBean(name=ClientInformationResponseView.VIEWNAME) 37 | protected ClientInformationResponseView clientInformationResponseView() { 38 | return new ClientInformationResponseView(); 39 | } 40 | 41 | 42 | @Override 43 | public void configure(HttpSecurity http) throws Exception { 44 | // @formatter:off 45 | http 46 | .requestMatchers() 47 | .antMatchers(PATTERN) 48 | .and() 49 | .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint) 50 | .and() 51 | .sessionManagement() 52 | .sessionCreationPolicy(SessionCreationPolicy.STATELESS) 53 | .and() 54 | .authorizeRequests() 55 | .antMatchers(PATTERN) 56 | .permitAll() 57 | ; 58 | // @formatter:on 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/main/java/org/mitre/springboot/config/openid/connect/JwkWebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.config.openid.connect; 2 | 3 | import javax.servlet.Filter; 4 | 5 | import org.mitre.openid.connect.view.JWKSetView; 6 | import org.mitre.openid.connect.web.JWKSetPublishingEndpoint; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.beans.factory.annotation.Qualifier; 9 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 10 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | import org.springframework.core.annotation.Order; 14 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 15 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 16 | import org.springframework.security.config.http.SessionCreationPolicy; 17 | import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint; 18 | 19 | @Order(150) 20 | @Configuration 21 | @ConditionalOnProperty(havingValue="true", name="openid.connect.endpoints.oidc.jwksetpublishing.enabled", matchIfMissing=true) 22 | public class JwkWebSecurityConfig extends WebSecurityConfigurerAdapter { 23 | 24 | @Autowired 25 | protected Http403ForbiddenEntryPoint http403ForbiddenEntryPoint; 26 | 27 | @Bean 28 | @ConditionalOnMissingBean(JWKSetPublishingEndpoint.class) 29 | protected JWKSetPublishingEndpoint JWKSetPublishingEndpoint() { 30 | return new JWKSetPublishingEndpoint(); 31 | } 32 | 33 | @Bean(name=JWKSetView.VIEWNAME) 34 | @ConditionalOnMissingBean(name=JWKSetView.VIEWNAME) 35 | protected JWKSetView jwkSet() { 36 | return new JWKSetView(); 37 | } 38 | 39 | @Override 40 | protected void configure(HttpSecurity http) throws Exception { 41 | // @formatter:off 42 | http 43 | .requestMatchers() 44 | .antMatchers("/jwk**") 45 | .and() 46 | .exceptionHandling() 47 | .authenticationEntryPoint(http403ForbiddenEntryPoint) 48 | .and() 49 | .sessionManagement() 50 | .sessionCreationPolicy(SessionCreationPolicy.STATELESS) 51 | .and() 52 | .authorizeRequests() 53 | .antMatchers("/jwk**") 54 | .permitAll() 55 | ; 56 | // @formatter:on 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/main/java/org/mitre/springboot/config/openid/connect/UserInfoResourceServerConfig.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.config.openid.connect; 2 | 3 | import javax.servlet.Filter; 4 | 5 | import org.mitre.openid.connect.view.UserInfoJWTView; 6 | import org.mitre.openid.connect.view.UserInfoView; 7 | import org.mitre.openid.connect.web.UserInfoEndpoint; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.beans.factory.annotation.Qualifier; 10 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 11 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.core.annotation.Order; 15 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 16 | import org.springframework.security.config.http.SessionCreationPolicy; 17 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; 18 | import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint; 19 | import org.springframework.security.web.context.SecurityContextPersistenceFilter; 20 | 21 | @Configuration 22 | @ConditionalOnProperty(havingValue="true", name="openid.connect.endpoints.oidc.userinfo.enabled", matchIfMissing=true) 23 | @Order(190) 24 | public class UserInfoResourceServerConfig extends ResourceServerConfigurerAdapter { 25 | String PATTERN = "/" + org.mitre.openid.connect.web.UserInfoEndpoint.URL + "**"; 26 | 27 | @Autowired 28 | protected OAuth2AuthenticationEntryPoint authenticationEntryPoint; 29 | 30 | @Bean 31 | @ConditionalOnMissingBean(UserInfoEndpoint.class) 32 | protected UserInfoEndpoint userInfoEndpoint() { 33 | return new UserInfoEndpoint(); 34 | } 35 | 36 | @Bean(name=UserInfoJWTView.VIEWNAME) 37 | @ConditionalOnMissingBean(name=UserInfoJWTView.VIEWNAME) 38 | protected UserInfoJWTView userInfoJwtView() { 39 | return new UserInfoJWTView(); 40 | } 41 | 42 | @Bean(name=UserInfoView.VIEWNAME) 43 | @ConditionalOnMissingBean(name=UserInfoView.VIEWNAME) 44 | protected UserInfoView userInfoView() { 45 | return new UserInfoView(); 46 | } 47 | 48 | @Override 49 | public void configure(HttpSecurity http) throws Exception { 50 | // @formatter:off 51 | http 52 | .requestMatchers() 53 | .antMatchers(PATTERN) 54 | .and() 55 | .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint) 56 | .and() 57 | .sessionManagement() 58 | .sessionCreationPolicy(SessionCreationPolicy.STATELESS) 59 | ; 60 | // @formatter:on 61 | } 62 | 63 | } -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/main/java/org/mitre/springboot/config/openid/connect/WellKnownWebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.config.openid.connect; 2 | 3 | import org.mitre.discovery.view.WebfingerView; 4 | import org.mitre.discovery.web.DiscoveryEndpoint; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.core.annotation.Order; 11 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 12 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 13 | import org.springframework.security.config.http.SessionCreationPolicy; 14 | import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint; 15 | 16 | @Order(160) 17 | @Configuration 18 | @ConditionalOnProperty(havingValue="true", name="openid.connect.endpoints.oidc.discovery.enabled", matchIfMissing=true) 19 | public class WellKnownWebSecurityConfig extends WebSecurityConfigurerAdapter { 20 | 21 | @Autowired 22 | protected Http403ForbiddenEntryPoint http403ForbiddenEntryPoint; 23 | 24 | @Bean 25 | @ConditionalOnMissingBean(DiscoveryEndpoint.class) 26 | protected DiscoveryEndpoint discoveryEndpoint() { 27 | return new DiscoveryEndpoint(); 28 | } 29 | 30 | @Bean(name="webfingerView") 31 | @ConditionalOnMissingBean(name="webfingerView") 32 | protected WebfingerView webfingerView() { 33 | return new WebfingerView(); 34 | } 35 | 36 | @Override 37 | protected void configure(HttpSecurity http) throws Exception { 38 | // @formatter:off 39 | http 40 | .requestMatchers() 41 | .antMatchers("/.well-known/**") 42 | .and() 43 | .exceptionHandling() 44 | .authenticationEntryPoint(http403ForbiddenEntryPoint) 45 | .and() 46 | .sessionManagement() 47 | .sessionCreationPolicy(SessionCreationPolicy.STATELESS) 48 | .and() 49 | .authorizeRequests() 50 | .antMatchers("/.well-known/**") 51 | .permitAll() 52 | ; 53 | // @formatter:on 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | initialize: true 4 | schema: classpath:/db/tables/hsql_database_tables.sql,classpath:/db/tables/security-schema.sql 5 | data: classpath:/db/users.sql,classpath:/db/clients.sql,classpath:/db/scopes.sql 6 | logging: 7 | level: 8 | ROOT: INFO 9 | org.springframework.security: INFO 10 | 11 | openid: 12 | connect: 13 | server: 14 | issuer: http://localhost:8080/ 15 | topbarTitle: OpenID Connect Server 16 | logoImageUrl: resources/images/openid_connect_small.png 17 | crypto: 18 | keystore: 19 | path: classpath:keystore.jwks 20 | signing: 21 | defaultSignerKeyId: rsa1 22 | defaultSigningAlgorithmName: RS256 23 | encrypt: 24 | defaultAlgorithm: RSA1_5 25 | defaultDecryptionKeyId: rsa1 26 | defaultEncryptionKeyId: rsa1 -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/main/resources/db/tables/security-schema.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- Tables for Spring Security's user details service 3 | -- 4 | 5 | -- 6 | -- Tables for Spring Security's user details service 7 | -- 8 | 9 | create table IF NOT EXISTS users( 10 | username varchar(50) not null primary key, 11 | password varchar(2048) not null, 12 | enabled boolean not null); 13 | 14 | create table IF NOT EXISTS authorities ( 15 | username varchar(50) not null, 16 | authority varchar(50) not null, 17 | constraint fk_authorities_users foreign key(username) references users(username), 18 | constraint ix_authority unique (username,authority)); -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/main/resources/keystore.jwks: -------------------------------------------------------------------------------- 1 | { 2 | "keys": [ 3 | { 4 | "alg": "RS256", 5 | "d": "PvBAngE3kkTnD3yDKo3wCvHJHm20kb9a0FVGLd0s2Y0E_3H2XnZC8-2zPhN6AQTjPhohSDCew20gzm76lyOvMqRiUP2Zpaopa1d2fGvNIQSdM07yKa6EivEYxqPQxa5esoZnexgnb9fom70I8n5OQRNQikwu-az26CsHX2zWMRodzSdN5CXHvb1PV09DmH8azTYwoMElPIqmcTfxiRw2Ov5ucmXXngKRFJgvfUgKd7v4ScBX7sQoQEjWEtt7ta0WvL3Ar5E1RAW4aHxuubZ6AtloxWCf17AAKw03dfP5RDm5TDmgm2B635ecJ7fTvneFmg8W_fdMTPRfBlCGNBp3wQ", 6 | "e": "AQAB", 7 | "n": "qt6yOiI_wCoCVlGO0MySsez0VkSqhPvDl3rfabOslx35mYEO-n4ABfIT5Gn2zN-CeIcOZ5ugAXvIIRWv5H55-tzjFazi5IKkOIMCiz5__MtsdxKCqGlZu2zt-BLpqTOAPiflNPpM3RUAlxKAhnYEqNha6-allPnFQupnW_eTYoyuzuedT7dSp90ry0ZcQDimntXWeaSbrYKCj9Rr9W1jn2uTowUuXaScKXTCjAmJVnsD75JNzQfa8DweklTyWQF-Y5Ky039I0VIu-0CIGhXY48GAFe2EFb8VpNhf07DP63p138RWQ1d3KPEM9mYJVpQC68j3wzDQYSljpLf9by7TGw", 8 | "kty": "RSA", 9 | "kid": "rsa1" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/test/java/org/mitre/boot/security/TestBootApplication.java: -------------------------------------------------------------------------------- 1 | package org.mitre.boot.security; 2 | 3 | import org.mitre.springboot.config.annotation.EnableOpenIDConnectServer; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.boot.web.support.SpringBootServletInitializer; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | /** 10 | * @author barretttucker 11 | * 12 | */ 13 | @Configuration 14 | @SpringBootApplication 15 | @EnableOpenIDConnectServer 16 | public class TestBootApplication extends SpringBootServletInitializer{ 17 | 18 | public static void main(final String[] args){ 19 | SpringApplication.run(TestBootApplication.class, args); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/test/java/org/mitre/boot/security/TestBootApplicationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.boot.security; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.security.web.FilterChainProxy; 9 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 10 | import org.springframework.test.context.web.WebAppConfiguration; 11 | import org.springframework.test.web.servlet.MockMvc; 12 | import org.springframework.test.web.servlet.setup.MockMvcBuilders; 13 | import org.springframework.web.context.WebApplicationContext; 14 | 15 | @RunWith(SpringJUnit4ClassRunner.class) 16 | @SpringBootTest(classes = TestBootApplication.class) 17 | @WebAppConfiguration 18 | public class TestBootApplicationTests{ 19 | 20 | @Autowired 21 | protected WebApplicationContext context; 22 | 23 | @Autowired 24 | protected FilterChainProxy springSecurityFilterChain; 25 | 26 | protected MockMvc mockMvc; 27 | 28 | @Before 29 | public void setUp(){ 30 | this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).addFilter(springSecurityFilterChain).build(); 31 | } 32 | 33 | @Test 34 | public void contextLoads(){ 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/test/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | jpa: 3 | properties: 4 | eclipselink: 5 | logging: 6 | level: 7 | ROOT: INFO 8 | sql: INFO 9 | datasource: 10 | initialize: true 11 | schema: classpath:/db/tables/hsql_database_tables.sql,classpath:/db/tables/security-schema.sql 12 | logging: 13 | level: 14 | ROOT: INFO 15 | org.springframework.security: INFO 16 | server: 17 | port: 8080 18 | contextPath: / 19 | 20 | openid: 21 | connect: 22 | server: 23 | host: localhost 24 | issuer: http://${openid.connect.server.host}:${server.port}${server.contextPath} 25 | topbarTitle: OpenID Connect Server 26 | logoImageUrl: resources/images/openid_connect_small.png 27 | regTokenLifeTime: 172800 28 | forceHttps: false 29 | rqpTokenLifeTime: 30 | locale: en 31 | languageNamespaces: 32 | - messages 33 | dualClient: false 34 | crypto: 35 | keystore: 36 | path: classpath:keystore.jwks 37 | signing: 38 | defaultSignerKeyId: rsa1 39 | defaultSigningAlgorithmName: RS256 40 | encrypt: 41 | defaultAlgorithm: RSA1_5 42 | defaultDecryptionKeyId: rsa1 43 | defaultEncryptionKeyId: rsa1 44 | jsonMessageSource: 45 | baseDirectory: classpath:/static/resources/js/locale/ 46 | scheduling: 47 | enabled: true 48 | corePoolSize: 5 49 | tasks: 50 | clearExpiredTokens: 51 | fixedDelay: 30000 52 | initialDelay: 60000 53 | clearExpiredSites: 54 | fixedDelay: 30000 55 | initialDelay: 60000 56 | clearExpiredAuthorizationCodes: 57 | fixedDelay: 30000 58 | initialDelay: 60000 59 | endpoints: 60 | api: 61 | whitelist.enabled: true 62 | approvedsite.enabled: true 63 | blacklist.enabled: true 64 | client.enabled: true 65 | data.enabled: true 66 | token.enabled: true 67 | scope.enabled: true 68 | stats.enabled: true 69 | oidc: 70 | dynamicclientregistration.enabled: false 71 | jwksetpublishing.enabled: false 72 | userinfo.enabled: false 73 | discovery.enabled: false 74 | protectedresourceregistration.enabled: false 75 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-config/src/test/resources/keystore.jwks: -------------------------------------------------------------------------------- 1 | { 2 | "keys": [ 3 | { 4 | "alg": "RS256", 5 | "d": "PvBAngE3kkTnD3yDKo3wCvHJHm20kb9a0FVGLd0s2Y0E_3H2XnZC8-2zPhN6AQTjPhohSDCew20gzm76lyOvMqRiUP2Zpaopa1d2fGvNIQSdM07yKa6EivEYxqPQxa5esoZnexgnb9fom70I8n5OQRNQikwu-az26CsHX2zWMRodzSdN5CXHvb1PV09DmH8azTYwoMElPIqmcTfxiRw2Ov5ucmXXngKRFJgvfUgKd7v4ScBX7sQoQEjWEtt7ta0WvL3Ar5E1RAW4aHxuubZ6AtloxWCf17AAKw03dfP5RDm5TDmgm2B635ecJ7fTvneFmg8W_fdMTPRfBlCGNBp3wQ", 6 | "e": "AQAB", 7 | "n": "qt6yOiI_wCoCVlGO0MySsez0VkSqhPvDl3rfabOslx35mYEO-n4ABfIT5Gn2zN-CeIcOZ5ugAXvIIRWv5H55-tzjFazi5IKkOIMCiz5__MtsdxKCqGlZu2zt-BLpqTOAPiflNPpM3RUAlxKAhnYEqNha6-allPnFQupnW_eTYoyuzuedT7dSp90ry0ZcQDimntXWeaSbrYKCj9Rr9W1jn2uTowUuXaScKXTCjAmJVnsD75JNzQfa8DweklTyWQF-Y5Ky039I0VIu-0CIGhXY48GAFe2EFb8VpNhf07DP63p138RWQ1d3KPEM9mYJVpQC68j3wzDQYSljpLf9by7TGw", 8 | "kty": "RSA", 9 | "kid": "rsa1" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/README.md: -------------------------------------------------------------------------------- 1 | # Spring Boot MITREid Connect Tests 2 | --- 3 | 4 | This suite of tests attempts to enhance the coverage provided by the reference implementation unit tests. They are intended as integration tests to test security policies that are implemented via @PreAuthorize annotations, WebSecurityConfigurerAdapters or ResourceServerConfigurerAdapters. -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/build.gradle: -------------------------------------------------------------------------------- 1 | 2 | dependencies { 3 | testImplementation project(":openid-connect-server-spring-boot-config") 4 | testImplementation project(":openid-connect-server-spring-boot-ui-thymeleaf") 5 | 6 | testImplementation libs.springBootStarterTest 7 | testImplementation libs.springSecurityTest 8 | testImplementation libs.jsonPath 9 | testImplementation libs.httpClient 10 | testImplementation libs.bouncyCastle 11 | 12 | testRuntimeOnly libs.h2Database 13 | } 14 | 15 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/gradle.properties: -------------------------------------------------------------------------------- 1 | description = OpenID Connect Spring Boot Application Tests -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/boot/security/ui/LoginEndpointTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.boot.security.ui; 2 | 3 | import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; 4 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 5 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; 6 | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; 7 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; 8 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 9 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; 10 | 11 | import java.util.Locale; 12 | 13 | import javax.servlet.http.HttpSession; 14 | import javax.transaction.Transactional; 15 | 16 | import org.junit.Assert; 17 | import org.junit.Test; 18 | import org.mitre.springboot.EndpointTestsBase; 19 | import org.springframework.mock.web.MockHttpSession; 20 | 21 | @Transactional 22 | public class LoginEndpointTests extends EndpointTestsBase { 23 | 24 | @Test 25 | public void loginViewAsAdminTest() throws Exception { 26 | HttpSession session = mockMvc.perform( 27 | post("/login") 28 | .with(csrf()) 29 | .param("username", "admin") 30 | .param("password", "password")) 31 | .andExpect(status().isFound()) 32 | .andExpect(redirectedUrl("/")) 33 | .andDo(print()) 34 | .andReturn() 35 | .getRequest() 36 | .getSession() 37 | ; 38 | 39 | Assert.assertNotNull(session); 40 | 41 | mockMvc.perform( 42 | get("/") 43 | .session((MockHttpSession)session).locale(Locale.ENGLISH)) 44 | .andDo(print()) 45 | .andExpect(status().isOk()) 46 | .andExpect(view().name("home")) 47 | ; 48 | } 49 | 50 | @Test 51 | public void loginViewAsUserTest() throws Exception { 52 | HttpSession session = mockMvc.perform( 53 | post("/login") 54 | .with(csrf()) 55 | .param("username", "user") 56 | .param("password", "password")) 57 | .andExpect(status().isFound()) 58 | .andExpect(redirectedUrl("/")) 59 | .andDo(print()) 60 | .andReturn() 61 | .getRequest() 62 | .getSession(); 63 | 64 | Assert.assertNotNull(session); 65 | 66 | mockMvc.perform( 67 | get("/") 68 | .session((MockHttpSession)session).locale(Locale.ENGLISH)) 69 | .andDo(print()) 70 | .andExpect(status().isOk()) 71 | .andExpect(view().name("home")) 72 | ; 73 | } 74 | 75 | 76 | 77 | } 78 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/EndpointTestsBase.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot; 2 | 3 | import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; 4 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; 5 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; 6 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 7 | 8 | import java.util.UUID; 9 | 10 | import org.junit.Before; 11 | import org.junit.runner.RunWith; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.boot.test.context.SpringBootTest; 14 | import org.springframework.mock.web.MockHttpSession; 15 | import org.springframework.security.web.FilterChainProxy; 16 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 17 | import org.springframework.test.context.web.WebAppConfiguration; 18 | import org.springframework.test.web.servlet.MockMvc; 19 | import org.springframework.test.web.servlet.setup.MockMvcBuilders; 20 | import org.springframework.web.context.WebApplicationContext; 21 | 22 | import com.fasterxml.jackson.databind.ObjectMapper; 23 | 24 | @RunWith(SpringJUnit4ClassRunner.class) 25 | @SpringBootTest(classes = {TestBootApplication.class}) 26 | @WebAppConfiguration 27 | public abstract class EndpointTestsBase{ 28 | 29 | @Autowired 30 | protected WebApplicationContext context; 31 | 32 | @Autowired 33 | protected FilterChainProxy springSecurityFilterChain; 34 | 35 | protected MockMvc mockMvc; 36 | protected MockHttpSession mockSession; 37 | protected ObjectMapper mapper = new ObjectMapper(); 38 | 39 | @Before 40 | public void setUp(){ 41 | this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).addFilter(springSecurityFilterChain).build(); 42 | mockSession = new MockHttpSession(context.getServletContext(), UUID.randomUUID().toString()); 43 | } 44 | 45 | protected void adminSession() throws Exception{ 46 | loginSession("admin", "password"); 47 | } 48 | 49 | protected void userSession() throws Exception{ 50 | loginSession("user", "password"); 51 | } 52 | 53 | protected void loginSession(final String username, final String password) throws Exception{ 54 | mockMvc.perform(post("/login").session(mockSession).with(csrf()).param("username", username).param("password", 55 | password)).andExpect(status().isFound()).andExpect(redirectedUrl("/")).andReturn().getRequest(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/TestBootApplication.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot; 2 | 3 | import org.mitre.springboot.config.annotation.EnableOpenIDConnectServer; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.boot.web.support.SpringBootServletInitializer; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | /** 10 | * @author barretttucker 11 | * 12 | */ 13 | @Configuration 14 | @SpringBootApplication 15 | @EnableOpenIDConnectServer 16 | public class TestBootApplication extends SpringBootServletInitializer{ 17 | 18 | public static void main(final String[] args){ 19 | SpringApplication.run(TestBootApplication.class, args); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/discovery/web/DiscoveryEndpointAuthorizationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.discovery.web; 2 | 3 | import javax.transaction.Transactional; 4 | 5 | import org.junit.Test; 6 | import org.mitre.springboot.openid.connect.web.ApiAuthorizationTestsBase; 7 | import org.springframework.beans.factory.annotation.Value; 8 | 9 | @Transactional 10 | public class DiscoveryEndpointAuthorizationTests extends ApiAuthorizationTestsBase { 11 | 12 | @Value("${openid.connect.server.issuer}") 13 | protected String issuer; 14 | 15 | @Test 16 | public void adminGetDiscoveryEndpointSuccess() throws Exception { 17 | adminSession(); 18 | checkGetAccess("/.well-known/openid-configuration", 200); 19 | checkGetAccess("/.well-known/webfinger?resource="+issuer+"&rel=http://openid.net/specs/connect/1.0/issuer", 200); 20 | } 21 | 22 | @Test 23 | public void userGetDiscoveryEndpointSuccess() throws Exception { 24 | userSession(); 25 | checkGetAccess("/.well-known/openid-configuration", 200); 26 | checkGetAccess("/.well-known/webfinger?resource="+issuer+"&rel=http://openid.net/specs/connect/1.0/issuer", 200); 27 | } 28 | 29 | @Test 30 | public void anonymousGetDiscoverySuccess() throws Exception { 31 | checkGetAccess("/.well-known/openid-configuration", 200); 32 | checkGetAccess("/.well-known/webfinger?resource="+issuer+"&rel=http://openid.net/specs/connect/1.0/issuer", 200); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/oauth2/web/BCryptTokenEndpointAuthorizationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.oauth2.web; 2 | 3 | import javax.transaction.Transactional; 4 | 5 | import org.junit.Test; 6 | import org.springframework.test.context.ActiveProfiles; 7 | 8 | @Transactional 9 | @ActiveProfiles(profiles = "bcrypt") 10 | public class BCryptTokenEndpointAuthorizationTests extends OAuthAuthorizationTestsBase{ 11 | 12 | @Test 13 | public void givenAClientCredentialsAuthenticationShouldBeAuthenticatedWhenPasswordIsEncodedWithBCrypt() 14 | throws Exception{ 15 | 16 | getClientAccessToken("client_bcrypt", "secret"); 17 | } 18 | 19 | @Test 20 | public void givenAPasswordAuthenticationShouldBeAuthenticatedWhenPasswordIsEncodedWithBCrypt() throws Exception{ 21 | 22 | getToken("admin_bcrypt", "password", "token", "access_token"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/oauth2/web/IntrospectEndpointAuthorizationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.oauth2.web; 2 | 3 | import static org.hamcrest.Matchers.is; 4 | import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; 5 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 6 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; 7 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 8 | 9 | import javax.transaction.Transactional; 10 | 11 | import org.junit.Test; 12 | import org.mitre.oauth2.web.IntrospectionEndpoint; 13 | 14 | @Transactional 15 | public class IntrospectEndpointAuthorizationTests extends OAuthAuthorizationTestsBase { 16 | 17 | 18 | //TODO verify JWT access via JWTBearerClientAssertionTokenEndpointFilter rather than basic auth 19 | @Test 20 | public void userGetIntrospectEndpointSuccess() throws Exception { 21 | String accessToken = getUserAccessToken(); 22 | mockMvc.perform( 23 | get("/"+IntrospectionEndpoint.URL) 24 | .param("token", accessToken) 25 | .with(httpBasic("client","secret")) 26 | ) 27 | .andExpect(status().is(200)) 28 | .andExpect(jsonPath("sub", is("01921.FLANRJQW"))) 29 | .andReturn() 30 | .getResponse() 31 | ; 32 | } 33 | 34 | @Test 35 | public void userGetIntrospectClientCredentialsOnUriEndpointSuccess() throws Exception { 36 | String accessToken = getUserAccessToken(); 37 | mockMvc.perform( 38 | get("/"+IntrospectionEndpoint.URL) 39 | .param("token", accessToken) 40 | .param("client_id", "client") 41 | .param("client_secret", "secret") 42 | ) 43 | .andExpect(status().is(200)) 44 | .andExpect(jsonPath("sub", is("01921.FLANRJQW"))) 45 | .andReturn() 46 | .getResponse() 47 | ; 48 | } 49 | 50 | @Test 51 | public void anonymousGetIntrospectEndpointUnauthenticated() throws Exception { 52 | mockMvc.perform( 53 | get("/"+IntrospectionEndpoint.URL)) 54 | .andExpect(status().is(401)) 55 | ; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/oauth2/web/OAuthConfirmationControllerAuthorizationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.oauth2.web; 2 | 3 | import javax.transaction.Transactional; 4 | 5 | import org.junit.Test; 6 | import org.mitre.springboot.openid.connect.web.ApiAuthorizationTestsBase; 7 | 8 | @Transactional 9 | public class OAuthConfirmationControllerAuthorizationTests extends ApiAuthorizationTestsBase { 10 | 11 | //TODO OauthConfirmationControllerAuthorizationTests 12 | @Test 13 | public void TODO(){} 14 | 15 | } 16 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/oauth2/web/Pbkdf2TokenEndpointAuthorizationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.oauth2.web; 2 | 3 | import javax.transaction.Transactional; 4 | 5 | import org.junit.Test; 6 | import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder; 7 | import org.springframework.test.context.ActiveProfiles; 8 | 9 | @Transactional 10 | @ActiveProfiles(profiles = "pbkdf2") 11 | public class Pbkdf2TokenEndpointAuthorizationTests extends OAuthAuthorizationTestsBase{ 12 | 13 | @Test 14 | public void givenAClientCredentialsAuthenticationShouldBeAuthenticatedWhenPasswordIsEncodedWithBCrypt() 15 | throws Exception{ 16 | 17 | final Pbkdf2PasswordEncoder encoder = new Pbkdf2PasswordEncoder("salt"); 18 | 19 | final String secret = encoder.encode("secret"); 20 | final String password = encoder.encode("password"); 21 | 22 | getClientAccessToken("client_pbkdf2", "secret"); 23 | } 24 | 25 | @Test 26 | public void givenAPasswordAuthenticationShouldBeAuthenticatedWhenPasswordIsEncodedWithBCrypt() throws Exception{ 27 | 28 | final Pbkdf2PasswordEncoder encoder = new Pbkdf2PasswordEncoder("salt"); 29 | final String password = encoder.encode("password"); 30 | getToken("admin_pbkdf2", "password", "token", "access_token"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/oauth2/web/RevocationEndpointAuthorizationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.oauth2.web; 2 | 3 | import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; 4 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 5 | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; 6 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 7 | 8 | import javax.transaction.Transactional; 9 | 10 | import org.junit.Test; 11 | import org.mitre.oauth2.web.RevocationEndpoint; 12 | 13 | @Transactional 14 | public class RevocationEndpointAuthorizationTests extends OAuthAuthorizationTestsBase { 15 | 16 | //TODO verify JWT access via JWTBearerClientAssertionTokenEndpointFilter rather than basic auth 17 | @Test 18 | public void userGetRevocationEndpointClientIdAuthenticationSuccess() throws Exception { 19 | String accessToken = getUserAccessToken(); 20 | mockMvc.perform( 21 | get("/"+RevocationEndpoint.URL) 22 | .param("token", accessToken) 23 | .with(httpBasic("client","secret")) 24 | ) 25 | .andExpect(status().is(200)) 26 | .andDo(print()) 27 | .andReturn() 28 | .getResponse() 29 | ; 30 | } 31 | 32 | @Test 33 | public void userGetRevocationEndpointClientCredentialsOnUriEndpointSuccess() throws Exception { 34 | String accessToken = getUserAccessToken(); 35 | mockMvc.perform( 36 | get("/"+RevocationEndpoint.URL) 37 | .param("token", accessToken) 38 | .param("client_id", "client") 39 | .param("client_secret", "secret") 40 | ) 41 | .andExpect(status().is(200)) 42 | .andReturn() 43 | .getResponse() 44 | ; 45 | } 46 | 47 | @Test 48 | public void anonymousGetRevocationEndpointUnauthenticated() throws Exception { 49 | mockMvc.perform( 50 | get("/"+RevocationEndpoint.URL)) 51 | .andExpect(status().is(401)) 52 | ; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/oauth2/web/SCryptTokenEndpointAuthorizationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.oauth2.web; 2 | 3 | import javax.transaction.Transactional; 4 | 5 | import org.junit.Test; 6 | import org.springframework.test.context.ActiveProfiles; 7 | 8 | @Transactional 9 | @ActiveProfiles(profiles = "scrypt") 10 | public class SCryptTokenEndpointAuthorizationTests extends OAuthAuthorizationTestsBase{ 11 | 12 | @Test 13 | public void givenAClientCredentialsAuthenticationShouldBeAuthenticatedWhenPasswordIsEncodedWithBCrypt() 14 | throws Exception{ 15 | 16 | getClientAccessToken("client_scrypt", "secret"); 17 | } 18 | 19 | @Test 20 | public void givenAPasswordAuthenticationShouldBeAuthenticatedWhenPasswordIsEncodedWithBCrypt() throws Exception{ 21 | 22 | getToken("admin_scrypt", "password", "token", "access_token"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/oauth2/web/ScopeApiAuthorizationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.oauth2.web; 2 | 3 | import javax.transaction.Transactional; 4 | 5 | import org.junit.Test; 6 | import org.mitre.springboot.openid.connect.web.ApiAuthorizationTestsBase; 7 | import org.springframework.test.annotation.Rollback; 8 | 9 | @Transactional 10 | public class ScopeApiAuthorizationTests extends ApiAuthorizationTestsBase { 11 | 12 | 13 | @Test 14 | public void adminGetApiScopesSuccess() throws Exception { 15 | adminSession(); 16 | checkGetAccess("/api/scopes", 200); 17 | checkGetAccess("/api/scopes/1", 200); 18 | } 19 | 20 | @Test 21 | @Rollback(true) 22 | public void adminPostApiScopesSuccess() throws Exception { 23 | adminSession(); 24 | checkPostAccess("/api/scopes", 200,"{'value':'test'}"); 25 | } 26 | 27 | @Test 28 | @Rollback(true) 29 | public void adminPutApiScopesSuccess() throws Exception { 30 | adminSession(); 31 | checkPutAccess("/api/scopes/1", 200, "{'id':1,'value':'test'}"); 32 | } 33 | 34 | @Test 35 | @Rollback(true) 36 | public void adminDeleteApiScopesSuccess() throws Exception { 37 | adminSession(); 38 | checkDeleteAccess("/api/scopes/1", 200); 39 | } 40 | 41 | @Test 42 | public void userGetApiScopesSuccess() throws Exception { 43 | userSession(); 44 | checkGetAccess("/api/scopes", 200); 45 | checkGetAccess("/api/scopes/1", 200); 46 | } 47 | 48 | @Test 49 | @Rollback(true) 50 | public void userPostApiScopesUauthorized() throws Exception { 51 | userSession(); 52 | checkPostAccess("/api/scopes", 403); 53 | } 54 | 55 | @Test 56 | @Rollback(true) 57 | public void userPutApiScopesUauthorized() throws Exception { 58 | userSession(); 59 | checkPutAccess("/api/scopes/1", 403); 60 | } 61 | 62 | @Test 63 | @Rollback(true) 64 | public void userDeleteApiScopesUauthorized() throws Exception { 65 | userSession(); 66 | checkDeleteAccess("/api/scopes/1", 403); 67 | } 68 | 69 | 70 | @Test 71 | public void anonymousGetApiScopesUnauthenticated() throws Exception { 72 | checkGetAccess("/api/scopes", 401); 73 | checkGetAccess("/api/scopes/1", 401); 74 | } 75 | 76 | @Test 77 | public void anonymousPostApiScopesUnauthenticated() throws Exception { 78 | checkPostAccess("/api/scopes", 401); 79 | } 80 | 81 | @Test 82 | public void userPutApiScopesUnauthenticated() throws Exception { 83 | checkPutAccess("/api/scopes/1", 401); 84 | } 85 | 86 | @Test 87 | public void userDeleteApiScopesUnauthenticated() throws Exception { 88 | checkDeleteAccess("/api/scopes/1", 401); 89 | } 90 | 91 | 92 | } 93 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/oauth2/web/StandardTokenEndpointAuthorizationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.oauth2.web; 2 | 3 | import javax.transaction.Transactional; 4 | 5 | import org.junit.Test; 6 | import org.springframework.test.context.ActiveProfiles; 7 | 8 | @Transactional 9 | @ActiveProfiles(profiles = "standard") 10 | public class StandardTokenEndpointAuthorizationTests extends OAuthAuthorizationTestsBase{ 11 | 12 | @Test 13 | public void givenAClientCredentialsAuthenticationShouldBeAuthenticatedWhenPasswordIsEncodedWithBCrypt() 14 | throws Exception{ 15 | 16 | getClientAccessToken("client_standard", "secret"); 17 | } 18 | 19 | @Test 20 | public void givenAPasswordAuthenticationShouldBeAuthenticatedWhenPasswordIsEncodedWithBCrypt() throws Exception{ 21 | getToken("admin_standard", "password", "token", "access_token"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/oauth2/web/TokenApiAuthorizationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.oauth2.web; 2 | 3 | import javax.transaction.Transactional; 4 | 5 | import org.junit.Test; 6 | import org.mitre.springboot.openid.connect.web.ApiAuthorizationTestsBase; 7 | 8 | @Transactional 9 | public class TokenApiAuthorizationTests extends ApiAuthorizationTestsBase { 10 | 11 | @Test 12 | public void adminGetApiTokenSuccess() throws Exception { 13 | adminSession(); 14 | checkGetAccess("/api/tokens/access", 200); 15 | } 16 | 17 | //TODO token tests for the token API endpoints 18 | @Test 19 | public void TODO(){} 20 | 21 | } 22 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/oauth2/web/TokenEndpointAuthorizationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.oauth2.web; 2 | 3 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 4 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 5 | 6 | import javax.transaction.Transactional; 7 | 8 | import org.junit.Test; 9 | 10 | @Transactional 11 | public class TokenEndpointAuthorizationTests extends OAuthAuthorizationTestsBase{ 12 | 13 | //TODO verify ClientCredentialsTokenEndpointFilter type of access with client_id and client_secret on the URI rather than basic auth 14 | //TODO verify JWT access via JWTBearerClientAssertionTokenEndpointFilter rather than basic auth 15 | //TODO token tests 16 | 17 | @Test 18 | public void anonymousGetTokenEndpointUnauthenticated() throws Exception{ 19 | mockMvc.perform(get("/token")).andExpect(status().is(401)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/openid/connect/web/ApiAuthorizationTestsBase.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.openid.connect.web; 2 | 3 | import static org.hamcrest.Matchers.is; 4 | import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; 5 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; 6 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 7 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; 8 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; 9 | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; 10 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; 11 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 12 | 13 | import java.util.Locale; 14 | 15 | import javax.transaction.Transactional; 16 | 17 | import org.mitre.springboot.EndpointTestsBase; 18 | import org.springframework.http.MediaType; 19 | 20 | @Transactional 21 | public abstract class ApiAuthorizationTestsBase extends EndpointTestsBase { 22 | 23 | protected void checkGetAccess(String uri, int status) throws Exception { 24 | mockMvc.perform( 25 | get(uri) 26 | .session(mockSession) 27 | .locale(Locale.ENGLISH)) 28 | .andExpect(status().is(status)) 29 | ; 30 | } 31 | 32 | protected void checkPostAccess(String uri, int status) throws Exception { 33 | checkPostAccess(uri, status, "{}"); 34 | } 35 | 36 | protected void checkPostAccess(String uri, int status, String body) throws Exception { 37 | mockMvc.perform( 38 | post(uri) 39 | .contentType(MediaType.APPLICATION_JSON_VALUE) 40 | .content(body) 41 | .session(mockSession) 42 | .locale(Locale.ENGLISH) 43 | ) 44 | .andExpect(status().is(status)) 45 | ; 46 | } 47 | 48 | protected void checkPutAccess(String uri, int status) throws Exception { 49 | checkPutAccess(uri, status, "{}"); 50 | } 51 | 52 | protected void checkPutAccess(String uri, int status, String body) throws Exception { 53 | mockMvc.perform( 54 | put(uri) 55 | .contentType(MediaType.APPLICATION_JSON_VALUE) 56 | .content(body) 57 | .session(mockSession) 58 | .locale(Locale.ENGLISH) 59 | ) 60 | .andExpect(status().is(status)) 61 | ; 62 | } 63 | 64 | protected void checkDeleteAccess(String uri, int status) throws Exception { 65 | mockMvc.perform( 66 | delete(uri) 67 | .session(mockSession) 68 | .locale(Locale.ENGLISH) 69 | ) 70 | .andExpect(status().is(status)) 71 | ; 72 | } 73 | 74 | protected void checkGetAccess(String uri, int status, String jsonPath, String value) throws Exception { 75 | mockMvc.perform( 76 | get(uri) 77 | .session(mockSession) 78 | .locale(Locale.ENGLISH) 79 | ) 80 | .andExpect(status().is(status)) 81 | .andExpect(jsonPath(jsonPath, is(value))) 82 | ; 83 | } 84 | 85 | protected void checkGetAccessMissingValue(String uri, int status, String missingJsonPath) throws Exception { 86 | mockMvc.perform( 87 | get(uri) 88 | .session(mockSession) 89 | .locale(Locale.ENGLISH) 90 | ) 91 | .andExpect(status().is(status)) 92 | .andExpect(jsonPath(missingJsonPath).doesNotExist()) 93 | ; 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/openid/connect/web/ApprovedSiteApiAuthorizationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.openid.connect.web; 2 | 3 | import javax.transaction.Transactional; 4 | 5 | import org.junit.Test; 6 | 7 | @Transactional 8 | public class ApprovedSiteApiAuthorizationTests extends ApiAuthorizationTestsBase { 9 | 10 | 11 | @Test 12 | public void adminGetApiApprovedSuccess() throws Exception { 13 | adminSession(); 14 | checkGetAccess("/api/approved", 200); 15 | //Note test setup data has no approved sites, considering adding for security test 16 | //TODO test GET by ID 17 | //TODO test DELETE by ID 18 | } 19 | 20 | @Test 21 | public void userGetApiApprovedSuccess() throws Exception { 22 | userSession(); 23 | checkGetAccess("/api/approved", 200); 24 | //Note test setup data has no approved sites, considering adding for security test 25 | //TODO test GET by ID 26 | //TODO test DELETE by ID 27 | } 28 | 29 | @Test 30 | public void anonymousGetApiApprovedUnauthorized() throws Exception { 31 | checkGetAccess("/api/approved", 401); 32 | //TODO test GET by ID 33 | //TODO test DELETE by ID 34 | } 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/openid/connect/web/BlacklistApiAuthorizationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.openid.connect.web; 2 | 3 | import static org.hamcrest.Matchers.is; 4 | import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; 5 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; 6 | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; 7 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; 8 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 9 | 10 | import java.util.Locale; 11 | 12 | import javax.transaction.Transactional; 13 | 14 | import org.junit.Test; 15 | import org.mitre.openid.connect.model.BlacklistedSite; 16 | import org.springframework.http.MediaType; 17 | 18 | import com.fasterxml.jackson.databind.ObjectMapper; 19 | 20 | @Transactional 21 | public class BlacklistApiAuthorizationTests extends ApiAuthorizationTestsBase { 22 | 23 | ObjectMapper mapper = new ObjectMapper(); 24 | @Test 25 | public void adminGetApiBlacklistSuccess() throws Exception { 26 | adminSession(); 27 | checkGetAccess("/api/blacklist", 200); 28 | //Note test setup data has no blacklist sites, considering adding for security testing 29 | //TODO test GET by ID 30 | //TODO test POST 31 | //TODO test PUT by ID 32 | //TODO test DELETE by ID 33 | } 34 | 35 | @Test 36 | public void userGetApiBlacklistUnauthorized() throws Exception { 37 | userSession(); 38 | checkGetAccess("/api/blacklist", 403); 39 | } 40 | 41 | @Test 42 | public void userPostApiBlacklistUnauthorized() throws Exception { 43 | userSession(); 44 | checkPostAccess("/api/blacklist", 403); 45 | } 46 | 47 | @Test 48 | public void userPutApiBlacklistUnauthorized() throws Exception { 49 | userSession(); 50 | checkPutAccess("/api/blacklist/1", 403); 51 | } 52 | 53 | @Test 54 | public void userDeleteApiBlacklistUnauthorized() throws Exception { 55 | userSession(); 56 | checkDeleteAccess("/api/blacklist/1", 403); 57 | } 58 | 59 | @Test 60 | public void anonymousGetApiBlacklistUnauthenticated() throws Exception { 61 | checkGetAccess("/api/blacklist", 401); 62 | } 63 | 64 | @Test 65 | public void anonymousPostApiBlacklistUnauthenticated() throws Exception { 66 | checkPostAccess("/api/blacklist", 401); 67 | } 68 | 69 | @Test 70 | public void anonymousPutApiBlacklistUnauthenticated() throws Exception { 71 | checkPutAccess("/api/blacklist/1", 401); 72 | } 73 | 74 | @Test 75 | public void anonymousDeleteApiBlacklistUnauthenticated() throws Exception { 76 | checkDeleteAccess("/api/blacklist/1", 401); 77 | } 78 | 79 | 80 | @Test 81 | public void adminBlacklistAddSuccess() throws Exception { 82 | adminSession(); 83 | String blacklistUrl = "http://www.blacklistedsite.com"; 84 | String body = "{'uri':'" + blacklistUrl + "'}"; 85 | mockMvc.perform( 86 | post("/api/blacklist") 87 | .contentType(MediaType.APPLICATION_JSON_VALUE) 88 | .content(body) 89 | .session(mockSession).locale(Locale.ENGLISH) 90 | .with(csrf())) 91 | .andDo(print()) 92 | .andExpect(status().is(200)) 93 | ; 94 | } 95 | 96 | @Test 97 | public void adminBlacklistDeleteSuccess() throws Exception { 98 | adminSession(); 99 | String blacklistUrl = "http://www.blacklistedsite.com"; 100 | String body = "{'uri':'" + blacklistUrl + "'}"; 101 | String result = 102 | mockMvc.perform( 103 | post("/api/blacklist") 104 | .contentType(MediaType.APPLICATION_JSON_VALUE) 105 | .content(body) 106 | .session(mockSession).locale(Locale.ENGLISH) 107 | .with(csrf())) 108 | .andDo(print()) 109 | .andExpect(status().is(200)) 110 | .andReturn().getResponse().getContentAsString(); 111 | ; 112 | BlacklistedSite site = mapper.readValue(result, BlacklistedSite.class); 113 | checkDeleteAccess("/api/blacklist/"+site.getId(), 200); 114 | } 115 | 116 | @Test 117 | public void blacklistRefusal() throws Exception { 118 | String blacklistUrl = "http://www.blacklistedsite.com"; 119 | adminSession(); 120 | String body = "{'uri':'" + blacklistUrl + "'}"; 121 | mockMvc.perform( 122 | post("/api/blacklist") 123 | .contentType(MediaType.APPLICATION_JSON_VALUE) 124 | .content(body) 125 | .session(mockSession).locale(Locale.ENGLISH) 126 | .with(csrf())) 127 | .andExpect(status().is(200)) 128 | ; 129 | //Now try to register a new client for that uri and get the black list error 130 | body = "{'client_uri':'" + blacklistUrl + "','redirect_uris':['" + blacklistUrl + "']}"; 131 | mockMvc.perform( 132 | post("/register") 133 | .contentType(MediaType.APPLICATION_JSON_VALUE) 134 | .content(body) 135 | .with(csrf())) 136 | .andDo(print()) 137 | .andExpect(status().is(400)) 138 | .andExpect(jsonPath("error", is("invalid_redirect_uri"))) 139 | ; 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/openid/connect/web/ClientApiAuthorizationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.openid.connect.web; 2 | 3 | import javax.transaction.Transactional; 4 | 5 | import org.junit.Test; 6 | import org.springframework.test.annotation.Rollback; 7 | 8 | @Transactional 9 | public class ClientApiAuthorizationTests extends ApiAuthorizationTestsBase { 10 | 11 | 12 | 13 | 14 | @Test 15 | public void adminGetApiClientsSuccess() throws Exception { 16 | adminSession(); 17 | checkGetAccess("/api/clients", 200); 18 | checkGetAccess("/api/clients/1", 200, "clientSecret", "secret"); 19 | } 20 | 21 | @Test 22 | @Rollback(true) 23 | public void adminPostApiClientsSuccess() throws Exception { 24 | adminSession(); 25 | checkPostAccess("/api/clients", 200); 26 | } 27 | 28 | @Test 29 | @Rollback(true) 30 | public void adminPutApiClientsSuccess() throws Exception { 31 | adminSession(); 32 | checkPutAccess("/api/clients/1", 200); 33 | } 34 | 35 | @Test 36 | @Rollback(true) 37 | public void adminDeleteApiClientsSuccess() throws Exception { 38 | adminSession(); 39 | checkDeleteAccess("/api/clients/1", 200); 40 | } 41 | 42 | @Test 43 | public void userGetApiClientsSuccess() throws Exception { 44 | userSession(); 45 | checkGetAccess("/api/clients", 200); 46 | checkGetAccessMissingValue("/api/clients/1", 200, "clientSecret"); 47 | } 48 | 49 | @Test 50 | public void userPostApiClientsUnauthorized() throws Exception { 51 | userSession(); 52 | checkPostAccess("/api/clients", 403); 53 | } 54 | 55 | @Test 56 | public void userPutApiClientsUnauthorized() throws Exception { 57 | userSession(); 58 | checkPutAccess("/api/clients/1", 403); 59 | } 60 | 61 | @Test 62 | public void userDeleteApiClientsUnauthorized() throws Exception { 63 | userSession(); 64 | checkDeleteAccess("/api/clients/1", 403); 65 | } 66 | 67 | @Test 68 | public void anonymousGetApiClientsUnauthenticated() throws Exception { 69 | checkGetAccess("/api/clients", 401); 70 | checkGetAccess("/api/clients/1", 401); 71 | } 72 | 73 | @Test 74 | public void anonymousPostApiClientsUnauthenticated() throws Exception { 75 | checkPostAccess("/api/clients", 401); 76 | } 77 | 78 | 79 | } 80 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/openid/connect/web/DataApiAuthorizationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.openid.connect.web; 2 | 3 | import javax.transaction.Transactional; 4 | 5 | import org.junit.Test; 6 | import org.springframework.test.annotation.Rollback; 7 | 8 | @Transactional 9 | public class DataApiAuthorizationTests extends ApiAuthorizationTestsBase { 10 | 11 | @Test 12 | public void adminGetApiDataUnauthorized() throws Exception { 13 | adminSession(); 14 | checkGetAccess("/api/data", 200); 15 | } 16 | 17 | @Test 18 | @Rollback(true) 19 | public void adminPostApiDataSuccess() throws Exception { 20 | adminSession(); 21 | checkPostAccess("/api/data", 200); 22 | } 23 | 24 | @Test 25 | public void userGetApiDataUnauthorized() throws Exception { 26 | userSession(); 27 | checkGetAccess("/api/data", 403); 28 | } 29 | 30 | @Test 31 | public void userPostApiDataUnauthorized() throws Exception { 32 | userSession(); 33 | checkPostAccess("/api/data", 403); 34 | } 35 | 36 | @Test 37 | public void anonymousGetApiDataUnauthenticated() throws Exception { 38 | checkGetAccess("/api/data", 401); 39 | } 40 | 41 | @Test 42 | public void anonymousPostApiDataUnauthenticated() throws Exception { 43 | checkPostAccess("/api/data", 401); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/openid/connect/web/StatsApiAuthorizationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.openid.connect.web; 2 | 3 | import javax.transaction.Transactional; 4 | 5 | import org.junit.Test; 6 | 7 | @Transactional 8 | public class StatsApiAuthorizationTests extends ApiAuthorizationTestsBase{ 9 | 10 | @Test 11 | public void adminGetApiStatsSuccess() throws Exception{ 12 | adminSession(); 13 | checkGetAccess("/api/stats/byclientid/1", 200); 14 | } 15 | 16 | @Test 17 | public void userGetApiStatsSuccess() throws Exception{ 18 | userSession(); 19 | checkGetAccess("/api/stats/byclientid/1", 200); 20 | } 21 | 22 | @Test 23 | public void anonymousGetApiStatsUnauthenticated() throws Exception{ 24 | checkGetAccess("/api/stats/byclientid/1", 401); 25 | } 26 | 27 | @Test 28 | public void adminGetApiStatsSummarySuccess() throws Exception{ 29 | adminSession(); 30 | checkGetAccess("/api/stats/summary", 200); 31 | } 32 | 33 | @Test 34 | public void userGetApiStatsSummarySuccess() throws Exception{ 35 | userSession(); 36 | checkGetAccess("/api/stats/summary", 200); 37 | } 38 | 39 | @Test 40 | public void anonymousGetApiStatsSummarySuccess() throws Exception{ 41 | checkGetAccess("/api/stats/summary", 200); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/openid/connect/web/UserInfoEndpointAuthorizationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.openid.connect.web; 2 | 3 | import static org.hamcrest.Matchers.is; 4 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 5 | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; 6 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; 7 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 8 | 9 | import javax.transaction.Transactional; 10 | 11 | import org.junit.Test; 12 | import org.mitre.openid.connect.web.UserInfoEndpoint; 13 | import org.mitre.springboot.oauth2.web.OAuthAuthorizationTestsBase; 14 | import org.springframework.http.HttpHeaders; 15 | import org.springframework.http.MediaType; 16 | 17 | @Transactional 18 | public class UserInfoEndpointAuthorizationTests extends OAuthAuthorizationTestsBase { 19 | 20 | @Test 21 | public void adminGetUserInfoEndpointSuccess() throws Exception { 22 | String accessToken = getAdminAccessToken(); 23 | mockMvc.perform( 24 | get("/"+UserInfoEndpoint.URL) 25 | .header(HttpHeaders.ACCEPT,MediaType.APPLICATION_JSON_VALUE) 26 | .header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken) 27 | ) 28 | .andExpect(status().is(200)) 29 | .andExpect(jsonPath("sub", is("90342.ASDFJWFA"))) 30 | .andDo(print()) 31 | .andReturn() 32 | .getResponse() 33 | ; 34 | } 35 | 36 | @Test 37 | public void userGetUserInfoEndpointSuccess() throws Exception { 38 | String accessToken = getUserAccessToken(); 39 | mockMvc.perform( 40 | get("/"+UserInfoEndpoint.URL) 41 | .header(HttpHeaders.ACCEPT,MediaType.APPLICATION_JSON_VALUE) 42 | .header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken) 43 | ) 44 | .andExpect(status().is(200)) 45 | .andExpect(jsonPath("sub", is("01921.FLANRJQW"))) 46 | .andDo(print()) 47 | .andReturn() 48 | .getResponse() 49 | ; 50 | } 51 | 52 | @Test 53 | public void anonymousGetUserInfoEndpointUnauthenticated() throws Exception { 54 | mockMvc.perform( 55 | get("/"+UserInfoEndpoint.URL)) 56 | .andExpect(status().is(401)) 57 | ; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/java/org/mitre/springboot/openid/connect/web/WhitelistApiAuthorizationTests.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.openid.connect.web; 2 | 3 | import javax.transaction.Transactional; 4 | 5 | import org.junit.Test; 6 | 7 | @Transactional 8 | public class WhitelistApiAuthorizationTests extends ApiAuthorizationTestsBase { 9 | 10 | @Test 11 | public void adminGetApiWhitelistSuccess() throws Exception { 12 | adminSession(); 13 | checkGetAccess("/api/whitelist", 200); 14 | //Note test setup data has no whitelist sites, considering adding for security testing 15 | //TODO test GET by ID 16 | //TODO test PUT by ID 17 | //TODO test DELETE by ID 18 | } 19 | 20 | @Test 21 | public void adminGetWhitelistByIdSuccess() throws Exception { 22 | adminSession(); 23 | checkGetAccess("/api/whitelist/1", 200); 24 | } 25 | 26 | @Test 27 | public void adminDeleteWhitelistByIdSuccess() throws Exception { 28 | adminSession(); 29 | checkGetAccess("/api/whitelist/1", 200); 30 | checkDeleteAccess("/api/whitelist/1", 200); 31 | checkGetAccess("/api/whitelist/1", 404); 32 | } 33 | 34 | 35 | @Test 36 | public void adminPostApiWhitelistSucess() throws Exception { 37 | adminSession(); 38 | checkPostAccess("/api/whitelist", 200); 39 | } 40 | 41 | @Test 42 | public void userGetApiWhitelistSucess() throws Exception { 43 | userSession(); 44 | checkGetAccess("/api/whitelist", 200); 45 | //TODO get by ID 46 | } 47 | 48 | @Test 49 | public void userPostApiWhitelistUnauthorized() throws Exception { 50 | userSession(); 51 | checkPostAccess("/api/whitelist", 403); 52 | } 53 | 54 | @Test 55 | public void userPutApiWhitelistUnauthorized() throws Exception { 56 | userSession(); 57 | checkPutAccess("/api/whitelist/1", 403); 58 | } 59 | 60 | @Test 61 | public void userDeleteApiWhitelistUnauthorized() throws Exception { 62 | userSession(); 63 | checkDeleteAccess("/api/whitelist/1", 403); 64 | } 65 | 66 | @Test 67 | public void anonymousGetApiWhitelistUnauthenticated() throws Exception { 68 | checkGetAccess("/api/whitelist", 401); 69 | } 70 | 71 | @Test 72 | public void anonymousPostApiWhitelistUnauthenticated() throws Exception { 73 | checkPostAccess("/api/whitelist", 401); 74 | } 75 | 76 | @Test 77 | public void anonymousPutApiWhitelistUnauthenticated() throws Exception { 78 | checkPutAccess("/api/whitelist/1", 401); 79 | } 80 | 81 | @Test 82 | public void anonymousDeleteApiWhitelistUnauthenticated() throws Exception { 83 | checkDeleteAccess("/api/whitelist/1", 401); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/resources/application-bcrypt.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:h2:mem:oauth_bcrypt 4 | 5 | openid: 6 | connect: 7 | crypto: 8 | password-encoder: 9 | clients: 10 | bcrypt: 11 | enabled: true 12 | strength: -1 13 | users: 14 | bcrypt: 15 | enabled: true 16 | strength: -1 17 | keystore: 18 | path: classpath:keystore.jwks 19 | signing: 20 | defaultSignerKeyId: rsa1 21 | defaultSigningAlgorithmName: RS256 22 | encrypt: 23 | defaultAlgorithm: RSA1_5 24 | defaultDecryptionKeyId: rsa1 25 | defaultEncryptionKeyId: rsa1 26 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/resources/application-endpoints-disabled.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | jpa: 3 | properties: 4 | eclipselink: 5 | logging: 6 | level: 7 | ROOT: INFO 8 | sql: INFO 9 | datasource: 10 | initialize: true 11 | schema: classpath:/db/tables/hsql_database_tables.sql,classpath:/db/tables/security-schema.sql 12 | data: 13 | 14 | logging: 15 | level: 16 | ROOT: INFO 17 | org.springframework.security: INFO 18 | server: 19 | port: 8080 20 | contextPath: / 21 | 22 | openid: 23 | connect: 24 | server: 25 | host: localhost 26 | issuer: http://${openid.connect.server.host}:${server.port}${server.contextPath} 27 | topbarTitle: OpenID Connect Server 28 | logoImageUrl: resources/images/openid_connect_small.png 29 | regTokenLifeTime: 172800 30 | scheduling: 31 | enabled: false 32 | crypto: 33 | keystore: 34 | path: classpath:keystore.jwks 35 | signing: 36 | defaultSignerKeyId: rsa1 37 | defaultSigningAlgorithmName: RS256 38 | encrypt: 39 | defaultAlgorithm: RSA1_5 40 | defaultDecryptionKeyId: rsa1 41 | defaultEncryptionKeyId: rsa1 42 | endpoints: 43 | api: 44 | whitelist.enabled: false 45 | approvedsite.enabled: false 46 | blacklist.enabled: false 47 | client.enabled: false 48 | data.enabled: false 49 | token.enabled: false 50 | scope.enabled: false 51 | stats.enabled: false 52 | oidc: 53 | dynamicclientregistration.enabled: false 54 | jwksetpublishing.enabled: false 55 | userinfo.enabled: false 56 | discovery.enabled: false 57 | # protectedresourceregistration.enabled: false 58 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/resources/application-pbkdf2.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:h2:mem:oauth_pbkdf2 4 | 5 | openid: 6 | connect: 7 | crypto: 8 | password-encoder: 9 | clients: 10 | pbkdf2: 11 | enabled: true 12 | secret: salt 13 | users: 14 | pbkdf2: 15 | enabled: true 16 | secret: salt 17 | keystore: 18 | path: classpath:keystore.jwks 19 | signing: 20 | defaultSignerKeyId: rsa1 21 | defaultSigningAlgorithmName: RS256 22 | encrypt: 23 | defaultAlgorithm: RSA1_5 24 | defaultDecryptionKeyId: rsa1 25 | defaultEncryptionKeyId: rsa1 26 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/resources/application-scrypt.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:h2:mem:oauth_scrypt 4 | 5 | openid: 6 | connect: 7 | crypto: 8 | password-encoder: 9 | clients: 10 | scrypt: 11 | enabled: true 12 | cpu-cost: 16384 13 | memory-cost: 8 14 | parallelization: 1 15 | key-lenght: 32 16 | salt-lenght: 64 17 | users: 18 | scrypt: 19 | enabled: true 20 | cpu-cost: 16384 21 | memory-cost: 8 22 | parallelization: 1 23 | key-lenght: 32 24 | salt-lenght: 64 25 | keystore: 26 | path: classpath:keystore.jwks 27 | signing: 28 | defaultSignerKeyId: rsa1 29 | defaultSigningAlgorithmName: RS256 30 | encrypt: 31 | defaultAlgorithm: RSA1_5 32 | defaultDecryptionKeyId: rsa1 33 | defaultEncryptionKeyId: rsa1 34 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/resources/application-standard.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:h2:mem:oauth_standard 4 | 5 | openid: 6 | connect: 7 | crypto: 8 | password-encoder: 9 | clients: 10 | standard: 11 | enabled: true 12 | secret: salt 13 | users: 14 | standard: 15 | enabled: true 16 | secret: salt 17 | keystore: 18 | path: classpath:keystore.jwks 19 | signing: 20 | defaultSignerKeyId: rsa1 21 | defaultSigningAlgorithmName: RS256 22 | encrypt: 23 | defaultAlgorithm: RSA1_5 24 | defaultDecryptionKeyId: rsa1 25 | defaultEncryptionKeyId: rsa1 26 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | jpa: 3 | properties: 4 | eclipselink: 5 | logging: 6 | level: 7 | ROOT: INFO 8 | sql: INFO 9 | datasource: 10 | initialize: true 11 | schema: classpath:/db/tables/hsql_database_tables.sql,classpath:/db/tables/security-schema.sql 12 | data: classpath:/db/test/data/users.sql,classpath:/db/test/data/clients.sql,classpath:/db/test/data/scopes.sql 13 | logging: 14 | level: 15 | ROOT: INFO 16 | org.springframework.security: DEBUG 17 | server: 18 | port: 8080 19 | contextPath: / 20 | 21 | openid: 22 | connect: 23 | server: 24 | host: localhost 25 | issuer: http://${openid.connect.server.host}:${server.port}${server.contextPath} 26 | topbarTitle: OpenID Connect Server 27 | logoImageUrl: resources/images/openid_connect_small.png 28 | regTokenLifeTime: 172800 29 | scheduling: 30 | enabled: false 31 | crypto: 32 | keystore: 33 | path: classpath:keystore.jwks 34 | signing: 35 | defaultSignerKeyId: rsa1 36 | defaultSigningAlgorithmName: RS256 37 | encrypt: 38 | defaultAlgorithm: RSA1_5 39 | defaultDecryptionKeyId: rsa1 40 | defaultEncryptionKeyId: rsa1 41 | endpoints: 42 | api: 43 | whitelist.enabled: true 44 | approvedsite.enabled: true 45 | blacklist.enabled: true 46 | client.enabled: true 47 | data.enabled: true 48 | token.enabled: true 49 | scope.enabled: true 50 | stats.enabled: true 51 | oidc: 52 | dynamicclientregistration.enabled: true 53 | jwksetpublishing.enabled: true 54 | userinfo.enabled: true 55 | discovery.enabled: true 56 | protectedresourceregistration.enabled: true 57 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/resources/db/test/data/scopes.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- Turn off autocommit and start a transaction so that we can use the temp tables 3 | -- 4 | 5 | SET AUTOCOMMIT FALSE; 6 | 7 | -- 8 | -- Insert scope information 9 | -- 10 | 11 | INSERT INTO system_scope (scope, description, icon, restricted, default_scope) VALUES 12 | ('openid', 'log in using your identity', 'user', false, true), 13 | ('profile', 'basic profile information', 'list-alt', false, true), 14 | ('email', 'email address', 'envelope', false, true), 15 | ('address', 'physical address', 'home', false, true), 16 | ('phone', 'telephone number', 'bell', false, true), 17 | ('offline_access', 'offline access', 'time', false, false); 18 | 19 | COMMIT; 20 | 21 | SET AUTOCOMMIT TRUE; -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/resources/db/test/data/users.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- Turn off autocommit and start a transaction so that we can use the temp tables 3 | -- 4 | 5 | SET AUTOCOMMIT FALSE; 6 | 7 | -- 8 | -- Insert user information. To add users to the HSQL database, edit things here. 9 | -- 10 | 11 | INSERT INTO users (username, password, enabled) VALUES 12 | ('admin','password',true), 13 | ('admin_bcrypt','$2a$10$MzY7AG/8Sf/mbpGz6fFlquD8ymaKsQI5Z0rvjxYP4KeENcrFnr7FO',true), 14 | ('admin_scrypt', '$e0801$4bV2x7jsYTttcqdCFfHAuWJDFYGJX3Rzi3Ih9PAIWFKsch3o0jtfN4HkJQCxsB+rYKAQr6Lq1BJOG9UastlAiQ==$gVrJsKBQe7vl/F9GEzxLRsYfxEYUukAvj84v3A2x/D8=', true), 15 | ('admin_standard', '9e2830557e2ac4f60bafddd6e572b37b373b6a09382fef11591927f52fef3fba96a59d2335f09193', true), 16 | ('admin_pbkdf2', '16d96430514b8fda9ad661bdce180f1d0617c29dd345b03538fa2112e9d3f356b2898b2ea5e00b77', true), 17 | ('user','password',true); 18 | 19 | 20 | INSERT INTO authorities (username, authority) VALUES 21 | ('admin','ROLE_ADMIN'), 22 | ('admin','ROLE_USER'), 23 | ('admin_bcrypt','ROLE_ADMIN'), 24 | ('admin_bcrypt','ROLE_USER'), 25 | ('admin_scrypt','ROLE_ADMIN'), 26 | ('admin_scrypt','ROLE_USER'), 27 | ('admin_standard','ROLE_ADMIN'), 28 | ('admin_standard','ROLE_USER'), 29 | ('admin_pbkdf2','ROLE_ADMIN'), 30 | ('admin_pbkdf2','ROLE_USER'), 31 | ('user','ROLE_USER'); 32 | 33 | -- By default, the username column here has to match the username column in the users table, above 34 | INSERT INTO user_info (sub, preferred_username, name, email, email_verified) VALUES 35 | ('90342.ASDFJWFA','admin','Demo Admin','admin@example.com', true), 36 | ('90343.ASDFJWFA','admin_bcrypt','Demo Admin','admin@example.com', true), 37 | ('90344.ASDFJWFA','admin_scrypt','Demo Admin','admin@example.com', true), 38 | ('90345.ASDFJWFA','admin_standard','Demo Admin','admin@example.com', true), 39 | ('90346.ASDFJWFA','admin_pbkdf2','Demo Admin','admin@example.com', true), 40 | ('01921.FLANRJQW','user','Demo User','user@example.com', true); 41 | 42 | -- 43 | -- Close the transaction and turn autocommit back on 44 | -- 45 | 46 | COMMIT; 47 | 48 | SET AUTOCOMMIT TRUE; 49 | 50 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-test/src/test/resources/keystore.jwks: -------------------------------------------------------------------------------- 1 | { 2 | "keys": [ 3 | { 4 | "alg": "RS256", 5 | "d": "PvBAngE3kkTnD3yDKo3wCvHJHm20kb9a0FVGLd0s2Y0E_3H2XnZC8-2zPhN6AQTjPhohSDCew20gzm76lyOvMqRiUP2Zpaopa1d2fGvNIQSdM07yKa6EivEYxqPQxa5esoZnexgnb9fom70I8n5OQRNQikwu-az26CsHX2zWMRodzSdN5CXHvb1PV09DmH8azTYwoMElPIqmcTfxiRw2Ov5ucmXXngKRFJgvfUgKd7v4ScBX7sQoQEjWEtt7ta0WvL3Ar5E1RAW4aHxuubZ6AtloxWCf17AAKw03dfP5RDm5TDmgm2B635ecJ7fTvneFmg8W_fdMTPRfBlCGNBp3wQ", 6 | "e": "AQAB", 7 | "n": "qt6yOiI_wCoCVlGO0MySsez0VkSqhPvDl3rfabOslx35mYEO-n4ABfIT5Gn2zN-CeIcOZ5ugAXvIIRWv5H55-tzjFazi5IKkOIMCiz5__MtsdxKCqGlZu2zt-BLpqTOAPiflNPpM3RUAlxKAhnYEqNha6-allPnFQupnW_eTYoyuzuedT7dSp90ry0ZcQDimntXWeaSbrYKCj9Rr9W1jn2uTowUuXaScKXTCjAmJVnsD75JNzQfa8DweklTyWQF-Y5Ky039I0VIu-0CIGhXY48GAFe2EFb8VpNhf07DP63p138RWQ1d3KPEM9mYJVpQC68j3wzDQYSljpLf9by7TGw", 8 | "kty": "RSA", 9 | "kid": "rsa1" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/README.md: -------------------------------------------------------------------------------- 1 | # OpenID Connect Spring Boot Thymeleaf UI 2 | --- 3 | 4 | 5 | ##Spring Boot Application Properties 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
Application property name (Configuration Source)requireddefaultdescription
MitreID OpenID Connect (ConfigurationPropertiesBean)
openid.connect.server.topbarTitleXshould match public URI for the server
openid.connect.server.logoImageUrlX
openid.connect.server.localeen
openid.connect.server.languageNamespacesmessages
Web UI Configuration (WebMvcConfig)
openid.connect.jsonMessageSource.baseDirectoryclasspath:/static/resources/js/locale/
45 | 46 | ### Sample minimal application.yml 47 | ```YAML 48 | openid: 49 | connect: 50 | server: 51 | topbarTitle: OpenID Connect Server 52 | logoImageUrl: resources/images/openid_connect_small.png 53 | jsonMessageSource: 54 | baseDirectory: classpath:/static/resources/js/locale/ 55 | 56 | ``` -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/build.gradle: -------------------------------------------------------------------------------- 1 | 2 | dependencies { 3 | 4 | // OpenID Connect 5 | implementation libs.springSecurityOauth2 6 | implementation libs.springBootStarterWeb 7 | implementation libs.springBootStarterSecurity 8 | implementation libs.mitreOpenIdConnectServer 9 | implementation libs.bouncyCastle 10 | 11 | runtime libs.springBootStarterThymeleaf 12 | runtime libs.thymeleafSpringSecurity 13 | 14 | } 15 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/gradle.properties: -------------------------------------------------------------------------------- 1 | description = Thymeleaf UI for spring boot autoconfiguration version of the OpenID Connect Server reference implementation at https://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/java/org/mitre/springboot/config/ui/StaticResourcesWebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.config.ui; 2 | 3 | import org.mitre.oauth2.web.CorsFilter; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.core.annotation.Order; 7 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 8 | import org.springframework.security.config.annotation.web.builders.WebSecurity; 9 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 10 | import org.springframework.security.config.http.SessionCreationPolicy; 11 | import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint; 12 | import org.springframework.security.web.context.SecurityContextPersistenceFilter; 13 | 14 | @Order(140) 15 | @Configuration 16 | public class StaticResourcesWebSecurityConfig extends WebSecurityConfigurerAdapter { 17 | @Autowired 18 | private Http403ForbiddenEntryPoint http403ForbiddenEntryPoint; 19 | 20 | @Override 21 | public void configure(WebSecurity web) throws Exception { 22 | web.ignoring().antMatchers("/resources/**"); 23 | } 24 | 25 | @Override 26 | protected void configure(HttpSecurity http) throws Exception { 27 | // @formatter:off 28 | http 29 | .requestMatchers() 30 | .antMatchers("/resources/**") 31 | .and() 32 | .authorizeRequests() 33 | .antMatchers("/resources/**").permitAll() 34 | .and() 35 | .exceptionHandling() 36 | .authenticationEntryPoint(http403ForbiddenEntryPoint) 37 | .and() 38 | .sessionManagement() 39 | .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) 40 | ; 41 | // @formatter:on 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/java/org/mitre/springboot/config/ui/UserLoginConfig.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.config.ui; 2 | 3 | import org.mitre.openid.connect.web.AuthenticationTimeStamper; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.core.annotation.Order; 7 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 8 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 9 | import org.springframework.security.web.util.matcher.AntPathRequestMatcher; 10 | 11 | @Order(600) 12 | @Configuration 13 | public class UserLoginConfig extends WebSecurityConfigurerAdapter { 14 | 15 | @Autowired 16 | private AuthenticationTimeStamper authenticationTimeStamper; 17 | 18 | @Override 19 | protected void configure(HttpSecurity http) throws Exception { 20 | // @formatter:off 21 | http 22 | .sessionManagement() 23 | .enableSessionUrlRewriting(false) 24 | .and() 25 | .csrf() 26 | .and() 27 | .formLogin() 28 | .loginPage("/login") 29 | .failureUrl("/login?error=failure") 30 | .successHandler(authenticationTimeStamper) 31 | .permitAll() 32 | .and() 33 | .authorizeRequests() 34 | .antMatchers("/**") 35 | .permitAll() 36 | .and() 37 | .logout() 38 | .logoutSuccessUrl("/login?logout") 39 | //TODO upgrade default logout UI this should be a POST with CSRF for safety 40 | .logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET")) 41 | .permitAll() 42 | .and() 43 | .anonymous() 44 | .and() 45 | .headers() 46 | .frameOptions().deny() 47 | 48 | ; 49 | // @formatter:on 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/java/org/mitre/springboot/config/ui/WebMvcConfig.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.config.ui; 2 | 3 | import java.util.Arrays; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | 7 | import org.mitre.openid.connect.config.JsonMessageSource; 8 | import org.mitre.openid.connect.config.UIConfiguration; 9 | import org.mitre.openid.connect.web.RootController; 10 | import org.mitre.openid.connect.web.ServerConfigInterceptor; 11 | import org.mitre.openid.connect.web.UserInfoInterceptor; 12 | import org.springframework.beans.factory.annotation.Value; 13 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 14 | import org.springframework.boot.context.properties.ConfigurationProperties; 15 | import org.springframework.context.annotation.Bean; 16 | import org.springframework.context.annotation.Configuration; 17 | import org.springframework.context.annotation.Import; 18 | import org.springframework.core.io.Resource; 19 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; 20 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 21 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 22 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; 23 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 24 | 25 | @Configuration 26 | @EnableWebMvc 27 | public class WebMvcConfig extends WebMvcConfigurerAdapter{ 28 | 29 | @Bean 30 | @ConditionalOnMissingBean(UserInfoInterceptor.class) 31 | public UserInfoInterceptor getUserInfoInterceptor(){ 32 | return new UserInfoInterceptor(); 33 | } 34 | 35 | @Bean 36 | @ConditionalOnMissingBean(ServerConfigInterceptor.class) 37 | public ServerConfigInterceptor getServerConfigInterceptor(){ 38 | return new ServerConfigInterceptor(); 39 | } 40 | 41 | @Bean 42 | @ConditionalOnMissingBean(JsonMessageSource.class) 43 | @ConfigurationProperties(prefix = "openid.connect.jsonMessageSource") 44 | public JsonMessageSource messageSource(@Value("classpath:/static/resources/js/locale/") 45 | final Resource baseDirectory, @Value("true") 46 | final Boolean useCodeAsDefaultMessage){ 47 | final JsonMessageSource jsonMessageSource = new JsonMessageSource(); 48 | jsonMessageSource.setBaseDirectory(baseDirectory); 49 | jsonMessageSource.setUseCodeAsDefaultMessage(useCodeAsDefaultMessage); 50 | return jsonMessageSource; 51 | } 52 | 53 | @Bean(name = "uiConfiguration") 54 | @ConfigurationProperties(prefix = "openid.connect.server.ui") 55 | @ConditionalOnMissingBean(UIConfiguration.class) 56 | public UIConfiguration configurationPropertiesBean(){ 57 | final UIConfiguration uiConfiguration = new UIConfiguration(); 58 | // @formatter:off 59 | final Set jsResources = new HashSet( 60 | Arrays.asList( 61 | "resources/js/client.js", 62 | "resources/js/grant.js", 63 | "resources/js/scope.js", 64 | "resources/js/whitelist.js", 65 | "resources/js/dynreg.js", 66 | "resources/js/rsreg.js", 67 | "resources/js/token.js", 68 | "resources/js/blacklist.js", 69 | "resources/js/profile.js" 70 | )); 71 | // @formatter:on 72 | 73 | uiConfiguration.setJsFiles(jsResources); 74 | return uiConfiguration; 75 | } 76 | 77 | @Override 78 | public void addInterceptors(final InterceptorRegistry registry){ 79 | registry.addInterceptor(getUserInfoInterceptor()); 80 | registry.addInterceptor(getServerConfigInterceptor()); 81 | } 82 | 83 | @Override 84 | public void addViewControllers(final ViewControllerRegistry registry){ 85 | registry.addViewController("/login").setViewName("login"); 86 | } 87 | 88 | @Override 89 | public void addResourceHandlers(final ResourceHandlerRegistry registry){ 90 | registry.addResourceHandler("/resources/**").addResourceLocations("classpath:/static/resources/"); 91 | } 92 | 93 | @Configuration 94 | @Import(RootController.class) 95 | public static class RootControllerConfiguration{ 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/bootstrap2/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tntconcept/openid-connect-server-spring-boot/b2214d6c0bdd4e227dd9440f080fd8419e97d28b/openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/bootstrap2/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/bootstrap2/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tntconcept/openid-connect-server-spring-boot/b2214d6c0bdd4e227dd9440f080fd8419e97d28b/openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/bootstrap2/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/css/bootstrap-sheet.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap modal sheet 3 | * 4 | * Author: Michaël Perrin 5 | * https://github.com/michaelperrin/bootstrap-modal-sheet 6 | */ 7 | 8 | .sheet form { 9 | margin: 0; 10 | } 11 | 12 | .sheet .form-actions { 13 | margin-top: 10px; 14 | margin-bottom: 0; 15 | padding: 10px 20px 10px; 16 | text-align: right; 17 | } 18 | 19 | .sheet { 20 | position: absolute; 21 | z-index: 1050; 22 | 23 | width: 600px; 24 | background: rgba(240, 240, 240, 0.9); 25 | border-color: #909090; 26 | border-style: solid; 27 | border-width: 0 1px 1px 1px; 28 | box-shadow: inset 0 15px 12px -10px rgba(0, 0, 0, 0.4), 0 5px 12px rgba(0, 0, 0, 0.4); 29 | padding-top: 15px; 30 | } 31 | 32 | .sheet.hide { 33 | display: none; 34 | } 35 | 36 | .sheet .sheet-body { 37 | padding-left: 15px; 38 | padding-right: 15px; 39 | } 40 | 41 | .sheet .sheet-footer { 42 | margin-top: 10px; 43 | margin-bottom: 0; 44 | padding: 10px 20px 10px; 45 | text-align: right; 46 | background-color: #f5f5f5; 47 | border-top: 1px solid #e5e5e5; 48 | } 49 | 50 | .sheet-backdrop { 51 | position: fixed; 52 | top: 0; 53 | right: 0; 54 | bottom: 0; 55 | left: 0; 56 | z-index: 1040; 57 | } 58 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/css/mitreid-connect-local.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Overlay this file to provide local style overrides. 3 | */ -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/css/mitreid-connect-responsive-local.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Overlay this file to provide local style overrides. 3 | */ -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/css/mitreid-connect-responsive.css: -------------------------------------------------------------------------------- 1 | /* size-responsive CSS to be loaded after bootstrap-responsive */ 2 | 3 | @media ( min-width : 768px) and (max-width: 979px) { 4 | .main { 5 | padding-top: 0px; 6 | } 7 | } 8 | 9 | @media ( max-width : 767px) { 10 | #footer { 11 | margin-left: -20px; 12 | margin-right: -20px; 13 | padding-left: 20px; 14 | padding-right: 20px; 15 | } 16 | } -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/css/mitreid-connect.css: -------------------------------------------------------------------------------- 1 | /* Stylesheet for the MITREid Connect server web application */ 2 | 3 | html,body { 4 | height: 100%; 5 | /* The html and body elements cannot have any padding or margin. */ 6 | } 7 | 8 | .sidebar-nav { 9 | padding: 9px 0; 10 | } 11 | 12 | h1,label { 13 | text-shadow: 1px 1px 1px #FFFFFF; 14 | } 15 | 16 | .navbar .brand { 17 | max-height: 20px; 18 | } 19 | 20 | .navbar .brand img { 21 | max-height: 24px; 22 | width: auto; 23 | position: relative; 24 | top: -2px; 25 | left: -6px; 26 | } 27 | 28 | /* login button */ 29 | 30 | .navbar #userButton, 31 | .navbar #loginButton { 32 | background-repeat: repeat-x; 33 | border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); 34 | color: #ffffff; 35 | text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); 36 | box-shadow: 0 3px 8px rgba(255, 255, 255, 0.125) inset; 37 | font-size: 0.9em; 38 | } 39 | 40 | .navbar #userButton { 41 | background-color: #006dcc; 42 | background-image: linear-gradient(to bottom, #0088cc, #0044cc); 43 | } 44 | .navbar #loginButton { 45 | background-color: #5bb75b; 46 | background-image: linear-gradient(to bottom, #62c462, #51a351); 47 | } 48 | 49 | .navbar #userButton:focus, .navbar #userButton:hover, 50 | .navbar #loginButton:focus, .navbar #loginButton:hover { 51 | color: #ffffff; 52 | background-position: 0 -15px; 53 | text-decoration: none; 54 | transition: background-position 0.1s linear 0s; 55 | } 56 | 57 | .navbar #userButton:focus, .navbar #userButton:hover { 58 | background-color: #0044cc; 59 | } 60 | .navbar #loginButton:focus, .navbar #loginButton:hover { 61 | background-color: #51a351; 62 | } 63 | 64 | .navbar #userButton:active, 65 | .navbar #loginButton:active { 66 | color: #ffffff; 67 | background-image: none; 68 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15) inset, 0 1px 2px rgba(0, 0, 0, 0.05); 69 | outline: 0 none; 70 | } 71 | 72 | .navbar #userButton:active { 73 | background-color: #0044cc; 74 | } 75 | 76 | .navbar #loginButton:active { 77 | background-color: #51a351; 78 | } 79 | 80 | .navbar #userButton .caret { 81 | border-bottom-color: #ffffff; 82 | border-top-color: #ffffff; 83 | } 84 | 85 | /* Wrapper for page content to push down footer */ 86 | #wrap { 87 | min-height: 100%; 88 | height: auto !important; 89 | height: 100%; 90 | /* Negative indent footer by its height */ 91 | margin: 0 auto -60px; 92 | } 93 | 94 | /* Set the fixed height of the footer here */ 95 | #push,#footer { 96 | min-height: 60px; 97 | } 98 | 99 | #footer { 100 | background-color: #f5f5f5; 101 | } 102 | 103 | .main { 104 | padding-top: 60px; 105 | } 106 | 107 | .credit { 108 | margin: 20px 0; 109 | } 110 | 111 | .inputError { 112 | border: 1px solid #b94a48 !important; 113 | } 114 | 115 | /* Fix for wonky forms */ 116 | 117 | .input-append.input-block-level, 118 | .input-prepend.input-block-level { 119 | display: table; 120 | } 121 | 122 | .input-append.input-block-level .add-on, 123 | .input-prepend.input-block-level .add-on { 124 | display: table-cell; 125 | width: 1%; /* remove this if you want default bootstrap button width */ 126 | } 127 | 128 | .input-append.input-block-level > input, 129 | .input-prepend.input-block-level > input { 130 | box-sizing: border-box; /* use bootstrap mixin or include vendor variants */ 131 | -moz-box-sizing: border-box; /* for Firefox */ 132 | min-height: inherit; 133 | width: 100%; 134 | } 135 | 136 | /* This block applies to Chrome only */ 137 | @media screen and (-webkit-min-device-pixel-ratio:0) { 138 | .input-append.input-block-level > input, 139 | .input-prepend.input-block-level > input { 140 | display: table; /* table-cell is not working well in Chrome for small widths */ 141 | } 142 | } 143 | 144 | .input-append.input-block-level > input { 145 | border-right: 0; 146 | } 147 | 148 | .input-prepend.input-block-level > input { 149 | border-left: 0; 150 | } 151 | 152 | .label-matched, .badge-matched { 153 | background-color: #D1D1FF; 154 | } 155 | 156 | /* get rid of extraneous outline on tabs */ 157 | 158 | .nav-tabs > .active > a, .nav-tabs > .active > a:hover { 159 | outline: 0; 160 | } 161 | 162 | .control-group .controls div { 163 | display: block; 164 | } 165 | 166 | .control-group .controls div { 167 | padding-top: 5px; 168 | margin-bottom: 5px; 169 | } 170 | 171 | .control-group .controls div label.checkbox, 172 | .control-group .controls div label.radio { 173 | display: inline-block; 174 | padding: 0 5px 0 5px; 175 | line-height: 20px; 176 | } 177 | 178 | .control-group .controls div input[type=checkbox], 179 | .control-group .controls div input[type=radio] { 180 | line-height: 20px; 181 | vertical-align: middle; 182 | margin: 0; 183 | } 184 | 185 | /* User profile claims alignment */ 186 | .user-profile dd, .user-profile dt { 187 | height: 20px; 188 | } 189 | 190 | /* Client table images */ 191 | .client-logo { 192 | max-width: 64px; 193 | max-height: 64px 194 | } 195 | 196 | /* Modal and sheet fight for the same z-index otherwise */ 197 | .modal-backdrop { 198 | z-index: 2040; 199 | } 200 | .modal { 201 | z-index: 2050; 202 | } 203 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/images/heart_mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tntconcept/openid-connect-server-spring-boot/b2214d6c0bdd4e227dd9440f080fd8419e97d28b/openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/images/heart_mode.png -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/images/heart_mode@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tntconcept/openid-connect-server-spring-boot/b2214d6c0bdd4e227dd9440f080fd8419e97d28b/openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/images/heart_mode@2x.png -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/images/logo_placeholder.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tntconcept/openid-connect-server-spring-boot/b2214d6c0bdd4e227dd9440f080fd8419e97d28b/openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/images/logo_placeholder.gif -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/images/mitreid-connect.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tntconcept/openid-connect-server-spring-boot/b2214d6c0bdd4e227dd9440f080fd8419e97d28b/openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/images/mitreid-connect.ico -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/images/openid_connect_large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tntconcept/openid-connect-server-spring-boot/b2214d6c0bdd4e227dd9440f080fd8419e97d28b/openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/images/openid_connect_large.png -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/images/openid_connect_large@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tntconcept/openid-connect-server-spring-boot/b2214d6c0bdd4e227dd9440f080fd8419e97d28b/openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/images/openid_connect_large@2x.png -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/images/openid_connect_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tntconcept/openid-connect-server-spring-boot/b2214d6c0bdd4e227dd9440f080fd8419e97d28b/openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/images/openid_connect_small.png -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/images/openid_connect_small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tntconcept/openid-connect-server-spring-boot/b2214d6c0bdd4e227dd9440f080fd8419e97d28b/openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/images/openid_connect_small@2x.png -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/js/profile.js: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2017 The MITRE Corporation 3 | * and the MIT Internet Trust Consortium 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | *******************************************************************************/ 17 | ui.routes.push({ 18 | path: "user/profile", 19 | name: "profile", 20 | callback: function() { 21 | 22 | this.breadCrumbView.collection.reset(); 23 | this.breadCrumbView.collection.add([{ 24 | text: $.t('admin.home'), 25 | href: "" 26 | }, { 27 | text: $.t('admin.user-profile.show'), 28 | href: "manage/#user/profile" 29 | }]); 30 | 31 | this.updateSidebar('user/profile'); 32 | 33 | var view = new UserProfileView({ 34 | model: getUserInfo() 35 | }); 36 | $('#content').html(view.render().el); 37 | 38 | setPageTitle($.t('admin.user-profile.show')); 39 | 40 | } 41 | }); -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/template/blacklist.html: -------------------------------------------------------------------------------- 1 | 17 | 18 | 57 | 58 | 70 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/template/grant.html: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 54 | 55 | 89 | 90 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/static/resources/template/whitelist.html: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 43 | 44 | 71 | 72 | 109 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/about.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 |
11 |
12 | 13 | 14 |
15 | 16 |
17 | 18 | 19 | 20 |
21 | 22 | 23 |
24 |
25 |
26 |
27 |
28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/contact.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 |
11 |
12 | 13 |
14 |
15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 |
23 |
24 |
25 |
26 |
27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/deviceApproved.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 |
9 | 10 |
11 |

12 | XXX 13 |

14 |
15 |
16 | 17 |
18 |
19 |
20 |
21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 |
11 |
12 |
13 |
14 |

15 | 16 |

17 |

18 | 19 |

20 |

21 |
22 |
23 |
24 |
25 |
26 |
27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/error.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> 2 | <%@page import="org.springframework.http.HttpStatus"%> 3 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 4 | <%@ taglib prefix="o" tagdir="/WEB-INF/tags"%> 5 | <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> 6 | <%@ taglib prefix="security" uri="http://www.springframework.org/security/tags"%> 7 | <%@page import="org.springframework.security.oauth2.common.exceptions.OAuth2Exception"%> 8 | <% 9 | 10 | if (request.getAttribute("error") != null && request.getAttribute("error") instanceof OAuth2Exception) { 11 | request.setAttribute("errorCode", ((OAuth2Exception)request.getAttribute("error")).getOAuth2ErrorCode()); 12 | request.setAttribute("message", ((OAuth2Exception)request.getAttribute("error")).getMessage()); 13 | } else if (request.getAttribute("javax.servlet.error.exception") != null) { 14 | Throwable t = (Throwable)request.getAttribute("javax.servlet.error.exception"); 15 | request.setAttribute("errorCode", t.getClass().getSimpleName() + " (" + request.getAttribute("javax.servlet.error.status_code") + ")"); 16 | request.setAttribute("message", t.getMessage()); 17 | } else if (request.getAttribute("javax.servlet.error.status_code") != null) { 18 | Integer code = (Integer)request.getAttribute("javax.servlet.error.status_code"); 19 | HttpStatus status = HttpStatus.valueOf(code); 20 | request.setAttribute("errorCode", status.toString() + " " + status.getReasonPhrase()); 21 | request.setAttribute("message", request.getAttribute("javax.servlet.error.message")); 22 | } else { 23 | request.setAttribute("errorCode", "Server error"); 24 | request.setAttribute("message", "See the logs for details"); 25 | } 26 | 27 | %> 28 | 29 | 30 | 31 |
32 |
33 |
34 |
35 |

36 | 37 |

38 |

39 | 40 |

41 |

42 | 43 |
44 | 45 |
46 |
47 |
48 | 49 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/fragments/aboutContent.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

7 |

8 |
9 | 10 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/fragments/actionmenu.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
    6 | 7 | 8 |
  • 9 |
  • 10 |
  • 11 |
  • 12 |
  • 13 |
    14 | 15 |
  • 16 |
  • 17 |
  • 18 |
  • 19 | 20 |
  • 21 |
  • 22 |
23 | 24 | 25 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/fragments/contactContent.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

7 |

8 |
9 | 10 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/fragments/copyright.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HEART Mode 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/fragments/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 15 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 36 | 37 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/fragments/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/fragments/landingPageAbout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |

About

6 |

7 |
8 | 9 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/fragments/landingPageContact.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |

Contact

6 |

7 |
8 | 9 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/fragments/landingPageStats.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |

6 | 7 |

8 | 9 |

10 | 11 | 12 | 13 |

14 | 15 | 31 |
32 | 33 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/fragments/landingPageWelcome.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 | 8 |
9 |

10 |

11 |
12 |
13 |
14 | 15 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/fragments/sidebar.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 13 |
14 |
15 | 16 |
17 | 18 |
19 |
20 | 21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/fragments/statsContent.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

Current Statistics

7 | 8 |

There have been 9 | X user[[${statsSummary['userCount'] == 1 ? '' : 's'}]] of this system who have logged in to 10 | X total site[[${statsSummary["clientCount"] == 1 ? "" : "s"}]], for a total of 11 | X site approval[[${statsSummary["approvalCount"] == 1 ? "" : "s"}]].

12 |
13 | 14 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/fragments/topbar.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 44 | 45 |
46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 |
9 |
10 | 11 |
12 |
13 | 14 |
15 | 16 |
17 |
18 | 19 |
20 |
21 | 22 |
23 | 24 |
25 |
26 | 27 |
28 |
29 | 30 |
31 |
32 | 33 |
34 |
35 |
36 |
37 |
38 | 39 | 40 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 22 | 23 | 24 |
25 | 26 |

27 |
28 | 29 |
30 |
31 |
33 |
34 |
35 | 36 | 37 |
38 |
39 |
40 |
41 | 42 | 43 |
44 |
45 |
46 | 47 | 48 |
49 | 50 |
51 |
52 |
53 |
54 |
55 | 56 | 57 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/manage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | 20 | 21 |
22 |
23 | 24 |
25 |
26 | 27 |
28 |
29 |

30 |

31 |
32 |
33 |
34 |
35 |

36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | 48 | 49 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/requestUserCode.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 |
9 | 10 |
11 |

12 | 13 | 14 |
15 |
16 |
17 |
18 |
19 |
20 | 21 |
22 |
23 |
24 | 25 |
26 |
27 | 28 |
29 |
30 | 31 | 32 |
33 |
34 | 35 | 36 | 37 |
38 |
39 |
40 |
41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /openid-connect-server-spring-boot-ui-thymeleaf/src/main/resources/templates/stats.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 |
9 |
10 | 11 |
12 |
13 | 14 |
15 |
16 |
17 |
18 |
19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./gradlew uploadArchives -i -s 4 | RETVAL=$? 5 | 6 | if [ $RETVAL -eq 0 ]; then 7 | echo 'Artifacts published' 8 | else 9 | echo 'Publish failed.' 10 | return 1 11 | fi -------------------------------------------------------------------------------- /samples/default/README.md: -------------------------------------------------------------------------------- 1 | # OpenID Connect Spring Boot - Default Sample 2 | --- 3 | 4 | A Spring Boot Application configured to mimic the default [MITREid OpenID Connect WebApp](https://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server/tree/master/openid-connect-server-webapp) meant for maven and gradle overlay projects. 5 | 6 | After running the app you can simulate a remote client's OIDC authorize redirect flow (username: user, password:password) with the call: 7 | 8 | [http://localhost:8080/authorize?response_type=code token id_token&client_id=client&redirect_uri=http://localhost:8080/&scope=openid profile email&state=randomstate&nonce=randomnonce](http://localhost:8080/authorize?response_type=code token id_token&client_id=client&redirect_uri=http://localhost:8080/&scope=openid profile email&state=randomstate&nonce=randomnonce) 9 | 10 | -------------------------------------------------------------------------------- /samples/default/build.gradle: -------------------------------------------------------------------------------- 1 | apply from:"dependencies.gradle" 2 | 3 | apply plugin: 'java' 4 | apply plugin: 'eclipse' 5 | apply plugin: 'idea' 6 | apply plugin: 'org.springframework.boot' 7 | 8 | buildscript { 9 | ext { 10 | springBootVersion = "1.5.21.RELEASE" 11 | } 12 | repositories { 13 | mavenLocal() 14 | mavenCentral() 15 | } 16 | dependencies { 17 | classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 18 | } 19 | } 20 | 21 | repositories { 22 | mavenLocal() 23 | mavenCentral() 24 | maven { 25 | url =uri("https://maven.pkg.github.com/autentia/openid-connect-server-spring-boot") 26 | credentials { 27 | username = githubAutentiaUsername 28 | password = githubAutentiaToken 29 | } 30 | } 31 | } 32 | 33 | 34 | dependencies { 35 | compile libs.openIdConnectSpringBootConfig 36 | compile libs.openIdConnectSpringBootUI 37 | 38 | runtimeOnly libs.h2Database 39 | } 40 | 41 | uploadArchives.enabled = false -------------------------------------------------------------------------------- /samples/default/dependencies.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | h2DatabaseVersion = "1.4.192" 3 | openIdConnectSpringBootVersion = "0.1.6-SNAPSHOT" 4 | 5 | 6 | libs = [ 7 | openIdConnectSpringBootConfig : "net.simpledynamics:openid-connect-server-spring-boot-config:${openIdConnectSpringBootVersion}", 8 | openIdConnectSpringBootUI : "net.simpledynamics:openid-connect-server-spring-boot-ui-thymeleaf:${openIdConnectSpringBootVersion}", 9 | h2Database : "com.h2database:h2:${h2DatabaseVersion}" 10 | ] 11 | } -------------------------------------------------------------------------------- /samples/default/gradle.properties: -------------------------------------------------------------------------------- 1 | description = A Spring Boot Application configured to mimic the default MITREid OpenID Connect WebApp meant for maven and gradle overlay projects. -------------------------------------------------------------------------------- /samples/default/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tntconcept/openid-connect-server-spring-boot/b2214d6c0bdd4e227dd9440f080fd8419e97d28b/samples/default/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/default/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/default/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS="-Xmx64m" 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /samples/default/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "default" -------------------------------------------------------------------------------- /samples/default/src/main/java/org/mitre/springboot/samples/DefaultApplication.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.samples; 2 | 3 | import org.mitre.oauth2.service.OAuth2TokenEntityService; 4 | import org.mitre.oauth2.service.impl.DefaultOAuth2ProviderTokenService; 5 | import org.mitre.springboot.config.annotation.EnableOpenIDConnectServer; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.context.annotation.Primary; 12 | 13 | @SpringBootApplication 14 | @EnableOpenIDConnectServer 15 | public class DefaultApplication { 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(DefaultApplication.class, args); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /samples/default/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | initialize: true 4 | schema: classpath:/db/tables/hsql_database_tables.sql,classpath:/db/tables/security-schema.sql 5 | data: classpath:/db/users.sql,classpath:/db/clients.sql,classpath:/db/scopes.sql 6 | logging: 7 | level: 8 | ROOT: INFO 9 | org.springframework.security: INFO 10 | 11 | openid: 12 | connect: 13 | server: 14 | issuer: http://localhost:8080/ 15 | topbarTitle: OpenID Connect Server 16 | logoImageUrl: resources/images/openid_connect_small.png 17 | crypto: 18 | keystore: 19 | path: classpath:keystore.jwks 20 | signing: 21 | defaultSignerKeyId: rsa1 22 | defaultSigningAlgorithmName: RS256 23 | encrypt: 24 | defaultAlgorithm: RSA1_5 25 | defaultDecryptionKeyId: rsa1 26 | defaultEncryptionKeyId: rsa1 -------------------------------------------------------------------------------- /samples/default/src/main/resources/db/clients.sql: -------------------------------------------------------------------------------- 1 | 2 | -- 3 | -- Insert demo client information 4 | -- 5 | 6 | INSERT INTO client_details (client_id, client_secret, client_name, dynamically_registered, refresh_token_validity_seconds, access_token_validity_seconds, id_token_validity_seconds, allow_introspection) VALUES 7 | ('client', 'secret', 'Test Client', false, null, 3600, 600, true); 8 | select @a := scope_identity(); 9 | 10 | INSERT INTO client_scope (owner_id, scope) VALUES 11 | (@a, 'openid'), 12 | (@a, 'profile'), 13 | (@a, 'email'), 14 | (@a, 'address'), 15 | (@a, 'phone'), 16 | (@a, 'offline_access'); 17 | 18 | INSERT INTO client_redirect_uri (owner_id, redirect_uri) VALUES 19 | (@a, 'http://localhost/'), 20 | (@a, 'http://localhost:8080/'); 21 | 22 | INSERT INTO client_grant_type (owner_id, grant_type) VALUES 23 | (@a, 'authorization_code'), 24 | (@a, 'urn:ietf:params:oauth:grant_type:redelegate'), 25 | (@a, 'implicit'), 26 | (@a, 'refresh_token'); -------------------------------------------------------------------------------- /samples/default/src/main/resources/db/scopes.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- Insert demo scope information 3 | -- 4 | 5 | INSERT INTO system_scope (scope, description, icon, restricted, default_scope) VALUES 6 | ('openid', 'log in using your identity', 'user', false, true), 7 | ('profile', 'basic profile information', 'list-alt', false, true), 8 | ('email', 'email address', 'envelope', false, true), 9 | ('address', 'physical address', 'home', false, true), 10 | ('phone', 'telephone number', 'bell', false, true), 11 | ('offline_access', 'offline access', 'time', false, false); -------------------------------------------------------------------------------- /samples/default/src/main/resources/db/users.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- Insert demo user information. To add users to the H2 database, edit things here. 3 | -- 4 | 5 | INSERT INTO users (username, password, enabled) VALUES 6 | ('admin','password',true), 7 | ('user','password',true); 8 | 9 | 10 | INSERT INTO authorities (username, authority) VALUES 11 | ('admin','ROLE_ADMIN'), 12 | ('admin','ROLE_USER'), 13 | ('user','ROLE_USER'); 14 | 15 | -- By default, the username column here has to match the username column in the users table, above 16 | INSERT INTO user_info (sub, preferred_username, name, email, email_verified) VALUES 17 | ('90342.ASDFJWFA','admin','Demo Admin','admin@example.com', true), 18 | ('01921.FLANRJQW','user','Demo User','user@example.com', true); -------------------------------------------------------------------------------- /samples/default/src/main/resources/keystore.jwks: -------------------------------------------------------------------------------- 1 | { 2 | "keys": [ 3 | { 4 | "alg": "RS256", 5 | "d": "PvBAngE3kkTnD3yDKo3wCvHJHm20kb9a0FVGLd0s2Y0E_3H2XnZC8-2zPhN6AQTjPhohSDCew20gzm76lyOvMqRiUP2Zpaopa1d2fGvNIQSdM07yKa6EivEYxqPQxa5esoZnexgnb9fom70I8n5OQRNQikwu-az26CsHX2zWMRodzSdN5CXHvb1PV09DmH8azTYwoMElPIqmcTfxiRw2Ov5ucmXXngKRFJgvfUgKd7v4ScBX7sQoQEjWEtt7ta0WvL3Ar5E1RAW4aHxuubZ6AtloxWCf17AAKw03dfP5RDm5TDmgm2B635ecJ7fTvneFmg8W_fdMTPRfBlCGNBp3wQ", 6 | "e": "AQAB", 7 | "n": "qt6yOiI_wCoCVlGO0MySsez0VkSqhPvDl3rfabOslx35mYEO-n4ABfIT5Gn2zN-CeIcOZ5ugAXvIIRWv5H55-tzjFazi5IKkOIMCiz5__MtsdxKCqGlZu2zt-BLpqTOAPiflNPpM3RUAlxKAhnYEqNha6-allPnFQupnW_eTYoyuzuedT7dSp90ry0ZcQDimntXWeaSbrYKCj9Rr9W1jn2uTowUuXaScKXTCjAmJVnsD75JNzQfa8DweklTyWQF-Y5Ky039I0VIu-0CIGhXY48GAFe2EFb8VpNhf07DP63p138RWQ1d3KPEM9mYJVpQC68j3wzDQYSljpLf9by7TGw", 8 | "kty": "RSA", 9 | "kid": "rsa1" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /samples/simple-ui/README.md: -------------------------------------------------------------------------------- 1 | # OpenID Connect Spring Boot - Simple UI Sample 2 | --- 3 | 4 | A sample that does not include the stock MITREid OpenID Connect administration screens and APIs. Only the login, logout and authorize flows are enabled, making this a simple OIDC SSO server only. 5 | 6 | It is intended to show the separation of UI from the OIDC and OAuth 2.0 endpoints, and how to disable undesired features. 7 | 8 | The user client approval step is also skipped by adding the client and scopes to client whitelist table. 9 | 10 | After running the app you can simulate a remote client's OIDC authorize redirect flow (username: user, password:password) with the call: 11 | 12 | [http://localhost:8080/authorize?response_type=code token id_token&client_id=client&redirect_uri=http://localhost:8080/sampleclient&scope=openid profile email&state=randomstate&nonce=randomnonce](http://localhost:8080/authorize?response_type=code token id_token&client_id=client&redirect_uri=http://localhost:8080/sampleclient&scope=openid profile email&state=randomstate&nonce=randomnonce) 13 | 14 | **This configuration is not meant for actual production use.** 15 | 16 | At the very least you should create your own JKWS file, plug into a real database, and have method of managing users and client definitions etc. 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /samples/simple-ui/build.gradle: -------------------------------------------------------------------------------- 1 | apply from:"dependencies.gradle" 2 | 3 | apply plugin: 'java' 4 | apply plugin: 'eclipse' 5 | apply plugin: 'idea' 6 | apply plugin: 'org.springframework.boot' 7 | 8 | 9 | buildscript { 10 | ext { 11 | springBootVersion = "1.5.21.RELEASE" 12 | } 13 | repositories { 14 | mavenLocal() 15 | mavenCentral() 16 | } 17 | dependencies { 18 | classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 19 | } 20 | } 21 | 22 | repositories { 23 | mavenLocal() 24 | mavenCentral() 25 | maven { 26 | url =uri("https://maven.pkg.github.com/autentia/openid-connect-server-spring-boot") 27 | credentials { 28 | username = githubAutentiaUsername 29 | password = githubAutentiaToken 30 | } 31 | } 32 | } 33 | 34 | dependencies { 35 | compile libs.openIdConnectSpringBootConfig 36 | compile libs.openIdConnectSpringBootUI 37 | 38 | runtimeOnly libs.h2Database 39 | } 40 | 41 | uploadArchives.enabled = false -------------------------------------------------------------------------------- /samples/simple-ui/dependencies.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | h2DatabaseVersion = "1.4.192" 3 | openIdConnectSpringBootVersion = "0.1.6-SNAPSHOT" 4 | 5 | 6 | libs = [ 7 | openIdConnectSpringBootConfig : "net.simpledynamics:openid-connect-server-spring-boot-config:${openIdConnectSpringBootVersion}", 8 | openIdConnectSpringBootUI : "net.simpledynamics:openid-connect-server-spring-boot-ui-thymeleaf:${openIdConnectSpringBootVersion}", 9 | h2Database : "com.h2database:h2:${h2DatabaseVersion}" 10 | ] 11 | } -------------------------------------------------------------------------------- /samples/simple-ui/gradle.properties: -------------------------------------------------------------------------------- 1 | description = A Spring Boot Application MITREid OpenID Connect WebApp with minimal UI. -------------------------------------------------------------------------------- /samples/simple-ui/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tntconcept/openid-connect-server-spring-boot/b2214d6c0bdd4e227dd9440f080fd8419e97d28b/samples/simple-ui/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/simple-ui/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /samples/simple-ui/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS="-Xmx64m" 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /samples/simple-ui/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "simple-ui" -------------------------------------------------------------------------------- /samples/simple-ui/src/main/java/org/mitre/springboot/samples/SimpleUIApplication.java: -------------------------------------------------------------------------------- 1 | package org.mitre.springboot.samples; 2 | 3 | import org.mitre.openid.connect.web.AuthenticationTimeStamper; 4 | import org.mitre.springboot.config.annotation.EnableOpenIDConnectServer; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 10 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 11 | import org.springframework.security.web.context.SecurityContextPersistenceFilter; 12 | import org.springframework.web.filter.CorsFilter; 13 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; 14 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 15 | 16 | @SpringBootApplication 17 | @EnableOpenIDConnectServer 18 | public class SimpleUIApplication { 19 | 20 | public static void main(String[] args) { 21 | SpringApplication.run(SimpleUIApplication.class, args); 22 | } 23 | 24 | @Configuration 25 | public static class LoginConfiguration extends WebSecurityConfigurerAdapter { 26 | 27 | @Autowired 28 | private CorsFilter corsFilter; 29 | 30 | @Autowired 31 | private AuthenticationTimeStamper authenticationTimeStamper; 32 | 33 | @Override 34 | protected void configure(HttpSecurity http) throws Exception { 35 | // @formatter:off 36 | http 37 | .sessionManagement() 38 | .enableSessionUrlRewriting(false) 39 | .and() 40 | .csrf() 41 | .and() 42 | .formLogin() 43 | .loginPage("/session") 44 | .loginProcessingUrl("/login") 45 | .successHandler(authenticationTimeStamper) 46 | .failureUrl("/session?error") 47 | .permitAll() 48 | .and() 49 | .authorizeRequests() 50 | .antMatchers("/**") 51 | .permitAll() 52 | .and() 53 | .addFilterBefore(corsFilter, SecurityContextPersistenceFilter.class) 54 | .logout() 55 | .logoutSuccessUrl("/session?logout") 56 | .permitAll() 57 | .and() 58 | .exceptionHandling().accessDeniedPage("/session?denied") //in this simple case usually due to a InvalidCsrfTokenException after session timeout 59 | .and() 60 | .anonymous() 61 | .and() 62 | .headers() 63 | .frameOptions().deny() 64 | ; 65 | // @formatter:on 66 | } 67 | 68 | } 69 | 70 | @Configuration 71 | public static class WebMvcConfiguration extends WebMvcConfigurerAdapter { 72 | 73 | @Override 74 | public void addViewControllers(ViewControllerRegistry registry) { 75 | registry.addViewController("/session").setViewName("session"); 76 | registry.addViewController("/sampleclient").setViewName("sampleclient"); 77 | } 78 | 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /samples/simple-ui/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | initialize: true 4 | schema: classpath:/db/tables/hsql_database_tables.sql,classpath:/db/tables/security-schema.sql 5 | data: classpath:/db/users.sql,classpath:/db/clients.sql,classpath:/db/scopes.sql 6 | logging: 7 | level: 8 | ROOT: INFO 9 | org.springframework.security: INFO 10 | 11 | openid: 12 | connect: 13 | server: 14 | issuer: http://localhost:8080/ 15 | topbarTitle: OpenID Connect Server 16 | crypto: 17 | keystore: 18 | path: classpath:keystore.jwks 19 | signing: 20 | defaultSignerKeyId: rsa1 21 | defaultSigningAlgorithmName: RS256 22 | encrypt: 23 | defaultAlgorithm: RSA1_5 24 | defaultDecryptionKeyId: rsa1 25 | defaultEncryptionKeyId: rsa1 26 | endpoints: 27 | api: 28 | whitelist.enabled: false 29 | approvedsite.enabled: false 30 | blacklist.enabled: false 31 | client.enabled: false 32 | data.enabled: false 33 | token.enabled: false 34 | scope.enabled: false 35 | stats.enabled: false 36 | oidc: 37 | dynamicclientregistration.enabled: false 38 | jwksetpublishing.enabled: true 39 | userinfo.enabled: true 40 | discovery.enabled: true 41 | protectedresourceregistration.enabled: true 42 | -------------------------------------------------------------------------------- /samples/simple-ui/src/main/resources/db/clients.sql: -------------------------------------------------------------------------------- 1 | 2 | -- 3 | -- Insert demo client information 4 | -- 5 | 6 | INSERT INTO client_details (client_id, client_secret, client_name, dynamically_registered, refresh_token_validity_seconds, access_token_validity_seconds, id_token_validity_seconds, allow_introspection) VALUES 7 | ('client', 'secret', 'Test Client', false, null, 3600, 600, true); 8 | select @a := scope_identity(); 9 | 10 | INSERT INTO client_scope (owner_id, scope) VALUES 11 | (@a, 'openid'), 12 | (@a, 'profile'), 13 | (@a, 'email'), 14 | (@a, 'address'), 15 | (@a, 'phone'), 16 | (@a, 'offline_access'); 17 | 18 | INSERT INTO client_redirect_uri (owner_id, redirect_uri) VALUES 19 | (@a, 'http://localhost/'), 20 | (@a, 'http://localhost:8080/'), 21 | (@a, 'http://localhost:8080/sampleclient'); 22 | 23 | INSERT INTO client_grant_type (owner_id, grant_type) VALUES 24 | (@a, 'authorization_code'), 25 | (@a, 'urn:ietf:params:oauth:grant_type:redelegate'), 26 | (@a, 'implicit'), 27 | (@a, 'refresh_token'); 28 | 29 | --- Whitelist the client 30 | INSERT INTO whitelisted_site(client_id, creator_user_id) VALUES 31 | ('client','system'); 32 | 33 | select @whitelisted_site_id := scope_identity(); 34 | 35 | INSERT INTO whitelisted_site_scope(owner_id, scope) VALUES 36 | (@whitelisted_site_id, 'openid'), 37 | (@whitelisted_site_id, 'profile'), 38 | (@whitelisted_site_id, 'email'), 39 | (@whitelisted_site_id, 'address'), 40 | (@whitelisted_site_id, 'phone'), 41 | (@whitelisted_site_id, 'offline_access'); -------------------------------------------------------------------------------- /samples/simple-ui/src/main/resources/db/scopes.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- Insert demo scope information 3 | -- 4 | 5 | INSERT INTO system_scope (scope, description, icon, restricted, default_scope) VALUES 6 | ('openid', 'log in using your identity', 'user', false, true), 7 | ('profile', 'basic profile information', 'list-alt', false, true), 8 | ('email', 'email address', 'envelope', false, true), 9 | ('address', 'physical address', 'home', false, true), 10 | ('phone', 'telephone number', 'bell', false, true), 11 | ('offline_access', 'offline access', 'time', false, false); -------------------------------------------------------------------------------- /samples/simple-ui/src/main/resources/db/users.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- Insert demo user information. To add users to the H2 database, edit things here. 3 | -- 4 | 5 | INSERT INTO users (username, password, enabled) VALUES 6 | ('user','password',true); 7 | 8 | 9 | INSERT INTO authorities (username, authority) VALUES 10 | ('user','ROLE_USER'); 11 | 12 | -- By default, the username column here has to match the username column in the users table, above 13 | INSERT INTO user_info (sub, preferred_username, name, email, email_verified) VALUES 14 | ('01921.FLANRJQW','user','Demo User','user@example.com', true); -------------------------------------------------------------------------------- /samples/simple-ui/src/main/resources/keystore.jwks: -------------------------------------------------------------------------------- 1 | { 2 | "keys": [ 3 | { 4 | "alg": "RS256", 5 | "d": "PvBAngE3kkTnD3yDKo3wCvHJHm20kb9a0FVGLd0s2Y0E_3H2XnZC8-2zPhN6AQTjPhohSDCew20gzm76lyOvMqRiUP2Zpaopa1d2fGvNIQSdM07yKa6EivEYxqPQxa5esoZnexgnb9fom70I8n5OQRNQikwu-az26CsHX2zWMRodzSdN5CXHvb1PV09DmH8azTYwoMElPIqmcTfxiRw2Ov5ucmXXngKRFJgvfUgKd7v4ScBX7sQoQEjWEtt7ta0WvL3Ar5E1RAW4aHxuubZ6AtloxWCf17AAKw03dfP5RDm5TDmgm2B635ecJ7fTvneFmg8W_fdMTPRfBlCGNBp3wQ", 6 | "e": "AQAB", 7 | "n": "qt6yOiI_wCoCVlGO0MySsez0VkSqhPvDl3rfabOslx35mYEO-n4ABfIT5Gn2zN-CeIcOZ5ugAXvIIRWv5H55-tzjFazi5IKkOIMCiz5__MtsdxKCqGlZu2zt-BLpqTOAPiflNPpM3RUAlxKAhnYEqNha6-allPnFQupnW_eTYoyuzuedT7dSp90ry0ZcQDimntXWeaSbrYKCj9Rr9W1jn2uTowUuXaScKXTCjAmJVnsD75JNzQfa8DweklTyWQF-Y5Ky039I0VIu-0CIGhXY48GAFe2EFb8VpNhf07DP63p138RWQ1d3KPEM9mYJVpQC68j3wzDQYSljpLf9by7TGw", 8 | "kty": "RSA", 9 | "kid": "rsa1" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /samples/simple-ui/src/main/resources/templates/sampleclient.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 13 | 14 | 15 |
16 |
17 |
18 |
19 |
20 |

Sample Client

21 |
22 |
This would normally be on a separate client application's server, but we're redirecting here as demo to show the redirect response contents
23 | 24 |
25 |
26 |
27 |
28 |

29 | Access Token 30 |

31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |

41 | ID Token 42 |

43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | 53 |
54 |
55 |
56 |
57 | 58 | 59 | 60 | 61 | 62 | 68 | 69 | -------------------------------------------------------------------------------- /samples/simple-ui/src/main/resources/templates/session.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 16 |
17 |
18 |
19 |
20 |
21 |

22 |
23 |
24 |
25 |
26 |
27 |
28 | 29 | 30 |
31 |
32 |
33 |
34 | 35 | 36 |
37 |
38 |
39 | 40 |
41 |
Invalid username and password.
42 |
You have been logged out.
43 |
Your session timed out, please retry.
44 |
45 | 46 |
47 | 48 |
49 |
50 | You are logged in as '' 51 |
52 |
53 |
54 |
55 | 56 |
57 | 58 |
59 |
60 | 61 | 66 | 67 |
68 | 69 |
70 |
71 |
72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "openid-connect-server-spring-boot" 2 | 3 | include 'openid-connect-server-spring-boot-config' 4 | include 'openid-connect-server-spring-boot-ui-thymeleaf' 5 | include 'openid-connect-server-spring-boot-test' --------------------------------------------------------------------------------