diff --git a/lab-68/lab-68-demo03-authorization-server-with-resource-owner-password-credentials/pom.xml b/lab-68/lab-68-demo03-authorization-server-with-resource-owner-password-credentials/pom.xml
new file mode 100644
index 00000000..c104d837
--- /dev/null
+++ b/lab-68/lab-68-demo03-authorization-server-with-resource-owner-password-credentials/pom.xml
@@ -0,0 +1,55 @@
+
+
+
+ lab-68
+ cn.iocoder.springboot.labs
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ lab-68-demo03-authorization-server-with-resource-owner-password-credentials
+
+
+
+ 2.2.4.RELEASE
+
+ 1.8
+ 1.8
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ ${spring.boot.version}
+ pom
+ import
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+
+
+
+
+
+
+ org.springframework.security.oauth.boot
+ spring-security-oauth2-autoconfigure
+ ${spring.boot.version}
+
+
+
+
diff --git a/lab-68/lab-68-demo03-authorization-server-with-resource-owner-password-credentials/src/main/java/cn/iocoder/springboot/lab68/authorizationserverdemo/AuthorizationServerApplication.java b/lab-68/lab-68-demo03-authorization-server-with-resource-owner-password-credentials/src/main/java/cn/iocoder/springboot/lab68/authorizationserverdemo/AuthorizationServerApplication.java
new file mode 100644
index 00000000..d08ae7c8
--- /dev/null
+++ b/lab-68/lab-68-demo03-authorization-server-with-resource-owner-password-credentials/src/main/java/cn/iocoder/springboot/lab68/authorizationserverdemo/AuthorizationServerApplication.java
@@ -0,0 +1,13 @@
+package cn.iocoder.springboot.lab68.authorizationserverdemo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class AuthorizationServerApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(AuthorizationServerApplication.class, args);
+ }
+
+}
diff --git a/lab-68/lab-68-demo03-authorization-server-with-resource-owner-password-credentials/src/main/java/cn/iocoder/springboot/lab68/authorizationserverdemo/config/OAuth2AuthorizationServerConfig.java b/lab-68/lab-68-demo03-authorization-server-with-resource-owner-password-credentials/src/main/java/cn/iocoder/springboot/lab68/authorizationserverdemo/config/OAuth2AuthorizationServerConfig.java
new file mode 100644
index 00000000..3247ef64
--- /dev/null
+++ b/lab-68/lab-68-demo03-authorization-server-with-resource-owner-password-credentials/src/main/java/cn/iocoder/springboot/lab68/authorizationserverdemo/config/OAuth2AuthorizationServerConfig.java
@@ -0,0 +1,51 @@
+package cn.iocoder.springboot.lab68.authorizationserverdemo.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
+import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
+import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
+
+/**
+ * 授权服务器配置
+ */
+@Configuration
+@EnableAuthorizationServer
+public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
+
+ /**
+ * 用户认证 Manager
+ */
+ @Autowired
+ private AuthenticationManager authenticationManager;
+
+ @Override
+ public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
+ endpoints.authenticationManager(authenticationManager);
+ }
+
+ @Override
+ public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
+ oauthServer.checkTokenAccess("isAuthenticated()");
+// oauthServer.tokenKeyAccess("isAuthenticated()")
+// .checkTokenAccess("isAuthenticated()");
+// oauthServer.tokenKeyAccess("permitAll()")
+// .checkTokenAccess("permitAll()");
+ }
+
+ @Override
+ public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
+ clients.inMemory()
+ .withClient("clientapp").secret("112233") // Client 账号、密码。
+ .authorizedGrantTypes("password", "refresh_token") // 密码模式
+ .scopes("read_userinfo", "read_contacts") // 可授权的 Scope
+ .accessTokenValiditySeconds(3600) // 访问令牌的有效期为 3600 秒 = 2 小时
+ .refreshTokenValiditySeconds(864000) // 刷新令牌的有效期为 864000 秒 = 10 天
+// .and().withClient() // 可以继续配置新的 Client
+ ;
+ }
+
+}
diff --git a/lab-68/lab-68-demo03-authorization-server-with-resource-owner-password-credentials/src/main/java/cn/iocoder/springboot/lab68/authorizationserverdemo/config/SecurityConfig.java b/lab-68/lab-68-demo03-authorization-server-with-resource-owner-password-credentials/src/main/java/cn/iocoder/springboot/lab68/authorizationserverdemo/config/SecurityConfig.java
new file mode 100644
index 00000000..9da10ba5
--- /dev/null
+++ b/lab-68/lab-68-demo03-authorization-server-with-resource-owner-password-credentials/src/main/java/cn/iocoder/springboot/lab68/authorizationserverdemo/config/SecurityConfig.java
@@ -0,0 +1,38 @@
+package cn.iocoder.springboot.lab68.authorizationserverdemo.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.BeanIds;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.crypto.password.NoOpPasswordEncoder;
+
+@Configuration
+@EnableWebSecurity
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Override
+ @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
+ public AuthenticationManager authenticationManagerBean() throws Exception {
+ return super.authenticationManagerBean();
+ }
+
+ @Bean
+ public static NoOpPasswordEncoder passwordEncoder() {
+ return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
+ }
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ auth.
+ // 使用内存中的 InMemoryUserDetailsManager
+ inMemoryAuthentication()
+ // 不使用 PasswordEncoder 密码编码器
+ .passwordEncoder(passwordEncoder())
+ // 配置 yunai 用户
+ .withUser("yunai").password("1024").roles("USER");
+ }
+
+}
diff --git a/lab-68/pom.xml b/lab-68/pom.xml
index cefd083f..5faae9d3 100644
--- a/lab-68/pom.xml
+++ b/lab-68/pom.xml
@@ -22,6 +22,8 @@
lab-68-demo02-authorization-server-with-authorization-code
lab-68-demo02-authorization-server-with-implicit
lab-68-demo02-authorization-server-with-client-credentials
+
+ lab-68-demo03-authorization-server-with-resource-owner-password-credentials