@@ -0,0 +1,20 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="CompilerConfiguration"> | |||
<annotationProcessing> | |||
<profile name="Maven default annotation processors profile" enabled="true"> | |||
<sourceOutputDir name="target/generated-sources/annotations" /> | |||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" /> | |||
<outputRelativeToContentRoot value="true" /> | |||
<module name="Spring_Authorization_Server" /> | |||
<module name="tuoheng_oidc" /> | |||
</profile> | |||
</annotationProcessing> | |||
</component> | |||
<component name="JavacSettings"> | |||
<option name="ADDITIONAL_OPTIONS_OVERRIDE"> | |||
<module name="Spring_Authorization_Server" options="-parameters" /> | |||
<module name="tuoheng_oidc" options="-parameters" /> | |||
</option> | |||
</component> | |||
</project> |
@@ -0,0 +1,7 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="Encoding"> | |||
<file url="file://$PROJECT_DIR$/Spring_Authorization_Server/src/main/java" charset="UTF-8" /> | |||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" /> | |||
</component> | |||
</project> |
@@ -0,0 +1,20 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="RemoteRepositoriesConfiguration"> | |||
<remote-repository> | |||
<option name="id" value="central" /> | |||
<option name="name" value="Central Repository" /> | |||
<option name="url" value="http://maven.aliyun.com/nexus/content/groups/public/" /> | |||
</remote-repository> | |||
<remote-repository> | |||
<option name="id" value="central" /> | |||
<option name="name" value="Maven Central repository" /> | |||
<option name="url" value="https://repo1.maven.org/maven2" /> | |||
</remote-repository> | |||
<remote-repository> | |||
<option name="id" value="jboss.community" /> | |||
<option name="name" value="JBoss Community repository" /> | |||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" /> | |||
</remote-repository> | |||
</component> | |||
</project> |
@@ -0,0 +1,13 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="ExternalStorageConfigurationManager" enabled="true" /> | |||
<component name="MavenProjectsManager"> | |||
<option name="originalFiles"> | |||
<list> | |||
<option value="$PROJECT_DIR$/pom.xml" /> | |||
<option value="$PROJECT_DIR$/Spring_Authorization_Server/pom.xml" /> | |||
</list> | |||
</option> | |||
</component> | |||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK" /> | |||
</project> |
@@ -0,0 +1,124 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="Palette2"> | |||
<group name="Swing"> | |||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false"> | |||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" /> | |||
</item> | |||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false"> | |||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" /> | |||
</item> | |||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false"> | |||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" /> | |||
</item> | |||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true"> | |||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" /> | |||
</item> | |||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false"> | |||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" /> | |||
<initial-values> | |||
<property name="text" value="Button" /> | |||
</initial-values> | |||
</item> | |||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false"> | |||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> | |||
<initial-values> | |||
<property name="text" value="RadioButton" /> | |||
</initial-values> | |||
</item> | |||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false"> | |||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> | |||
<initial-values> | |||
<property name="text" value="CheckBox" /> | |||
</initial-values> | |||
</item> | |||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false"> | |||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" /> | |||
<initial-values> | |||
<property name="text" value="Label" /> | |||
</initial-values> | |||
</item> | |||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true"> | |||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> | |||
<preferred-size width="150" height="-1" /> | |||
</default-constraints> | |||
</item> | |||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true"> | |||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> | |||
<preferred-size width="150" height="-1" /> | |||
</default-constraints> | |||
</item> | |||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true"> | |||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> | |||
<preferred-size width="150" height="-1" /> | |||
</default-constraints> | |||
</item> | |||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true"> | |||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> | |||
<preferred-size width="150" height="50" /> | |||
</default-constraints> | |||
</item> | |||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true"> | |||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> | |||
<preferred-size width="150" height="50" /> | |||
</default-constraints> | |||
</item> | |||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true"> | |||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> | |||
<preferred-size width="150" height="50" /> | |||
</default-constraints> | |||
</item> | |||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true"> | |||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" /> | |||
</item> | |||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false"> | |||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> | |||
<preferred-size width="150" height="50" /> | |||
</default-constraints> | |||
</item> | |||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false"> | |||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3"> | |||
<preferred-size width="150" height="50" /> | |||
</default-constraints> | |||
</item> | |||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false"> | |||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> | |||
<preferred-size width="150" height="50" /> | |||
</default-constraints> | |||
</item> | |||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false"> | |||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> | |||
<preferred-size width="200" height="200" /> | |||
</default-constraints> | |||
</item> | |||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false"> | |||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> | |||
<preferred-size width="200" height="200" /> | |||
</default-constraints> | |||
</item> | |||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true"> | |||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> | |||
</item> | |||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false"> | |||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> | |||
</item> | |||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false"> | |||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" /> | |||
</item> | |||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false"> | |||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" /> | |||
</item> | |||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false"> | |||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1"> | |||
<preferred-size width="-1" height="20" /> | |||
</default-constraints> | |||
</item> | |||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false"> | |||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" /> | |||
</item> | |||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false"> | |||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" /> | |||
</item> | |||
</group> | |||
</component> | |||
</project> |
@@ -0,0 +1,6 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="VcsDirectoryMappings"> | |||
<mapping directory="$PROJECT_DIR$" vcs="Git" /> | |||
</component> | |||
</project> |
@@ -0,0 +1,254 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="AutoImportSettings"> | |||
<option name="autoReloadType" value="SELECTIVE" /> | |||
</component> | |||
<component name="ChangeListManager"> | |||
<list default="true" id="3d625d39-e01c-4cdb-a118-b6b850d2db2a" name="Changes" comment="first commit" /> | |||
<option name="SHOW_DIALOG" value="false" /> | |||
<option name="HIGHLIGHT_CONFLICTS" value="true" /> | |||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> | |||
<option name="LAST_RESOLUTION" value="IGNORE" /> | |||
</component> | |||
<component name="FileTemplateManagerImpl"> | |||
<option name="RECENT_TEMPLATES"> | |||
<list> | |||
<option value="Class" /> | |||
<option value="FxmlFile" /> | |||
</list> | |||
</option> | |||
</component> | |||
<component name="Git.Settings"> | |||
<option name="RECENT_BRANCH_BY_REPOSITORY"> | |||
<map> | |||
<entry key="$PROJECT_DIR$" value="master" /> | |||
</map> | |||
</option> | |||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" /> | |||
</component> | |||
<component name="MarkdownSettingsMigration"> | |||
<option name="stateVersion" value="1" /> | |||
</component> | |||
<component name="MavenImportPreferences"> | |||
<option name="generalSettings"> | |||
<MavenGeneralSettings> | |||
<option name="localRepository" value="D:\mvn_repository" /> | |||
<option name="mavenHome" value="Use Maven wrapper" /> | |||
<option name="showDialogWithAdvancedSettings" value="true" /> | |||
<option name="useMavenConfig" value="true" /> | |||
<option name="userSettingsFile" value="D:\Software\apache-maven-3.6.1\conf\settings.xml" /> | |||
</MavenGeneralSettings> | |||
</option> | |||
<option name="enabledProfiles"> | |||
<list> | |||
<option value="local" /> | |||
</list> | |||
</option> | |||
</component> | |||
<component name="ProjectId" id="2FKcrEf74Sqqi7h9gH28BU8Eb7a" /> | |||
<component name="ProjectLevelVcsManager" settingsEditedManually="true" /> | |||
<component name="ProjectViewState"> | |||
<option name="hideEmptyMiddlePackages" value="true" /> | |||
<option name="showExcludedFiles" value="false" /> | |||
<option name="showLibraryContents" value="true" /> | |||
</component> | |||
<component name="PropertiesComponent"><![CDATA[{ | |||
"keyToString": { | |||
"RequestMappingsPanelOrder0": "0", | |||
"RequestMappingsPanelOrder1": "1", | |||
"RequestMappingsPanelWidth0": "75", | |||
"RequestMappingsPanelWidth1": "75", | |||
"RunOnceActivity.OpenProjectViewOnStart": "true", | |||
"RunOnceActivity.ShowReadmeOnStart": "true", | |||
"WebServerToolWindowFactoryState": "false", | |||
"jdk.selected.JAVA_MODULE": "1.8", | |||
"last_directory_selection": "D:/TH_workspace/tuoheng_oidc/Spring_Authorization_Server/src/test/java", | |||
"last_opened_file_path": "D:/TH_workspace/tuoheng_oidc/Spring_Authorization_Server/src/main/resources", | |||
"nodejs_package_manager_path": "npm", | |||
"project.structure.last.edited": "Modules", | |||
"project.structure.proportion": "0.15", | |||
"project.structure.side.proportion": "0.3348666", | |||
"settings.editor.selected.configurable": "MavenSettings", | |||
"spring.configuration.checksum": "4aaf3b561721ae338572fef3b1b36b8c" | |||
} | |||
}]]></component> | |||
<component name="RecentsManager"> | |||
<key name="CopyFile.RECENT_KEYS"> | |||
<recent name="D:\TH_workspace\tuoheng_oidc\Spring_Authorization_Server\src\main\resources" /> | |||
</key> | |||
<key name="CopyClassDialog.RECENTS_KEY"> | |||
<recent name="com.tuoheng.until" /> | |||
</key> | |||
</component> | |||
<component name="RunManager" selected="Spring Boot.SpringAuthorizationServerApplication"> | |||
<configuration name="CryptoUtil" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true"> | |||
<option name="MAIN_CLASS_NAME" value="com.tuoheng.until.CryptoUtil" /> | |||
<module name="Spring_Authorization_Server" /> | |||
<extension name="coverage"> | |||
<pattern> | |||
<option name="PATTERN" value="com.tuoheng.until.*" /> | |||
<option name="ENABLED" value="true" /> | |||
</pattern> | |||
</extension> | |||
<method v="2"> | |||
<option name="Make" enabled="true" /> | |||
</method> | |||
</configuration> | |||
<configuration name="ApplicationTests" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true"> | |||
<module name="Spring_Authorization_Server" /> | |||
<extension name="coverage"> | |||
<pattern> | |||
<option name="PATTERN" value="com.tuoheng.config.*" /> | |||
<option name="ENABLED" value="true" /> | |||
</pattern> | |||
</extension> | |||
<option name="PACKAGE_NAME" value="com.tuoheng.config" /> | |||
<option name="MAIN_CLASS_NAME" value="com.tuoheng.config.ApplicationTests" /> | |||
<option name="TEST_OBJECT" value="class" /> | |||
<method v="2"> | |||
<option name="Make" enabled="true" /> | |||
</method> | |||
</configuration> | |||
<configuration name="SpringAuthorizationServerApplication" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot"> | |||
<module name="Spring_Authorization_Server" /> | |||
<option name="SPRING_BOOT_MAIN_CLASS" value="com.tuoheng.SpringAuthorizationServerApplication" /> | |||
<method v="2"> | |||
<option name="Make" enabled="true" /> | |||
</method> | |||
</configuration> | |||
<recent_temporary> | |||
<list> | |||
<item itemvalue="JUnit.ApplicationTests" /> | |||
<item itemvalue="Application.CryptoUtil" /> | |||
</list> | |||
</recent_temporary> | |||
</component> | |||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" /> | |||
<component name="TaskManager"> | |||
<task active="true" id="Default" summary="Default task"> | |||
<changelist id="3d625d39-e01c-4cdb-a118-b6b850d2db2a" name="Changes" comment="" /> | |||
<created>1664244413973</created> | |||
<option name="number" value="Default" /> | |||
<option name="presentableId" value="Default" /> | |||
<updated>1664244413973</updated> | |||
<workItem from="1664244415262" duration="6124000" /> | |||
<workItem from="1664262363401" duration="7308000" /> | |||
<workItem from="1664277836289" duration="66000" /> | |||
<workItem from="1664324718566" duration="19196000" /> | |||
<workItem from="1664410795083" duration="15879000" /> | |||
<workItem from="1664497850782" duration="24541000" /> | |||
<workItem from="1665190006394" duration="12411000" /> | |||
</task> | |||
<task id="LOCAL-00001" summary="first commit"> | |||
<created>1664245217656</created> | |||
<option name="number" value="00001" /> | |||
<option name="presentableId" value="LOCAL-00001" /> | |||
<option name="project" value="LOCAL" /> | |||
<updated>1664245217656</updated> | |||
</task> | |||
<task id="LOCAL-00002" summary="first commit"> | |||
<created>1664245344567</created> | |||
<option name="number" value="00002" /> | |||
<option name="presentableId" value="LOCAL-00002" /> | |||
<option name="project" value="LOCAL" /> | |||
<updated>1664245344567</updated> | |||
</task> | |||
<task id="LOCAL-00003" summary="first commit"> | |||
<created>1664266153862</created> | |||
<option name="number" value="00003" /> | |||
<option name="presentableId" value="LOCAL-00003" /> | |||
<option name="project" value="LOCAL" /> | |||
<updated>1664266153862</updated> | |||
</task> | |||
<task id="LOCAL-00004" summary="first commit"> | |||
<created>1664270850485</created> | |||
<option name="number" value="00004" /> | |||
<option name="presentableId" value="LOCAL-00004" /> | |||
<option name="project" value="LOCAL" /> | |||
<updated>1664270850485</updated> | |||
</task> | |||
<task id="LOCAL-00005" summary="first commit"> | |||
<created>1664328605978</created> | |||
<option name="number" value="00005" /> | |||
<option name="presentableId" value="LOCAL-00005" /> | |||
<option name="project" value="LOCAL" /> | |||
<updated>1664328605978</updated> | |||
</task> | |||
<task id="LOCAL-00006" summary="first commit"> | |||
<created>1664332370111</created> | |||
<option name="number" value="00006" /> | |||
<option name="presentableId" value="LOCAL-00006" /> | |||
<option name="project" value="LOCAL" /> | |||
<updated>1664332370111</updated> | |||
</task> | |||
<task id="LOCAL-00007" summary="first commit"> | |||
<created>1664342000639</created> | |||
<option name="number" value="00007" /> | |||
<option name="presentableId" value="LOCAL-00007" /> | |||
<option name="project" value="LOCAL" /> | |||
<updated>1664342000639</updated> | |||
</task> | |||
<task id="LOCAL-00008" summary="first commit"> | |||
<created>1664415968397</created> | |||
<option name="number" value="00008" /> | |||
<option name="presentableId" value="LOCAL-00008" /> | |||
<option name="project" value="LOCAL" /> | |||
<updated>1664415968398</updated> | |||
</task> | |||
<task id="LOCAL-00009" summary="first commit"> | |||
<created>1664416192991</created> | |||
<option name="number" value="00009" /> | |||
<option name="presentableId" value="LOCAL-00009" /> | |||
<option name="project" value="LOCAL" /> | |||
<updated>1664416192991</updated> | |||
</task> | |||
<task id="LOCAL-00010" summary="first commit"> | |||
<created>1664501707719</created> | |||
<option name="number" value="00010" /> | |||
<option name="presentableId" value="LOCAL-00010" /> | |||
<option name="project" value="LOCAL" /> | |||
<updated>1664501707719</updated> | |||
</task> | |||
<task id="LOCAL-00011" summary="first commit"> | |||
<created>1664516181337</created> | |||
<option name="number" value="00011" /> | |||
<option name="presentableId" value="LOCAL-00011" /> | |||
<option name="project" value="LOCAL" /> | |||
<updated>1664516181337</updated> | |||
</task> | |||
<task id="LOCAL-00012" summary="first commit"> | |||
<created>1665195189771</created> | |||
<option name="number" value="00012" /> | |||
<option name="presentableId" value="LOCAL-00012" /> | |||
<option name="project" value="LOCAL" /> | |||
<updated>1665195189771</updated> | |||
</task> | |||
<task id="LOCAL-00013" summary="first commit"> | |||
<created>1665195248223</created> | |||
<option name="number" value="00013" /> | |||
<option name="presentableId" value="LOCAL-00013" /> | |||
<option name="project" value="LOCAL" /> | |||
<updated>1665195248223</updated> | |||
</task> | |||
<option name="localTasksCounter" value="14" /> | |||
<servers /> | |||
</component> | |||
<component name="TypeScriptGeneratedFilesManager"> | |||
<option name="version" value="3" /> | |||
</component> | |||
<component name="Vcs.Log.Tabs.Properties"> | |||
<option name="TAB_STATES"> | |||
<map> | |||
<entry key="MAIN"> | |||
<value> | |||
<State /> | |||
</value> | |||
</entry> | |||
</map> | |||
</option> | |||
</component> | |||
<component name="VcsManagerConfiguration"> | |||
<MESSAGE value="first commit" /> | |||
<option name="LAST_COMMIT_MESSAGE" value="first commit" /> | |||
</component> | |||
</project> |
@@ -0,0 +1,2 @@ | |||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip | |||
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar |
@@ -0,0 +1,9 @@ | |||
# Getting Started | |||
### Reference Documentation | |||
For further reference, please consider the following sections: | |||
* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html) | |||
* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.7.3/maven-plugin/reference/html/) | |||
* [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.7.3/maven-plugin/reference/html/#build-image) | |||
@@ -0,0 +1,66 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> | |||
<component name="FacetManager"> | |||
<facet type="Spring" name="Spring"> | |||
<configuration /> | |||
</facet> | |||
</component> | |||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8"> | |||
<output url="file://$MODULE_DIR$/target/classes" /> | |||
<output-test url="file://$MODULE_DIR$/target/test-classes" /> | |||
<content url="file://$MODULE_DIR$"> | |||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> | |||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> | |||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> | |||
<excludeFolder url="file://$MODULE_DIR$/target" /> | |||
</content> | |||
<orderEntry type="inheritedJdk" /> | |||
<orderEntry type="sourceFolder" forTests="false" /> | |||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.7.3" level="project" /> | |||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.7.3" level="project" /> | |||
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.22" level="project" /> | |||
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.22" level="project" /> | |||
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.22" level="project" /> | |||
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.22" level="project" /> | |||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.7.3" level="project" /> | |||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.7.3" level="project" /> | |||
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" /> | |||
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" /> | |||
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" /> | |||
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" /> | |||
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" /> | |||
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" /> | |||
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.22" level="project" /> | |||
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.22" level="project" /> | |||
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.30" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.7.3" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.7.3" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.7.3" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: com.jayway.jsonpath:json-path:2.7.0" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.4.8" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:2.4.8" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm:9.1" level="project" /> | |||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:2.3.3" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: jakarta.activation:jakarta.activation-api:1.2.2" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:3.22.0" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest:2.2" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter:5.8.2" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-api:5.8.2" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.opentest4j:opentest4j:1.2.0" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-commons:1.8.2" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.1.2" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-params:5.8.2" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-engine:5.8.2" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-engine:1.8.2" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:4.5.1" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy:1.12.13" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.12.13" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:3.2" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-junit-jupiter:4.5.1" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.1" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.3.22" level="project" /> | |||
<orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.9.0" level="project" /> | |||
</component> | |||
</module> |
@@ -0,0 +1,33 @@ | |||
HELP.md | |||
target/ | |||
!.mvn/wrapper/maven-wrapper.jar | |||
!**/src/main/**/target/ | |||
!**/src/test/**/target/ | |||
### STS ### | |||
.apt_generated | |||
.classpath | |||
.factorypath | |||
.project | |||
.settings | |||
.springBeans | |||
.sts4-cache | |||
### IntelliJ IDEA ### | |||
.idea | |||
*.iws | |||
*.iml | |||
*.ipr | |||
### NetBeans ### | |||
/nbproject/private/ | |||
/nbbuild/ | |||
/dist/ | |||
/nbdist/ | |||
/.nb-gradle/ | |||
build/ | |||
!**/src/main/**/build/ | |||
!**/src/test/**/build/ | |||
### VS Code ### | |||
.vscode/ |
@@ -0,0 +1,2 @@ | |||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip | |||
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar |
@@ -0,0 +1,316 @@ | |||
#!/bin/sh | |||
# ---------------------------------------------------------------------------- | |||
# Licensed to the Apache Software Foundation (ASF) under one | |||
# or more contributor license agreements. See the NOTICE file | |||
# distributed with this work for additional information | |||
# regarding copyright ownership. The ASF licenses this file | |||
# to you under the Apache License, Version 2.0 (the | |||
# "License"); you may not use this file except in compliance | |||
# with the License. You may obtain a copy of the License at | |||
# | |||
# https://www.apache.org/licenses/LICENSE-2.0 | |||
# | |||
# Unless required by applicable law or agreed to in writing, | |||
# software distributed under the License is distributed on an | |||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |||
# KIND, either express or implied. See the License for the | |||
# specific language governing permissions and limitations | |||
# under the License. | |||
# ---------------------------------------------------------------------------- | |||
# ---------------------------------------------------------------------------- | |||
# Maven Start Up Batch script | |||
# | |||
# Required ENV vars: | |||
# ------------------ | |||
# JAVA_HOME - location of a JDK home dir | |||
# | |||
# Optional ENV vars | |||
# ----------------- | |||
# M2_HOME - location of maven2's installed home dir | |||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven | |||
# e.g. to debug Maven itself, use | |||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 | |||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files | |||
# ---------------------------------------------------------------------------- | |||
if [ -z "$MAVEN_SKIP_RC" ] ; then | |||
if [ -f /usr/local/etc/mavenrc ] ; then | |||
. /usr/local/etc/mavenrc | |||
fi | |||
if [ -f /etc/mavenrc ] ; then | |||
. /etc/mavenrc | |||
fi | |||
if [ -f "$HOME/.mavenrc" ] ; then | |||
. "$HOME/.mavenrc" | |||
fi | |||
fi | |||
# OS specific support. $var _must_ be set to either true or false. | |||
cygwin=false; | |||
darwin=false; | |||
mingw=false | |||
case "`uname`" in | |||
CYGWIN*) cygwin=true ;; | |||
MINGW*) mingw=true;; | |||
Darwin*) darwin=true | |||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home | |||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html | |||
if [ -z "$JAVA_HOME" ]; then | |||
if [ -x "/usr/libexec/java_home" ]; then | |||
export JAVA_HOME="`/usr/libexec/java_home`" | |||
else | |||
export JAVA_HOME="/Library/Java/Home" | |||
fi | |||
fi | |||
;; | |||
esac | |||
if [ -z "$JAVA_HOME" ] ; then | |||
if [ -r /etc/gentoo-release ] ; then | |||
JAVA_HOME=`java-config --jre-home` | |||
fi | |||
fi | |||
if [ -z "$M2_HOME" ] ; then | |||
## resolve links - $0 may be a link to maven's home | |||
PRG="$0" | |||
# need this for relative symlinks | |||
while [ -h "$PRG" ] ; do | |||
ls=`ls -ld "$PRG"` | |||
link=`expr "$ls" : '.*-> \(.*\)$'` | |||
if expr "$link" : '/.*' > /dev/null; then | |||
PRG="$link" | |||
else | |||
PRG="`dirname "$PRG"`/$link" | |||
fi | |||
done | |||
saveddir=`pwd` | |||
M2_HOME=`dirname "$PRG"`/.. | |||
# make it fully qualified | |||
M2_HOME=`cd "$M2_HOME" && pwd` | |||
cd "$saveddir" | |||
# echo Using m2 at $M2_HOME | |||
fi | |||
# For Cygwin, ensure paths are in UNIX format before anything is touched | |||
if $cygwin ; then | |||
[ -n "$M2_HOME" ] && | |||
M2_HOME=`cygpath --unix "$M2_HOME"` | |||
[ -n "$JAVA_HOME" ] && | |||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"` | |||
[ -n "$CLASSPATH" ] && | |||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"` | |||
fi | |||
# For Mingw, ensure paths are in UNIX format before anything is touched | |||
if $mingw ; then | |||
[ -n "$M2_HOME" ] && | |||
M2_HOME="`(cd "$M2_HOME"; pwd)`" | |||
[ -n "$JAVA_HOME" ] && | |||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" | |||
fi | |||
if [ -z "$JAVA_HOME" ]; then | |||
javaExecutable="`which javac`" | |||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then | |||
# readlink(1) is not available as standard on Solaris 10. | |||
readLink=`which readlink` | |||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then | |||
if $darwin ; then | |||
javaHome="`dirname \"$javaExecutable\"`" | |||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" | |||
else | |||
javaExecutable="`readlink -f \"$javaExecutable\"`" | |||
fi | |||
javaHome="`dirname \"$javaExecutable\"`" | |||
javaHome=`expr "$javaHome" : '\(.*\)/bin'` | |||
JAVA_HOME="$javaHome" | |||
export JAVA_HOME | |||
fi | |||
fi | |||
fi | |||
if [ -z "$JAVACMD" ] ; then | |||
if [ -n "$JAVA_HOME" ] ; then | |||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | |||
# IBM's JDK on AIX uses strange locations for the executables | |||
JAVACMD="$JAVA_HOME/jre/sh/java" | |||
else | |||
JAVACMD="$JAVA_HOME/bin/java" | |||
fi | |||
else | |||
JAVACMD="`\\unset -f command; \\command -v java`" | |||
fi | |||
fi | |||
if [ ! -x "$JAVACMD" ] ; then | |||
echo "Error: JAVA_HOME is not defined correctly." >&2 | |||
echo " We cannot execute $JAVACMD" >&2 | |||
exit 1 | |||
fi | |||
if [ -z "$JAVA_HOME" ] ; then | |||
echo "Warning: JAVA_HOME environment variable is not set." | |||
fi | |||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher | |||
# traverses directory structure from process work directory to filesystem root | |||
# first directory with .mvn subdirectory is considered project base directory | |||
find_maven_basedir() { | |||
if [ -z "$1" ] | |||
then | |||
echo "Path not specified to find_maven_basedir" | |||
return 1 | |||
fi | |||
basedir="$1" | |||
wdir="$1" | |||
while [ "$wdir" != '/' ] ; do | |||
if [ -d "$wdir"/.mvn ] ; then | |||
basedir=$wdir | |||
break | |||
fi | |||
# workaround for JBEAP-8937 (on Solaris 10/Sparc) | |||
if [ -d "${wdir}" ]; then | |||
wdir=`cd "$wdir/.."; pwd` | |||
fi | |||
# end of workaround | |||
done | |||
echo "${basedir}" | |||
} | |||
# concatenates all lines of a file | |||
concat_lines() { | |||
if [ -f "$1" ]; then | |||
echo "$(tr -s '\n' ' ' < "$1")" | |||
fi | |||
} | |||
BASE_DIR=`find_maven_basedir "$(pwd)"` | |||
if [ -z "$BASE_DIR" ]; then | |||
exit 1; | |||
fi | |||
########################################################################################## | |||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central | |||
# This allows using the maven wrapper in projects that prohibit checking in binary data. | |||
########################################################################################## | |||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then | |||
if [ "$MVNW_VERBOSE" = true ]; then | |||
echo "Found .mvn/wrapper/maven-wrapper.jar" | |||
fi | |||
else | |||
if [ "$MVNW_VERBOSE" = true ]; then | |||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." | |||
fi | |||
if [ -n "$MVNW_REPOURL" ]; then | |||
jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" | |||
else | |||
jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" | |||
fi | |||
while IFS="=" read key value; do | |||
case "$key" in (wrapperUrl) jarUrl="$value"; break ;; | |||
esac | |||
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" | |||
if [ "$MVNW_VERBOSE" = true ]; then | |||
echo "Downloading from: $jarUrl" | |||
fi | |||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" | |||
if $cygwin; then | |||
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` | |||
fi | |||
if command -v wget > /dev/null; then | |||
if [ "$MVNW_VERBOSE" = true ]; then | |||
echo "Found wget ... using wget" | |||
fi | |||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then | |||
wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" | |||
else | |||
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" | |||
fi | |||
elif command -v curl > /dev/null; then | |||
if [ "$MVNW_VERBOSE" = true ]; then | |||
echo "Found curl ... using curl" | |||
fi | |||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then | |||
curl -o "$wrapperJarPath" "$jarUrl" -f | |||
else | |||
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f | |||
fi | |||
else | |||
if [ "$MVNW_VERBOSE" = true ]; then | |||
echo "Falling back to using Java to download" | |||
fi | |||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" | |||
# For Cygwin, switch paths to Windows format before running javac | |||
if $cygwin; then | |||
javaClass=`cygpath --path --windows "$javaClass"` | |||
fi | |||
if [ -e "$javaClass" ]; then | |||
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then | |||
if [ "$MVNW_VERBOSE" = true ]; then | |||
echo " - Compiling MavenWrapperDownloader.java ..." | |||
fi | |||
# Compiling the Java class | |||
("$JAVA_HOME/bin/javac" "$javaClass") | |||
fi | |||
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then | |||
# Running the downloader | |||
if [ "$MVNW_VERBOSE" = true ]; then | |||
echo " - Running MavenWrapperDownloader.java ..." | |||
fi | |||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") | |||
fi | |||
fi | |||
fi | |||
fi | |||
########################################################################################## | |||
# End of extension | |||
########################################################################################## | |||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} | |||
if [ "$MVNW_VERBOSE" = true ]; then | |||
echo $MAVEN_PROJECTBASEDIR | |||
fi | |||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" | |||
# For Cygwin, switch paths to Windows format before running java | |||
if $cygwin; then | |||
[ -n "$M2_HOME" ] && | |||
M2_HOME=`cygpath --path --windows "$M2_HOME"` | |||
[ -n "$JAVA_HOME" ] && | |||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` | |||
[ -n "$CLASSPATH" ] && | |||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"` | |||
[ -n "$MAVEN_PROJECTBASEDIR" ] && | |||
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` | |||
fi | |||
# Provide a "standardized" way to retrieve the CLI args that will | |||
# work with both Windows and non-Windows executions. | |||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" | |||
export MAVEN_CMD_LINE_ARGS | |||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain | |||
exec "$JAVACMD" \ | |||
$MAVEN_OPTS \ | |||
$MAVEN_DEBUG_OPTS \ | |||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ | |||
"-Dmaven.home=${M2_HOME}" \ | |||
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ | |||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" |
@@ -0,0 +1,188 @@ | |||
@REM ---------------------------------------------------------------------------- | |||
@REM Licensed to the Apache Software Foundation (ASF) under one | |||
@REM or more contributor license agreements. See the NOTICE file | |||
@REM distributed with this work for additional information | |||
@REM regarding copyright ownership. The ASF licenses this file | |||
@REM to you under the Apache License, Version 2.0 (the | |||
@REM "License"); you may not use this file except in compliance | |||
@REM with the License. You may obtain a copy of the License at | |||
@REM | |||
@REM https://www.apache.org/licenses/LICENSE-2.0 | |||
@REM | |||
@REM Unless required by applicable law or agreed to in writing, | |||
@REM software distributed under the License is distributed on an | |||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |||
@REM KIND, either express or implied. See the License for the | |||
@REM specific language governing permissions and limitations | |||
@REM under the License. | |||
@REM ---------------------------------------------------------------------------- | |||
@REM ---------------------------------------------------------------------------- | |||
@REM Maven Start Up Batch script | |||
@REM | |||
@REM Required ENV vars: | |||
@REM JAVA_HOME - location of a JDK home dir | |||
@REM | |||
@REM Optional ENV vars | |||
@REM M2_HOME - location of maven2's installed home dir | |||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands | |||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending | |||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven | |||
@REM e.g. to debug Maven itself, use | |||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 | |||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files | |||
@REM ---------------------------------------------------------------------------- | |||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' | |||
@echo off | |||
@REM set title of command window | |||
title %0 | |||
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' | |||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% | |||
@REM set %HOME% to equivalent of $HOME | |||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") | |||
@REM Execute a user defined script before this one | |||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre | |||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending | |||
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* | |||
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* | |||
:skipRcPre | |||
@setlocal | |||
set ERROR_CODE=0 | |||
@REM To isolate internal variables from possible post scripts, we use another setlocal | |||
@setlocal | |||
@REM ==== START VALIDATION ==== | |||
if not "%JAVA_HOME%" == "" goto OkJHome | |||
echo. | |||
echo Error: JAVA_HOME not found in your environment. >&2 | |||
echo Please set the JAVA_HOME variable in your environment to match the >&2 | |||
echo location of your Java installation. >&2 | |||
echo. | |||
goto error | |||
:OkJHome | |||
if exist "%JAVA_HOME%\bin\java.exe" goto init | |||
echo. | |||
echo Error: JAVA_HOME is set to an invalid directory. >&2 | |||
echo JAVA_HOME = "%JAVA_HOME%" >&2 | |||
echo Please set the JAVA_HOME variable in your environment to match the >&2 | |||
echo location of your Java installation. >&2 | |||
echo. | |||
goto error | |||
@REM ==== END VALIDATION ==== | |||
:init | |||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". | |||
@REM Fallback to current working directory if not found. | |||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% | |||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir | |||
set EXEC_DIR=%CD% | |||
set WDIR=%EXEC_DIR% | |||
:findBaseDir | |||
IF EXIST "%WDIR%"\.mvn goto baseDirFound | |||
cd .. | |||
IF "%WDIR%"=="%CD%" goto baseDirNotFound | |||
set WDIR=%CD% | |||
goto findBaseDir | |||
:baseDirFound | |||
set MAVEN_PROJECTBASEDIR=%WDIR% | |||
cd "%EXEC_DIR%" | |||
goto endDetectBaseDir | |||
:baseDirNotFound | |||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR% | |||
cd "%EXEC_DIR%" | |||
:endDetectBaseDir | |||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig | |||
@setlocal EnableExtensions EnableDelayedExpansion | |||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a | |||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% | |||
:endReadAdditionalConfig | |||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" | |||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" | |||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain | |||
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" | |||
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( | |||
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B | |||
) | |||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central | |||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data. | |||
if exist %WRAPPER_JAR% ( | |||
if "%MVNW_VERBOSE%" == "true" ( | |||
echo Found %WRAPPER_JAR% | |||
) | |||
) else ( | |||
if not "%MVNW_REPOURL%" == "" ( | |||
SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" | |||
) | |||
if "%MVNW_VERBOSE%" == "true" ( | |||
echo Couldn't find %WRAPPER_JAR%, downloading it ... | |||
echo Downloading from: %DOWNLOAD_URL% | |||
) | |||
powershell -Command "&{"^ | |||
"$webclient = new-object System.Net.WebClient;"^ | |||
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ | |||
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ | |||
"}"^ | |||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ | |||
"}" | |||
if "%MVNW_VERBOSE%" == "true" ( | |||
echo Finished downloading %WRAPPER_JAR% | |||
) | |||
) | |||
@REM End of extension | |||
@REM Provide a "standardized" way to retrieve the CLI args that will | |||
@REM work with both Windows and non-Windows executions. | |||
set MAVEN_CMD_LINE_ARGS=%* | |||
%MAVEN_JAVA_EXE% ^ | |||
%JVM_CONFIG_MAVEN_PROPS% ^ | |||
%MAVEN_OPTS% ^ | |||
%MAVEN_DEBUG_OPTS% ^ | |||
-classpath %WRAPPER_JAR% ^ | |||
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ | |||
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* | |||
if ERRORLEVEL 1 goto error | |||
goto end | |||
:error | |||
set ERROR_CODE=1 | |||
:end | |||
@endlocal & set ERROR_CODE=%ERROR_CODE% | |||
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost | |||
@REM check for post script, once with legacy .bat ending and once with .cmd ending | |||
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" | |||
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" | |||
:skipRcPost | |||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' | |||
if "%MAVEN_BATCH_PAUSE%"=="on" pause | |||
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% | |||
cmd /C exit /B %ERROR_CODE% |
@@ -0,0 +1,128 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
<modelVersion>4.0.0</modelVersion> | |||
<parent> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-parent</artifactId> | |||
<version>2.7.3</version> | |||
<relativePath/> <!-- lookup parent from repository --> | |||
</parent> | |||
<groupId>com.tuoheng</groupId> | |||
<artifactId>tuoheng_oidc_server</artifactId> | |||
<version>1.0.0</version> | |||
<name>tuoheng_oidc_server</name> | |||
<description>tuoheng_oidc_server</description> | |||
<properties> | |||
<java.version>1.8</java.version> | |||
</properties> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-test</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
<!--spring-authorization-server依赖--> | |||
<dependency> | |||
<groupId>org.springframework.security</groupId> | |||
<artifactId>spring-security-oauth2-authorization-server</artifactId> | |||
<version>0.3.1</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-web</artifactId> | |||
<version>2.6.7</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-security</artifactId> | |||
<version>2.6.7</version> | |||
</dependency> | |||
<!-- 数据库 --> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-jdbc</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>mysql</groupId> | |||
<artifactId>mysql-connector-java</artifactId> | |||
</dependency> | |||
<!--MyBatis整合SpringBoot框架的起步依赖--> | |||
<dependency> | |||
<groupId>org.mybatis.spring.boot</groupId> | |||
<artifactId>mybatis-spring-boot-starter</artifactId> | |||
<version>2.2.1</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.projectlombok</groupId> | |||
<artifactId>lombok</artifactId> | |||
<version>1.18.22</version> | |||
</dependency> | |||
<!-- 数据连接池 --> | |||
<dependency> | |||
<groupId>com.alibaba</groupId> | |||
<artifactId>druid-spring-boot-starter</artifactId> | |||
<version>1.2.9</version> | |||
</dependency> | |||
</dependencies> | |||
<!-- 构建环境变量 --> | |||
<profiles> | |||
<!-- 本地开发环境 --> | |||
<profile> | |||
<id>local</id> | |||
<properties> | |||
<package.environment>local</package.environment> | |||
</properties> | |||
<activation> | |||
<activeByDefault>true</activeByDefault> | |||
</activation> | |||
</profile> | |||
<!-- 开发环境 --> | |||
<profile> | |||
<id>dev</id> | |||
<properties> | |||
<package.environment>dev</package.environment> | |||
</properties> | |||
</profile> | |||
<!-- 测试环境 --> | |||
<profile> | |||
<id>test</id> | |||
<properties> | |||
<package.environment>test</package.environment> | |||
</properties> | |||
</profile> | |||
<!-- 生产环境 --> | |||
<profile> | |||
<id>prod</id> | |||
<properties> | |||
<package.environment>prod</package.environment> | |||
</properties> | |||
</profile> | |||
</profiles> | |||
<build> | |||
<plugins> | |||
<plugin> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-maven-plugin</artifactId> | |||
</plugin> | |||
</plugins> | |||
</build> | |||
</project> |
@@ -0,0 +1,13 @@ | |||
package com.tuoheng; | |||
import org.springframework.boot.SpringApplication; | |||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||
@SpringBootApplication | |||
public class SpringAuthorizationServerApplication { | |||
public static void main(String[] args) { | |||
SpringApplication.run(SpringAuthorizationServerApplication.class, args); | |||
System.out.println("TuoHeng-Oidc启动成功~"); | |||
} | |||
} |
@@ -0,0 +1,60 @@ | |||
package com.tuoheng.config; | |||
import org.springframework.context.annotation.Bean; | |||
import org.springframework.context.annotation.Configuration; | |||
import org.springframework.jdbc.core.JdbcTemplate; | |||
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationConsentService; | |||
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService; | |||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService; | |||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; | |||
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository; | |||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; | |||
/** | |||
* @author chenjiandong | |||
* @description: TODO | |||
* @date 2022/9/22 14:53 | |||
*/ | |||
@Configuration(proxyBeanMethods = false) | |||
public class AuthorizationServerConfig { | |||
@Bean | |||
public RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTemplate) { | |||
//Save registered client from db | |||
JdbcRegisteredClientRepository registeredClientRepository = new JdbcRegisteredClientRepository(jdbcTemplate); | |||
//registeredClientRepository.save(RegisteredClientUtil.getRegisteredClient()); | |||
return registeredClientRepository; | |||
} | |||
/** | |||
* 令牌的发放记录 | |||
* | |||
* @param jdbcTemplate 操作数据库 | |||
* @param registeredClientRepository 客户端仓库 | |||
* @return 授权服务 | |||
*/ | |||
@Bean | |||
public OAuth2AuthorizationService auth2AuthorizationService( | |||
JdbcTemplate jdbcTemplate, | |||
RegisteredClientRepository registeredClientRepository) { | |||
return new JdbcOAuth2AuthorizationService(jdbcTemplate, registeredClientRepository); | |||
} | |||
/** | |||
* 把资源拥有者授权确认操作保存到数据库 | |||
* 资源拥有者(Resource Owner)对客户端的授权记录 | |||
* | |||
* @param jdbcTemplate 操作数据库 | |||
* @param registeredClientRepository 客户端仓库 | |||
* @return | |||
*/ | |||
@Bean | |||
public OAuth2AuthorizationConsentService auth2AuthorizationConsentService( | |||
JdbcTemplate jdbcTemplate, | |||
RegisteredClientRepository registeredClientRepository) { | |||
return new JdbcOAuth2AuthorizationConsentService(jdbcTemplate, registeredClientRepository); | |||
} | |||
} |
@@ -0,0 +1,31 @@ | |||
package com.tuoheng.config; | |||
import org.springframework.context.annotation.Bean; | |||
import org.springframework.context.annotation.Configuration; | |||
import org.springframework.security.core.GrantedAuthority; | |||
import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames; | |||
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext; | |||
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer; | |||
import java.util.stream.Collectors; | |||
/** | |||
* @author chenjiandong | |||
* @description: TODO | |||
* @date 2022/9/22 15:06 | |||
*/ | |||
@Configuration(proxyBeanMethods = false) | |||
public class IdTokenCustomizerConfig { | |||
@Bean | |||
public OAuth2TokenCustomizer<JwtEncodingContext> tokenCustomizer() { | |||
return (context) -> { | |||
if (OidcParameterNames.ID_TOKEN.equals(context.getTokenType().getValue())) { | |||
context.getClaims().claims(claims -> | |||
claims.put("role", context.getPrincipal().getAuthorities() | |||
.stream().map(GrantedAuthority::getAuthority) | |||
.collect(Collectors.toSet()))); | |||
} | |||
}; | |||
} | |||
} |
@@ -0,0 +1,51 @@ | |||
package com.tuoheng.config; | |||
import com.nimbusds.jose.jwk.JWKSet; | |||
import com.nimbusds.jose.jwk.RSAKey; | |||
import com.nimbusds.jose.jwk.source.ImmutableJWKSet; | |||
import com.nimbusds.jose.jwk.source.JWKSource; | |||
import com.nimbusds.jose.proc.SecurityContext; | |||
import org.springframework.context.annotation.Bean; | |||
import org.springframework.context.annotation.Configuration; | |||
import java.security.KeyPair; | |||
import java.security.KeyPairGenerator; | |||
import java.security.interfaces.RSAPrivateKey; | |||
import java.security.interfaces.RSAPublicKey; | |||
import java.util.UUID; | |||
/** | |||
* @author chenjiandong | |||
* @description: TODO | |||
* @date 2022/9/29 10:16 | |||
*/ | |||
@Configuration | |||
public class JWKSourceConfig { | |||
@Bean | |||
public JWKSource<SecurityContext> jwkSource() { | |||
KeyPair keyPair = generateRsaKey(); | |||
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); | |||
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); | |||
RSAKey rsaKey = new RSAKey.Builder(publicKey) | |||
.privateKey(privateKey) | |||
.keyID(UUID.randomUUID().toString()) | |||
.build(); | |||
JWKSet jwkSet = new JWKSet(rsaKey); | |||
return new ImmutableJWKSet<>(jwkSet); | |||
} | |||
private static KeyPair generateRsaKey() { | |||
KeyPair keyPair; | |||
try { | |||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); | |||
keyPairGenerator.initialize(2048); | |||
keyPair = keyPairGenerator.generateKeyPair(); | |||
} | |||
catch (Exception ex) { | |||
throw new IllegalStateException(ex); | |||
} | |||
return keyPair; | |||
} | |||
} |
@@ -0,0 +1,48 @@ | |||
package com.tuoheng.config; | |||
import org.springframework.context.annotation.Configuration; | |||
import org.springframework.core.Ordered; | |||
import org.springframework.core.annotation.Order; | |||
import org.springframework.stereotype.Component; | |||
import javax.servlet.*; | |||
import javax.servlet.http.HttpServletRequest; | |||
import javax.servlet.http.HttpServletResponse; | |||
import java.io.IOException; | |||
/** | |||
* @author chenjiandong | |||
* @description: TODO | |||
* @date 2022/9/29 9:22 | |||
*/ | |||
@Configuration | |||
@Order(Ordered.HIGHEST_PRECEDENCE) | |||
public class MyCorsFilter implements Filter { | |||
public MyCorsFilter() { | |||
} | |||
@Override | |||
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { | |||
HttpServletResponse response = (HttpServletResponse) res; | |||
HttpServletRequest request = (HttpServletRequest) req; | |||
response.setHeader("Access-Control-Allow-Origin", "*"); | |||
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); | |||
response.setHeader("Access-Control-Max-Age", "3600"); | |||
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization"); | |||
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { | |||
response.setStatus(HttpServletResponse.SC_OK); | |||
} else { | |||
chain.doFilter(req, res); | |||
} | |||
} | |||
@Override | |||
public void init(FilterConfig filterConfig) { | |||
} | |||
@Override | |||
public void destroy() { | |||
} | |||
} |
@@ -0,0 +1,109 @@ | |||
package com.tuoheng.config; | |||
import com.tuoheng.service.OidcUserInfoService; | |||
import lombok.RequiredArgsConstructor; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.context.annotation.Bean; | |||
import org.springframework.context.annotation.Configuration; | |||
import org.springframework.core.annotation.Order; | |||
import org.springframework.security.config.Customizer; | |||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; | |||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; | |||
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; | |||
import org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OAuth2AuthorizationServerConfigurer; | |||
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer; | |||
import org.springframework.security.core.userdetails.UserDetailsService; | |||
import org.springframework.security.oauth2.core.oidc.OidcUserInfo; | |||
import org.springframework.security.oauth2.server.authorization.config.ProviderSettings; | |||
import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcUserInfoAuthenticationContext; | |||
import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcUserInfoAuthenticationToken; | |||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; | |||
import org.springframework.security.provisioning.JdbcUserDetailsManager; | |||
import org.springframework.security.web.SecurityFilterChain; | |||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; | |||
import org.springframework.security.web.util.matcher.RequestMatcher; | |||
import javax.sql.DataSource; | |||
import java.util.function.Function; | |||
/** | |||
* @author chenjiandong | |||
* @description: TODO | |||
* @date 2022/9/22 14:58 | |||
*/ | |||
@EnableWebSecurity | |||
@Configuration(proxyBeanMethods = false) | |||
@RequiredArgsConstructor | |||
public class SecurityConfig { | |||
@Autowired | |||
private DataSource dataSource; | |||
@Bean | |||
@Order(1) | |||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { | |||
OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer = | |||
new OAuth2AuthorizationServerConfigurer<>(); | |||
OidcUserInfoService oidcUserInfoService = new OidcUserInfoService(); | |||
//自定义用户映射器 | |||
Function<OidcUserInfoAuthenticationContext, OidcUserInfo> userInfoMapper = (context) -> { | |||
OidcUserInfoAuthenticationToken authentication = context.getAuthentication(); | |||
JwtAuthenticationToken principal = (JwtAuthenticationToken) authentication.getPrincipal(); | |||
return oidcUserInfoService.loadUser(principal.getName(), context.getAccessToken().getScopes()); | |||
}; | |||
authorizationServerConfigurer.oidc((oidc) -> { | |||
oidc.userInfoEndpoint((userInfo) -> userInfo.userInfoMapper(userInfoMapper)); | |||
}); | |||
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher(); | |||
return http.requestMatcher(endpointsMatcher) | |||
//.userDetailsService(userService) | |||
.authorizeRequests((authorizeRequests) -> { | |||
((ExpressionUrlAuthorizationConfigurer.AuthorizedUrl) authorizeRequests.anyRequest()).authenticated(); | |||
}).csrf((csrf) -> { | |||
csrf.ignoringRequestMatchers(new RequestMatcher[]{endpointsMatcher}); | |||
}).apply(authorizationServerConfigurer) | |||
.and() | |||
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt) | |||
.exceptionHandling(exceptions -> exceptions. | |||
authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))) | |||
.apply(authorizationServerConfigurer) | |||
.and() | |||
.build(); | |||
} | |||
@Bean | |||
@Order(2) | |||
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { | |||
http | |||
.authorizeHttpRequests((authorize) -> authorize | |||
.antMatchers("/getHealth").permitAll() | |||
.anyRequest().authenticated() | |||
) | |||
// Form login handles the redirect to the login page from the | |||
// authorization server filter chain | |||
.formLogin(Customizer.withDefaults()); | |||
return http.build(); | |||
} | |||
@Bean | |||
public UserDetailsService userDetailsService() { | |||
// UserDetails userDetails = User.withDefaultPasswordEncoder() | |||
// .username("admin") | |||
// .password("123456") | |||
// .roles("USER") | |||
// .build(); | |||
// | |||
// return new InMemoryUserDetailsManager(userDetails); | |||
return new JdbcUserDetailsManager(dataSource); | |||
} | |||
@Bean | |||
public ProviderSettings providerSettings() { | |||
return ProviderSettings.builder().build(); | |||
} | |||
} |
@@ -0,0 +1,19 @@ | |||
package com.tuoheng.controller; | |||
import org.springframework.web.bind.annotation.GetMapping; | |||
import org.springframework.web.bind.annotation.RestController; | |||
/** | |||
* @author chenjiandong | |||
* @description: TODO | |||
* @date 2022/9/28 9:55 | |||
*/ | |||
@RestController | |||
public class HealthController { | |||
@GetMapping("/getHealth") | |||
public String getHealth(){ | |||
return "oidc is ok"; | |||
} | |||
} |
@@ -0,0 +1,28 @@ | |||
package com.tuoheng.controller; | |||
import com.tuoheng.model.param.CreateUserDto; | |||
import com.tuoheng.service.UserSevice; | |||
import com.tuoheng.until.JsonResult; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Controller; | |||
import org.springframework.validation.annotation.Validated; | |||
import org.springframework.web.bind.annotation.*; | |||
/** | |||
* @author chenjiandong | |||
* @description: TODO | |||
* @date 2022/10/8 11:20 | |||
*/ | |||
@RestController | |||
@RequestMapping("/user") | |||
public class UserController { | |||
@Autowired | |||
private UserSevice userSevice; | |||
@PostMapping("/create") | |||
public JsonResult createUser(@RequestBody @Validated CreateUserDto createUserDto){ | |||
return userSevice.createUser(createUserDto); | |||
} | |||
} |
@@ -0,0 +1,15 @@ | |||
package com.tuoheng.mapper; | |||
import org.apache.ibatis.annotations.Mapper; | |||
/** | |||
* @author chenjiandong | |||
* @description: TODO | |||
* @date 2022/10/8 11:59 | |||
*/ | |||
@Mapper | |||
public interface UserMapper { | |||
int insertUser(); | |||
} |
@@ -0,0 +1,21 @@ | |||
package com.tuoheng.model.param; | |||
import lombok.Data; | |||
import java.util.List; | |||
/** | |||
* @author chenjiandong | |||
* @description: TODO | |||
* @date 2022/10/8 11:30 | |||
*/ | |||
@Data | |||
public class CreateUserDto { | |||
private String username; | |||
private String password; | |||
private List<String> roles; | |||
} |
@@ -0,0 +1,23 @@ | |||
package com.tuoheng.model.po; | |||
import lombok.Data; | |||
/** | |||
* @author chenjiandong | |||
* @description: TODO | |||
* @date 2022/10/8 12:07 | |||
*/ | |||
@Data | |||
public class UserPo { | |||
private Integer id; | |||
private String username; | |||
private String password; | |||
private Integer enabled; | |||
private String clientId; | |||
} |
@@ -0,0 +1,53 @@ | |||
package com.tuoheng.service; | |||
import com.nimbusds.jose.shaded.json.JSONObject; | |||
import org.springframework.security.oauth2.core.oidc.OidcScopes; | |||
import org.springframework.security.oauth2.core.oidc.OidcUserInfo; | |||
import org.springframework.util.CollectionUtils; | |||
import java.time.LocalDateTime; | |||
import java.time.format.DateTimeFormatter; | |||
import java.util.Collections; | |||
import java.util.Set; | |||
/** | |||
* @author chenjiandong | |||
* @description: TODO | |||
* @date 2022/9/29 10:17 | |||
*/ | |||
public class OidcUserInfoService { | |||
public OidcUserInfo loadUser(String name, Set<String> scopes) { | |||
OidcUserInfo.Builder builder = OidcUserInfo.builder().subject(name); | |||
if (!CollectionUtils.isEmpty(scopes)) { | |||
if (scopes.contains(OidcScopes.PROFILE)) { | |||
builder.name("First Last") | |||
.givenName("First") | |||
.familyName("Last") | |||
.middleName("Middle") | |||
.nickname("User") | |||
.preferredUsername(name) | |||
.profile("http://127.0.0.1:8080/" + name) | |||
.picture("http://127.0.0.1:8080/" + name + ".jpg") | |||
.website("http://127.0.0.1:8080/") | |||
.gender("female") | |||
.birthdate("2022-05-24") | |||
.zoneinfo("China/Beijing") | |||
.locale("zh-cn") | |||
.updatedAt(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE)); | |||
} | |||
if (scopes.contains(OidcScopes.EMAIL)) { | |||
builder.email(name + "@163.com").emailVerified(true); | |||
} | |||
if (scopes.contains(OidcScopes.ADDRESS)) { | |||
JSONObject address = new JSONObject(); | |||
address.put("address", Collections.singletonMap("formatted", "Champ de Mars\n5 Av. Anatole France\n75007 Paris\nFrance")); | |||
builder.address(address.toJSONString()); | |||
} | |||
if (scopes.contains(OidcScopes.PHONE)) { | |||
builder.phoneNumber("13728903134").phoneNumberVerified("false"); | |||
} | |||
} | |||
return builder.build(); | |||
} | |||
} |
@@ -0,0 +1,14 @@ | |||
package com.tuoheng.service; | |||
import com.tuoheng.model.param.CreateUserDto; | |||
import com.tuoheng.until.JsonResult; | |||
/** | |||
* @author chenjiandong | |||
* @description: TODO | |||
* @date 2022/10/8 11:35 | |||
*/ | |||
public interface UserSevice { | |||
JsonResult createUser(CreateUserDto createUserDto); | |||
} |
@@ -0,0 +1,32 @@ | |||
package com.tuoheng.service.impl; | |||
import com.tuoheng.model.param.CreateUserDto; | |||
import com.tuoheng.service.UserSevice; | |||
import com.tuoheng.until.JsonResult; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.security.core.userdetails.User; | |||
import org.springframework.security.core.userdetails.UserDetails; | |||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | |||
import org.springframework.security.provisioning.UserDetailsManager; | |||
import org.springframework.stereotype.Service; | |||
/** | |||
* @author chenjiandong | |||
* @description: TODO | |||
* @date 2022/10/8 11:35 | |||
*/ | |||
@Service | |||
public class UserServiceImpl implements UserSevice { | |||
public JsonResult createUser(CreateUserDto createUserDto){ | |||
// UserDetails userDetails = User.builder().passwordEncoder(s -> "{bcrypt}" + new BCryptPasswordEncoder().encode(s)) | |||
// .username("admin") | |||
// .password("123456") | |||
// .roles("ADMIN") | |||
// .build(); | |||
// UserDetailsManager userDetailsManager = new UserDetailsManager(); | |||
// userDetailsManager.createUser(userDetails); | |||
return JsonResult.success(); | |||
} | |||
} |
@@ -0,0 +1,32 @@ | |||
package com.tuoheng.until; | |||
import org.apache.tomcat.util.codec.binary.Base64; | |||
import javax.crypto.KeyGenerator; | |||
import javax.crypto.SecretKey; | |||
import java.security.NoSuchAlgorithmException; | |||
/** | |||
* @author chenjiandong | |||
* @description: TODO | |||
* @date 2022/9/30 10:56 | |||
*/ | |||
public class CryptoUtil { | |||
public static String genAesSecret() { | |||
try { | |||
KeyGenerator kg = KeyGenerator.getInstance("AES"); | |||
//下面调用方法的参数决定了生成密钥的长度,可以修改为128, 192或256 | |||
kg.init(128); | |||
SecretKey sk = kg.generateKey(); | |||
byte[] b = sk.getEncoded(); | |||
String secret = Base64.encodeBase64String(b); | |||
return secret; | |||
} catch (NoSuchAlgorithmException e) { | |||
e.printStackTrace(); | |||
throw new RuntimeException("没有此算法"); | |||
} | |||
} | |||
} |
@@ -0,0 +1,99 @@ | |||
package com.tuoheng.until; | |||
import java.io.Serializable; | |||
/** | |||
* JSON回应类 | |||
* | |||
* @author 牧羊人 | |||
* @date 2019/11/28 | |||
*/ | |||
public class JsonResult<T> implements Serializable { | |||
private static final long serialVersionUID = 1L; | |||
/** | |||
* 成功 | |||
*/ | |||
public static final int SUCCESS = 0; | |||
/** | |||
* 失败 | |||
*/ | |||
public static final int ERROR = -1; | |||
private int code; | |||
private String msg; | |||
private T data; | |||
public static <T> JsonResult<T> success() { | |||
return jsonResult(null, SUCCESS, "操作成功"); | |||
} | |||
public static <T> JsonResult<T> success(String msg) { | |||
return jsonResult(null, SUCCESS, msg); | |||
} | |||
public static <T> JsonResult<T> success(T data) { | |||
return jsonResult(data, SUCCESS, "操作成功"); | |||
} | |||
public static <T> JsonResult<T> success(T data, String msg) { | |||
return jsonResult(data, SUCCESS, msg); | |||
} | |||
public static <T> JsonResult<T> error() { | |||
return jsonResult(null, ERROR, "操作失败"); | |||
} | |||
public static <T> JsonResult<T> error(String msg) { | |||
return jsonResult(null, ERROR, msg); | |||
} | |||
public static <T> JsonResult<T> error(T data) { | |||
return jsonResult(data, ERROR, "操作失败"); | |||
} | |||
public static <T> JsonResult<T> error(T data, String msg) { | |||
return jsonResult(data, ERROR, msg); | |||
} | |||
public static <T> JsonResult<T> error(int code, String msg) { | |||
return jsonResult(null, code, msg); | |||
} | |||
private static <T> JsonResult<T> jsonResult(T data, int code, String msg) { | |||
JsonResult<T> result = new JsonResult<>(); | |||
result.setCode(code); | |||
result.setData(data); | |||
result.setMsg(msg); | |||
return result; | |||
} | |||
public int getCode() { | |||
return code; | |||
} | |||
public void setCode(int code) { | |||
this.code = code; | |||
} | |||
public String getMsg() { | |||
return msg; | |||
} | |||
public void setMsg(String msg) { | |||
this.msg = msg; | |||
} | |||
public T getData() { | |||
return data; | |||
} | |||
public void setData(T data) { | |||
this.data = data; | |||
} | |||
} |
@@ -0,0 +1,52 @@ | |||
package com.tuoheng.until; | |||
import org.springframework.security.oauth2.core.AuthorizationGrantType; | |||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod; | |||
import org.springframework.security.oauth2.core.OAuth2TokenFormat; | |||
import org.springframework.security.oauth2.core.oidc.OidcScopes; | |||
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm; | |||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; | |||
import org.springframework.security.oauth2.server.authorization.config.ClientSettings; | |||
import org.springframework.security.oauth2.server.authorization.config.TokenSettings; | |||
import java.time.Duration; | |||
import java.util.UUID; | |||
/** | |||
* @author chenjiandong | |||
* @description: TODO | |||
* @date 2022/9/30 10:31 | |||
*/ | |||
public class RegisteredClientUtil { | |||
public static RegisteredClient getRegisteredClient(){ | |||
RegisteredClient registeredClient = RegisteredClient.withId("1001") | |||
.clientId("tuoheng-hhz") | |||
.clientName("tuoheng-hhz-client") | |||
.clientSecret("{noop}" + CryptoUtil.genAesSecret()) | |||
.clientAuthenticationMethods(s -> { | |||
s.add(ClientAuthenticationMethod.CLIENT_SECRET_POST); | |||
s.add(ClientAuthenticationMethod.CLIENT_SECRET_BASIC); | |||
}) | |||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) | |||
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) | |||
.redirectUri("http://www.baidu.com") | |||
.scope(OidcScopes.OPENID) | |||
.scope(OidcScopes.PROFILE) | |||
.scope(OidcScopes.EMAIL) | |||
.clientSettings(ClientSettings.builder() | |||
.requireAuthorizationConsent(true) | |||
.requireProofKey(false) | |||
.build()) | |||
.tokenSettings(TokenSettings.builder() | |||
.accessTokenFormat(OAuth2TokenFormat.SELF_CONTAINED) | |||
.idTokenSignatureAlgorithm(SignatureAlgorithm.RS256) | |||
.accessTokenTimeToLive(Duration.ofMinutes(30)) | |||
.refreshTokenTimeToLive(Duration.ofDays(7)) | |||
.reuseRefreshTokens(true) | |||
.build()) | |||
.build(); | |||
return registeredClient; | |||
} | |||
} |
@@ -0,0 +1,37 @@ | |||
spring: | |||
security: | |||
oauth2: | |||
resource-server: | |||
jwt: | |||
issuer-uri: http://192.168.11.11:8090 #认证中心端点,作为资源端的配置 | |||
# 配置数据源 | |||
datasource: | |||
# 使用阿里的Druid连接池 | |||
type: com.alibaba.druid.pool.DruidDataSource | |||
driver-class-name: com.mysql.cj.jdbc.Driver | |||
# 填写你数据库的url、登录名、密码和数据库名 | |||
url: jdbc:mysql://192.168.11.13:3306/tuoheng_oidc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8&useSSL=true&tinyInt1isBit=false | |||
username: root | |||
password: idontcare | |||
druid: | |||
# 连接池的配置信息 | |||
# 初始连接数 | |||
initialSize: 5 | |||
# 最小连接池数量 | |||
minIdle: 5 | |||
# 最大连接池数量 | |||
maxActive: 20 | |||
# 配置获取连接等待超时的时间 | |||
maxWait: 60000 | |||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 | |||
timeBetweenEvictionRunsMillis: 60000 | |||
# 配置一个连接在池中最小生存的时间,单位是毫秒 | |||
minEvictableIdleTimeMillis: 300000 | |||
# 配置一个连接在池中最大生存的时间,单位是毫秒 | |||
maxEvictableIdleTimeMillis: 900000 | |||
# 配置检测连接是否有效 | |||
validationQuery: SELECT 1 FROM DUAL | |||
testWhileIdle: true | |||
testOnBorrow: false | |||
testOnReturn: false |
@@ -0,0 +1,37 @@ | |||
spring: | |||
security: | |||
oauth2: | |||
resource-server: | |||
jwt: | |||
issuer-uri: http://127.0.0.1:8090 #认证中心端点,作为资源端的配置、 | |||
# 配置数据源 | |||
datasource: | |||
# 使用阿里的Druid连接池 | |||
type: com.alibaba.druid.pool.DruidDataSource | |||
driver-class-name: com.mysql.cj.jdbc.Driver | |||
# 填写你数据库的url、登录名、密码和数据库名 | |||
url: jdbc:mysql://192.168.11.13:3306/tuoheng_oidc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8&useSSL=true&tinyInt1isBit=false | |||
username: root | |||
password: idontcare | |||
druid: | |||
# 连接池的配置信息 | |||
# 初始连接数 | |||
initialSize: 5 | |||
# 最小连接池数量 | |||
minIdle: 5 | |||
# 最大连接池数量 | |||
maxActive: 20 | |||
# 配置获取连接等待超时的时间 | |||
maxWait: 60000 | |||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 | |||
timeBetweenEvictionRunsMillis: 60000 | |||
# 配置一个连接在池中最小生存的时间,单位是毫秒 | |||
minEvictableIdleTimeMillis: 300000 | |||
# 配置一个连接在池中最大生存的时间,单位是毫秒 | |||
maxEvictableIdleTimeMillis: 900000 | |||
# 配置检测连接是否有效 | |||
validationQuery: SELECT 1 FROM DUAL | |||
testWhileIdle: true | |||
testOnBorrow: false | |||
testOnReturn: false |
@@ -0,0 +1,6 @@ | |||
spring: | |||
security: | |||
oauth2: | |||
resource-server: | |||
jwt: | |||
issuer-uri: http://127.0.0.1:8090 #认证中心端点,作为资源端的配置 |
@@ -0,0 +1,6 @@ | |||
spring: | |||
security: | |||
oauth2: | |||
resource-server: | |||
jwt: | |||
issuer-uri: http://127.0.0.1:8090 #认证中心端点,作为资源端的配置 |
@@ -0,0 +1,6 @@ | |||
server: | |||
port: 8090 | |||
spring: | |||
profiles: | |||
active: @package.environment@ |
@@ -0,0 +1,10 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||
<mapper namespace="com.tuoheng.mapper.UserMapper"> | |||
<insert id="insertUser" parameterType="com.tuoheng.model.po.UserPo"> | |||
insert into users (username, password, enabled, client_id) | |||
values (#{aName,jdbcType=VARCHAR}, #{aPass,jdbcType=VARCHAR}) | |||
</insert> | |||
</mapper> |
@@ -0,0 +1,13 @@ | |||
package com.tuoheng; | |||
import org.junit.jupiter.api.Test; | |||
import org.springframework.boot.test.context.SpringBootTest; | |||
@SpringBootTest | |||
class SpringAuthorizationServerApplicationTests { | |||
@Test | |||
void contextLoads() { | |||
} | |||
} |
@@ -0,0 +1,38 @@ | |||
package com.tuoheng.config; | |||
import org.junit.jupiter.api.Test; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.boot.test.context.SpringBootTest; | |||
import org.springframework.security.core.userdetails.User; | |||
import org.springframework.security.core.userdetails.UserDetails; | |||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | |||
import org.springframework.security.provisioning.UserDetailsManager; | |||
/** | |||
* @author chenjiandong | |||
* @description: TODO | |||
* @date 2022/10/8 11:05 | |||
*/ | |||
@SpringBootTest | |||
class ApplicationTests { | |||
/** | |||
* 初始化客户端信息 | |||
*/ | |||
@Autowired | |||
private UserDetailsManager userDetailsManager; | |||
/** | |||
* 创建用户信息 | |||
*/ | |||
@Test | |||
void testSaveUser() { | |||
UserDetails userDetails = User.builder().passwordEncoder(s -> "{bcrypt}" + new BCryptPasswordEncoder().encode(s)) | |||
.username("admin") | |||
.password("123456") | |||
.roles("ADMIN") | |||
.build(); | |||
userDetailsManager.createUser(userDetails); | |||
} | |||
} |
@@ -0,0 +1,316 @@ | |||
#!/bin/sh | |||
# ---------------------------------------------------------------------------- | |||
# Licensed to the Apache Software Foundation (ASF) under one | |||
# or more contributor license agreements. See the NOTICE file | |||
# distributed with this work for additional information | |||
# regarding copyright ownership. The ASF licenses this file | |||
# to you under the Apache License, Version 2.0 (the | |||
# "License"); you may not use this file except in compliance | |||
# with the License. You may obtain a copy of the License at | |||
# | |||
# https://www.apache.org/licenses/LICENSE-2.0 | |||
# | |||
# Unless required by applicable law or agreed to in writing, | |||
# software distributed under the License is distributed on an | |||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |||
# KIND, either express or implied. See the License for the | |||
# specific language governing permissions and limitations | |||
# under the License. | |||
# ---------------------------------------------------------------------------- | |||
# ---------------------------------------------------------------------------- | |||
# Maven Start Up Batch script | |||
# | |||
# Required ENV vars: | |||
# ------------------ | |||
# JAVA_HOME - location of a JDK home dir | |||
# | |||
# Optional ENV vars | |||
# ----------------- | |||
# M2_HOME - location of maven2's installed home dir | |||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven | |||
# e.g. to debug Maven itself, use | |||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 | |||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files | |||
# ---------------------------------------------------------------------------- | |||
if [ -z "$MAVEN_SKIP_RC" ] ; then | |||
if [ -f /usr/local/etc/mavenrc ] ; then | |||
. /usr/local/etc/mavenrc | |||
fi | |||
if [ -f /etc/mavenrc ] ; then | |||
. /etc/mavenrc | |||
fi | |||
if [ -f "$HOME/.mavenrc" ] ; then | |||
. "$HOME/.mavenrc" | |||
fi | |||
fi | |||
# OS specific support. $var _must_ be set to either true or false. | |||
cygwin=false; | |||
darwin=false; | |||
mingw=false | |||
case "`uname`" in | |||
CYGWIN*) cygwin=true ;; | |||
MINGW*) mingw=true;; | |||
Darwin*) darwin=true | |||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home | |||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html | |||
if [ -z "$JAVA_HOME" ]; then | |||
if [ -x "/usr/libexec/java_home" ]; then | |||
export JAVA_HOME="`/usr/libexec/java_home`" | |||
else | |||
export JAVA_HOME="/Library/Java/Home" | |||
fi | |||
fi | |||
;; | |||
esac | |||
if [ -z "$JAVA_HOME" ] ; then | |||
if [ -r /etc/gentoo-release ] ; then | |||
JAVA_HOME=`java-config --jre-home` | |||
fi | |||
fi | |||
if [ -z "$M2_HOME" ] ; then | |||
## resolve links - $0 may be a link to maven's home | |||
PRG="$0" | |||
# need this for relative symlinks | |||
while [ -h "$PRG" ] ; do | |||
ls=`ls -ld "$PRG"` | |||
link=`expr "$ls" : '.*-> \(.*\)$'` | |||
if expr "$link" : '/.*' > /dev/null; then | |||
PRG="$link" | |||
else | |||
PRG="`dirname "$PRG"`/$link" | |||
fi | |||
done | |||
saveddir=`pwd` | |||
M2_HOME=`dirname "$PRG"`/.. | |||
# make it fully qualified | |||
M2_HOME=`cd "$M2_HOME" && pwd` | |||
cd "$saveddir" | |||
# echo Using m2 at $M2_HOME | |||
fi | |||
# For Cygwin, ensure paths are in UNIX format before anything is touched | |||
if $cygwin ; then | |||
[ -n "$M2_HOME" ] && | |||
M2_HOME=`cygpath --unix "$M2_HOME"` | |||
[ -n "$JAVA_HOME" ] && | |||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"` | |||
[ -n "$CLASSPATH" ] && | |||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"` | |||
fi | |||
# For Mingw, ensure paths are in UNIX format before anything is touched | |||
if $mingw ; then | |||
[ -n "$M2_HOME" ] && | |||
M2_HOME="`(cd "$M2_HOME"; pwd)`" | |||
[ -n "$JAVA_HOME" ] && | |||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" | |||
fi | |||
if [ -z "$JAVA_HOME" ]; then | |||
javaExecutable="`which javac`" | |||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then | |||
# readlink(1) is not available as standard on Solaris 10. | |||
readLink=`which readlink` | |||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then | |||
if $darwin ; then | |||
javaHome="`dirname \"$javaExecutable\"`" | |||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" | |||
else | |||
javaExecutable="`readlink -f \"$javaExecutable\"`" | |||
fi | |||
javaHome="`dirname \"$javaExecutable\"`" | |||
javaHome=`expr "$javaHome" : '\(.*\)/bin'` | |||
JAVA_HOME="$javaHome" | |||
export JAVA_HOME | |||
fi | |||
fi | |||
fi | |||
if [ -z "$JAVACMD" ] ; then | |||
if [ -n "$JAVA_HOME" ] ; then | |||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | |||
# IBM's JDK on AIX uses strange locations for the executables | |||
JAVACMD="$JAVA_HOME/jre/sh/java" | |||
else | |||
JAVACMD="$JAVA_HOME/bin/java" | |||
fi | |||
else | |||
JAVACMD="`\\unset -f command; \\command -v java`" | |||
fi | |||
fi | |||
if [ ! -x "$JAVACMD" ] ; then | |||
echo "Error: JAVA_HOME is not defined correctly." >&2 | |||
echo " We cannot execute $JAVACMD" >&2 | |||
exit 1 | |||
fi | |||
if [ -z "$JAVA_HOME" ] ; then | |||
echo "Warning: JAVA_HOME environment variable is not set." | |||
fi | |||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher | |||
# traverses directory structure from process work directory to filesystem root | |||
# first directory with .mvn subdirectory is considered project base directory | |||
find_maven_basedir() { | |||
if [ -z "$1" ] | |||
then | |||
echo "Path not specified to find_maven_basedir" | |||
return 1 | |||
fi | |||
basedir="$1" | |||
wdir="$1" | |||
while [ "$wdir" != '/' ] ; do | |||
if [ -d "$wdir"/.mvn ] ; then | |||
basedir=$wdir | |||
break | |||
fi | |||
# workaround for JBEAP-8937 (on Solaris 10/Sparc) | |||
if [ -d "${wdir}" ]; then | |||
wdir=`cd "$wdir/.."; pwd` | |||
fi | |||
# end of workaround | |||
done | |||
echo "${basedir}" | |||
} | |||
# concatenates all lines of a file | |||
concat_lines() { | |||
if [ -f "$1" ]; then | |||
echo "$(tr -s '\n' ' ' < "$1")" | |||
fi | |||
} | |||
BASE_DIR=`find_maven_basedir "$(pwd)"` | |||
if [ -z "$BASE_DIR" ]; then | |||
exit 1; | |||
fi | |||
########################################################################################## | |||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central | |||
# This allows using the maven wrapper in projects that prohibit checking in binary data. | |||
########################################################################################## | |||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then | |||
if [ "$MVNW_VERBOSE" = true ]; then | |||
echo "Found .mvn/wrapper/maven-wrapper.jar" | |||
fi | |||
else | |||
if [ "$MVNW_VERBOSE" = true ]; then | |||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." | |||
fi | |||
if [ -n "$MVNW_REPOURL" ]; then | |||
jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" | |||
else | |||
jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" | |||
fi | |||
while IFS="=" read key value; do | |||
case "$key" in (wrapperUrl) jarUrl="$value"; break ;; | |||
esac | |||
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" | |||
if [ "$MVNW_VERBOSE" = true ]; then | |||
echo "Downloading from: $jarUrl" | |||
fi | |||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" | |||
if $cygwin; then | |||
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` | |||
fi | |||
if command -v wget > /dev/null; then | |||
if [ "$MVNW_VERBOSE" = true ]; then | |||
echo "Found wget ... using wget" | |||
fi | |||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then | |||
wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" | |||
else | |||
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" | |||
fi | |||
elif command -v curl > /dev/null; then | |||
if [ "$MVNW_VERBOSE" = true ]; then | |||
echo "Found curl ... using curl" | |||
fi | |||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then | |||
curl -o "$wrapperJarPath" "$jarUrl" -f | |||
else | |||
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f | |||
fi | |||
else | |||
if [ "$MVNW_VERBOSE" = true ]; then | |||
echo "Falling back to using Java to download" | |||
fi | |||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" | |||
# For Cygwin, switch paths to Windows format before running javac | |||
if $cygwin; then | |||
javaClass=`cygpath --path --windows "$javaClass"` | |||
fi | |||
if [ -e "$javaClass" ]; then | |||
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then | |||
if [ "$MVNW_VERBOSE" = true ]; then | |||
echo " - Compiling MavenWrapperDownloader.java ..." | |||
fi | |||
# Compiling the Java class | |||
("$JAVA_HOME/bin/javac" "$javaClass") | |||
fi | |||
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then | |||
# Running the downloader | |||
if [ "$MVNW_VERBOSE" = true ]; then | |||
echo " - Running MavenWrapperDownloader.java ..." | |||
fi | |||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") | |||
fi | |||
fi | |||
fi | |||
fi | |||
########################################################################################## | |||
# End of extension | |||
########################################################################################## | |||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} | |||
if [ "$MVNW_VERBOSE" = true ]; then | |||
echo $MAVEN_PROJECTBASEDIR | |||
fi | |||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" | |||
# For Cygwin, switch paths to Windows format before running java | |||
if $cygwin; then | |||
[ -n "$M2_HOME" ] && | |||
M2_HOME=`cygpath --path --windows "$M2_HOME"` | |||
[ -n "$JAVA_HOME" ] && | |||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` | |||
[ -n "$CLASSPATH" ] && | |||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"` | |||
[ -n "$MAVEN_PROJECTBASEDIR" ] && | |||
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` | |||
fi | |||
# Provide a "standardized" way to retrieve the CLI args that will | |||
# work with both Windows and non-Windows executions. | |||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" | |||
export MAVEN_CMD_LINE_ARGS | |||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain | |||
exec "$JAVACMD" \ | |||
$MAVEN_OPTS \ | |||
$MAVEN_DEBUG_OPTS \ | |||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ | |||
"-Dmaven.home=${M2_HOME}" \ | |||
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ | |||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" |
@@ -0,0 +1,188 @@ | |||
@REM ---------------------------------------------------------------------------- | |||
@REM Licensed to the Apache Software Foundation (ASF) under one | |||
@REM or more contributor license agreements. See the NOTICE file | |||
@REM distributed with this work for additional information | |||
@REM regarding copyright ownership. The ASF licenses this file | |||
@REM to you under the Apache License, Version 2.0 (the | |||
@REM "License"); you may not use this file except in compliance | |||
@REM with the License. You may obtain a copy of the License at | |||
@REM | |||
@REM https://www.apache.org/licenses/LICENSE-2.0 | |||
@REM | |||
@REM Unless required by applicable law or agreed to in writing, | |||
@REM software distributed under the License is distributed on an | |||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |||
@REM KIND, either express or implied. See the License for the | |||
@REM specific language governing permissions and limitations | |||
@REM under the License. | |||
@REM ---------------------------------------------------------------------------- | |||
@REM ---------------------------------------------------------------------------- | |||
@REM Maven Start Up Batch script | |||
@REM | |||
@REM Required ENV vars: | |||
@REM JAVA_HOME - location of a JDK home dir | |||
@REM | |||
@REM Optional ENV vars | |||
@REM M2_HOME - location of maven2's installed home dir | |||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands | |||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending | |||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven | |||
@REM e.g. to debug Maven itself, use | |||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 | |||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files | |||
@REM ---------------------------------------------------------------------------- | |||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' | |||
@echo off | |||
@REM set title of command window | |||
title %0 | |||
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' | |||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% | |||
@REM set %HOME% to equivalent of $HOME | |||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") | |||
@REM Execute a user defined script before this one | |||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre | |||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending | |||
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* | |||
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* | |||
:skipRcPre | |||
@setlocal | |||
set ERROR_CODE=0 | |||
@REM To isolate internal variables from possible post scripts, we use another setlocal | |||
@setlocal | |||
@REM ==== START VALIDATION ==== | |||
if not "%JAVA_HOME%" == "" goto OkJHome | |||
echo. | |||
echo Error: JAVA_HOME not found in your environment. >&2 | |||
echo Please set the JAVA_HOME variable in your environment to match the >&2 | |||
echo location of your Java installation. >&2 | |||
echo. | |||
goto error | |||
:OkJHome | |||
if exist "%JAVA_HOME%\bin\java.exe" goto init | |||
echo. | |||
echo Error: JAVA_HOME is set to an invalid directory. >&2 | |||
echo JAVA_HOME = "%JAVA_HOME%" >&2 | |||
echo Please set the JAVA_HOME variable in your environment to match the >&2 | |||
echo location of your Java installation. >&2 | |||
echo. | |||
goto error | |||
@REM ==== END VALIDATION ==== | |||
:init | |||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". | |||
@REM Fallback to current working directory if not found. | |||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% | |||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir | |||
set EXEC_DIR=%CD% | |||
set WDIR=%EXEC_DIR% | |||
:findBaseDir | |||
IF EXIST "%WDIR%"\.mvn goto baseDirFound | |||
cd .. | |||
IF "%WDIR%"=="%CD%" goto baseDirNotFound | |||
set WDIR=%CD% | |||
goto findBaseDir | |||
:baseDirFound | |||
set MAVEN_PROJECTBASEDIR=%WDIR% | |||
cd "%EXEC_DIR%" | |||
goto endDetectBaseDir | |||
:baseDirNotFound | |||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR% | |||
cd "%EXEC_DIR%" | |||
:endDetectBaseDir | |||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig | |||
@setlocal EnableExtensions EnableDelayedExpansion | |||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a | |||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% | |||
:endReadAdditionalConfig | |||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" | |||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" | |||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain | |||
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" | |||
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( | |||
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B | |||
) | |||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central | |||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data. | |||
if exist %WRAPPER_JAR% ( | |||
if "%MVNW_VERBOSE%" == "true" ( | |||
echo Found %WRAPPER_JAR% | |||
) | |||
) else ( | |||
if not "%MVNW_REPOURL%" == "" ( | |||
SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" | |||
) | |||
if "%MVNW_VERBOSE%" == "true" ( | |||
echo Couldn't find %WRAPPER_JAR%, downloading it ... | |||
echo Downloading from: %DOWNLOAD_URL% | |||
) | |||
powershell -Command "&{"^ | |||
"$webclient = new-object System.Net.WebClient;"^ | |||
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ | |||
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ | |||
"}"^ | |||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ | |||
"}" | |||
if "%MVNW_VERBOSE%" == "true" ( | |||
echo Finished downloading %WRAPPER_JAR% | |||
) | |||
) | |||
@REM End of extension | |||
@REM Provide a "standardized" way to retrieve the CLI args that will | |||
@REM work with both Windows and non-Windows executions. | |||
set MAVEN_CMD_LINE_ARGS=%* | |||
%MAVEN_JAVA_EXE% ^ | |||
%JVM_CONFIG_MAVEN_PROPS% ^ | |||
%MAVEN_OPTS% ^ | |||
%MAVEN_DEBUG_OPTS% ^ | |||
-classpath %WRAPPER_JAR% ^ | |||
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ | |||
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* | |||
if ERRORLEVEL 1 goto error | |||
goto end | |||
:error | |||
set ERROR_CODE=1 | |||
:end | |||
@endlocal & set ERROR_CODE=%ERROR_CODE% | |||
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost | |||
@REM check for post script, once with legacy .bat ending and once with .cmd ending | |||
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" | |||
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" | |||
:skipRcPost | |||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' | |||
if "%MAVEN_BATCH_PAUSE%"=="on" pause | |||
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% | |||
cmd /C exit /B %ERROR_CODE% |
@@ -0,0 +1,30 @@ | |||
Server端 项目 | |||
第一步:登录授权获取code: | |||
http://127.0.0.1:8090/oauth2/authorize? | |||
client_id=tuoheng-dsp | |||
&response_type=code | |||
&scope=openid+profile+email | |||
&redirect_uri=http://192.168.11.11:8086/home | |||
&state=4991a0e66547452286dd56e0d9473a0e | |||
扩展PKCE协议:(&code_challenge=IHicvKyz0IM1do9-3n9QpHf9xVluBshdD1vCD77gV7s&code_challenge_method=S256&response_mode=fragment) | |||
第二步:根据code获取token: | |||
http://127.0.0.1:8090/oauth2/token | |||
返回结果: | |||
{ | |||
"access_token": "eyJraWQiOiJhYjg4YTUyNS02ZTRiLTQ0ODMtYTA3MS1lODU1YzIwOGE1ZjkiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImF1ZCI6ImpzLnRva2VubWFuYWdlciIsIm5iZiI6MTY2MzY2MDQ3OSwic2NvcGUiOlsib3BlbmlkIiwicm9sZXMiLCJlbWFpbCJdLCJpc3MiOiJodHRwOlwvXC8xMjcuMC4wLjE6ODA5MCIsImV4cCI6MTY2MzY2NzY3OSwiaWF0IjoxNjYzNjYwNDc5fQ.hwbfRT-wl-YV3lfArRu_hqQsikk8EVxOpib50c_BZSEsdATOnucpKEtGE8bnQQD6NHim7bL7rQYwP7YyA94UBkMROFkN-tw3VL9BgNBG2OK5QxOVVsnTLnu1H890oboh_7L1VkdPeFwyj6XxgkakMS1mNWkyT_5TZJDs0kmN3dTojFc5LL-s1WVWBNRzZhyDEe6U-5o1kxoSk5G6sxwHIS750vPMZJqZlSUqqDR5Sl5GtwfkKVjdHvVWVaCxwwlK6ZjEAHA0H9sniF7rLqx0uIiwfPSFOLaEqSSe7-JANY76tkIvZYVDphyh2qGUn9aCgXx-LXi1oT7J2N1bTS8fJQ", | |||
"refresh_token": "8hKqtmtsUwoZEkJt5jxT302cyOV9lir7FAAjcSIZiaO588Vz4XrlOuyO1AdAYq90FTefeBpKPewWLlkPAU_OnPgWZU4JNxplXQ99yvGBBglkIkVSlApXk6PgmYvO1jlh", | |||
"scope": "openid roles email", | |||
"id_token": "eyJraWQiOiJhYjg4YTUyNS02ZTRiLTQ0ODMtYTA3MS1lODU1YzIwOGE1ZjkiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImF1ZCI6ImpzLnRva2VubWFuYWdlciIsImF6cCI6ImpzLnRva2VubWFuYWdlciIsImlzcyI6Imh0dHA6XC9cLzEyNy4wLjAuMTo4MDkwIiwiZXhwIjoxNjYzNjYyMjc5LCJpYXQiOjE2NjM2NjA0Nzl9.gNNXLQJlDxGiG8tWkt-z9rqnboCuv8-978-mvLSFXF5VpZyiO9gjbGRdlMDpsTFVYu9OdV1vq-4IpGZjh08JWCt051epJ-s4rnFoSWKQajY2Qq94X2ZrCGs7yJX8oQM6MrCZ12_LOmoV216pHOxz9XxQ5O2xXuFXZkFCHbQozGxhitlXWY0y-Ivio7GCVxjaNEBP_JFACzGiU4QH2lMytpg4GUWIvlAmjMg9cuoQqoOqY43CtEQaIfCZ38Qlenx0sfXrfLnF3ci6hnRcP8pnB2aVUEr6o3xRbKWExQaDGRK9SzGpWqNRfcjQ0FNmkuSglMg5gnj4A7yTqJE-KhXQaQ", | |||
"token_type": "Bearer", | |||
"expires_in": 7199 | |||
} | |||
第三步:根据token获取userinfo | |||
http://127.0.0.1:8090/userinfo | |||
{ | |||
"sub": "user", | |||
"email": "user@163.com", | |||
"email_verified": true | |||
} |
@@ -0,0 +1,41 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
<modelVersion>4.0.0</modelVersion> | |||
<parent> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-parent</artifactId> | |||
<version>2.7.3</version> | |||
<relativePath/> <!-- lookup parent from repository --> | |||
</parent> | |||
<groupId>com.tuoheng</groupId> | |||
<artifactId>tuoheng_oidc</artifactId> | |||
<version>0.0.1-SNAPSHOT</version> | |||
<name>tuoheng_oidc</name> | |||
<description>tuoheng_oidc</description> | |||
<properties> | |||
<java.version>1.8</java.version> | |||
</properties> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-test</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
</dependencies> | |||
<build> | |||
<plugins> | |||
<plugin> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-maven-plugin</artifactId> | |||
</plugin> | |||
</plugins> | |||
</build> | |||
</project> |