- 创建父工程mengxuegu-cloud-oauth2-parent
| <packaging>pom</packaging> |
| <parent> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-parent</artifactId> |
| <version>2.2.2.RELEASE</version> |
| <relativePath/> |
| </parent> |
| <properties> |
| <spring-cloud.version>Hoxton.RELEASE</spring-cloud.version> |
| <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| <maven.compiler.source>1.8</maven.compiler.source> |
| <maven.compiler.target>1.8</maven.compiler.target> |
| <mybatis-plus.version>3.2.0</mybatis-plus.version> |
| <druid.version>1.1.12</druid.version> |
| <kaptcha.version>2.3.2</kaptcha.version> |
| <fastjson.version>1.2.8</fastjson.version> |
| <commons-lang.version>2.6</commons-lang.version> |
| <commons-collections.version>3.2.2</commons-collections.version> |
| <commons-io.version>2.6</commons-io.version> |
| |
| <mengxuegu-security.version>1.0-SNAPSHOT</mengxuegu-security.version> |
| </properties> |
| |
| <dependencyManagement> |
| <dependencies> |
| <dependency> |
| <groupId>org.springframework.cloud</groupId> |
| <artifactId>spring-cloud-dependencies</artifactId> |
| <version>${spring-cloud.version}</version> |
| <type>pom</type> |
| |
| <scope>import</scope> |
| </dependency> |
| |
| <dependency> |
| <groupId>com.baomidou</groupId> |
| <artifactId>mybatis-plus-boot-starter</artifactId> |
| <version>${mybatis-plus.version}</version> |
| </dependency> |
| |
| <dependency> |
| <groupId>com.alibaba</groupId> |
| <artifactId>druid</artifactId> |
| <version>${druid.version}</version> |
| </dependency> |
| |
| <dependency> |
| <groupId>com.github.penggle</groupId> |
| <artifactId>kaptcha</artifactId> |
| <version>${kaptcha.version}</version> |
| </dependency> |
| |
| <dependency> |
| <groupId>com.alibaba</groupId> |
| <artifactId>fastjson</artifactId> |
| <version>${fastjson.version}</version> |
| </dependency> |
| <dependency> |
| <groupId>commons-lang</groupId> |
| <artifactId>commons-lang</artifactId> |
| <version>${commons-lang.version}</version> |
| </dependency> |
| <dependency> |
| <groupId>commons-collections</groupId> |
| <artifactId>commons-collections</artifactId> |
| <version>${commons-collections.version}</version> |
| </dependency> |
| <dependency> |
| <groupId>commons-io</groupId> |
| <artifactId>commons-io</artifactId> |
| <version>${commons-io.version}</version> |
| </dependency> |
| </dependencies> |
| </dependencyManagement> |
| <build> |
| <plugins> |
| <plugin> |
| <groupId>org.apache.maven.plugins</groupId> |
| <artifactId>maven-compiler-plugin</artifactId> |
| <version>3.7.0</version> |
| <configuration> |
| <source>1.8</source> |
| <target>1.8</target> |
| <encoding>UTF-8</encoding> |
| </configuration> |
| </plugin> |
| |
| <plugin> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-maven-plugin</artifactId> |
| </plugin> |
| </plugins> |
| </build> |
- 创建子模块mengxuegu-cloud-oauth2-base
| <dependencies> |
| |
| <dependency> |
| <groupId>org.projectlombok</groupId> |
| <artifactId>lombok</artifactId> |
| </dependency> |
| |
| <dependency> |
| <groupId>com.alibaba</groupId> |
| <artifactId>fastjson</artifactId> |
| </dependency> |
| <dependency> |
| <groupId>commons-lang</groupId> |
| <artifactId>commons-lang</artifactId> |
| </dependency> |
| <dependency> |
| <groupId>commons-collections</groupId> |
| <artifactId>commons-collections</artifactId> |
| </dependency> |
| <dependency> |
| <groupId>commons-io</groupId> |
| <artifactId>commons-io</artifactId> |
| </dependency> |
| </dependencies> |
| <?xml version="1.0" encoding="UTF-8"?> |
| |
| <configuration> |
| |
| |
| <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" /> |
| <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" /> |
| <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" /> |
| |
| <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/> |
| |
| <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"> |
| <layout class="ch.qos.logback.classic.PatternLayout"> |
| <pattern>${CONSOLE_LOG_PATTERN}</pattern> |
| </layout> |
| </appender> |
| |
| <root level="info"> |
| <appender-ref ref="stdout" /> |
| </root> |
| </configuration> |
- 在com.mengxuegu.base.result路径下编写MengxueguResult
| @Data |
| public class MengxueguResult implements Serializable { |
| |
| private Integer code; |
| |
| private String message; |
| |
| private Object data; |
| public MengxueguResult() { |
| } |
| public MengxueguResult(Object data) { |
| this.code = 200; |
| this.message = "OK"; |
| this.data = data; |
| } |
| public MengxueguResult(String message, Object data) { |
| this.code = 200; |
| this.message = message; |
| this.data = data; |
| } |
| public MengxueguResult(Integer code, String message, Object data) { |
| this.code = code; |
| this.message = message; |
| this.data = data; |
| } |
| public static MengxueguResult ok() { |
| return new MengxueguResult(null); |
| } |
| public static MengxueguResult ok(String message) { |
| return new MengxueguResult(message, null); |
| } |
| public static MengxueguResult ok(Object data) { |
| return new MengxueguResult(data); |
| } |
| public static MengxueguResult ok(String message, Object data) { |
| return new MengxueguResult(message, data); |
| } |
| public static MengxueguResult build(Integer code, String message) { |
| return new MengxueguResult(code, message, null); |
| } |
| public static MengxueguResult build(Integer code, String message, Object data) { |
| return new MengxueguResult(code, message, data); |
| } |
| public String toJsonString() { |
| return JSON.toJSONString(this); |
| } |
| |
| |
| |
| |
| |
| public static MengxueguResult format(String json) { |
| try { |
| return JSON.parseObject(json, MengxueguResult.class); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| return null; |
| } |
| } |
- 创建子模块mengxuegu-cloud-oauth2-server
| <dependencies> |
| <dependency> |
| <groupId>com.mengxuegu</groupId> |
| <artifactId>mengxuegu-cloud-oauth2-base</artifactId> |
| <version>${mengxuegu-security.version}</version> |
| </dependency> |
| |
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-web</artifactId> |
| </dependency> |
| |
| <dependency> |
| <groupId>org.springframework.cloud</groupId> |
| <artifactId>spring-cloud-starter-oauth2</artifactId> |
| </dependency> |
| |
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-test</artifactId> |
| </dependency> |
| |
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-devtools</artifactId> |
| </dependency> |
| </dependencies> |
| <build> |
| <plugins> |
| <plugin> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-maven-plugin</artifactId> |
| |
| <configuration> |
| <mainClass>com.mengxuegu.oauth2.AuthServerApplication</mainClass> |
| </configuration> |
| |
| </plugin> |
| </plugins> |
| </build> |
| server: |
| port: 8090 |
| servlet: |
| context-path: /auth |
- com.mengxuegu.oauth2路径下编写启动类
| @SpringBootApplication |
| public class AuthServerApplication { |
| public static void main(String[] args) { |
| SpringApplication.run(AuthServerApplication.class, args); |
| } |
| } |
| @Configuration |
| @EnableAuthorizationServer |
| public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { |
| @Autowired |
| private PasswordEncoder passwordEncoder; |
| |
| |
| |
| |
| |
| |
| |
| @Override |
| public void configure(ClientDetailsServiceConfigurer clients) throws Exception { |
| |
| clients.inMemory() |
| .withClient("mengxuegu-pc") |
| .secret(passwordEncoder.encode("mengxuegu-secret")) |
| .resourceIds("product-server") |
| .authorizedGrantTypes("authorization_code", "password", "implicit", "client_credentials", "refresh_token") |
| .scopes("all") |
| .autoApprove(false) |
| .redirectUris("http://www.mengxuegu.com/") |
| ; |
| } |
| } |
| |
| @Configuration |
| public class SpringSecurityBean { |
| @Bean |
| public PasswordEncoder passwordEncoder(){ |
| return new BCryptPasswordEncoder(); |
| } |
| } |
| |
| @EnableWebSecurity |
| public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { |
| @Autowired |
| private PasswordEncoder passwordEncoder; |
| @Override |
| protected void configure(AuthenticationManagerBuilder auth) throws Exception { |
| auth.inMemoryAuthentication() |
| .withUser("admin").password(passwordEncoder.encode("1234")) |
| .authorities("product"); |
| } |
| } |
| |
| http://localhost:8090/auth/oauth/authorize?client_id=mengxuegu-pc&response_type=code |
| |
| |
| http://localhost:8090/auth/oauth/authorize?client_id=mengxuegu-pc&response_type=code |





| # SpringSecurityConfig类中添加如下 |
| @Bean |
| @Override |
| public AuthenticationManager authenticationManagerBean() throws Exception { |
| return super.authenticationManagerBean(); |
| } |
| |
| # AuthorizationServerConfig类中添加如下 |
| @Autowired |
| private AuthenticationManager authenticationManager; |
| @Override |
| public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { |
| |
| endpoints.authenticationManager(authenticationManager); |
| } |
| |
-
postman测试


-
简单模式
| |
| http://localhost:8090/auth/oauth/authorize?client_id=mengxuegu-pc&response_type=token |

-
客户端模式

-
使用redis管理访问令牌
| # 添加依赖 |
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-data-redis</artifactId> |
| </dependency> |
| |
| # 编写TokenConfig |
| @Configuration |
| public class TokenConfig { |
| @Autowired |
| private RedisConnectionFactory redisConnectionFactory; |
| @Bean |
| public TokenStore tokenStore() { |
| |
| return new RedisTokenStore(redisConnectionFactory); |
| } |
| } |
| |
| # AuthorizationServerConfig配置如下 |
| @Autowired |
| private TokenStore tokenStore; |
| |
| @Override |
| public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { |
| |
| endpoints.tokenStore(tokenStore); |
| } |
- 本地启动redis测试
- 由于我本地没有安装redis
| |
| spring: |
| redis: |
| database: 0 |
| host: 124.222.5.107 |
| port: 6379 |
| password: 123456 |
| |
| |
| |
| |
| |
| |
| |
| timeout: 2000 |
| Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 124.222.5.107:6379 |
---分割线
| # pom |
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-data-redis</artifactId> |
| </dependency> |
| <dependency> |
| <groupId>org.apache.commons</groupId> |
| <artifactId>commons-pool2</artifactId> |
| </dependency> |
| |
| # yml |
| spring: |
| application: |
| name: security-demo |
| redis: |
| host: 192.168.1.102 |
| port: 6379 |
| # password: 没有不用写 |
| lettuce: |
| # 连接池配置 |
| pool: |
| # 连接池中的最小空闲连接,默认 0 |
| min-idle: 0 |
| # 连接池中的最大空闲连接,默认 8 |
| max-idle: 8 |
| # 连接池最大阻塞等待时间(使用负值表示没有限制),默认 -1ms |
| max-wait: -1ms |
| # 连接池最大连接数(使用负值表示没有限制),默认 8 |
| max-active: 8 |
| |
| # 编写TokenConfig |
| @Configuration |
| public class TokenConfig { |
| @Autowired |
| private RedisConnectionFactory redisConnectionFactory; |
| @Bean |
| public TokenStore tokenStore() { |
| |
| return new RedisTokenStore(redisConnectionFactory); |
| } |
| } |
| |
| # AuthorizationServerConfig配置如下 |
| @Autowired |
| private TokenStore tokenStore; |
| |
| @Override |
| public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { |
| |
| endpoints.tokenStore(tokenStore); |
| } |
- 测试


【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?