Spring Security OAuth2--密码模式 实战
用户访问客户端:用户通过客户端提交包含用户名和密码的请求,请求目标资源的访问令牌。 认证服务器验证身份:认证服务器接收请求,验证用户的用户名和密码信息。 返回访问令牌:认证通过后,认证服务器返回access_token给客户端。
发布日期:2021-04-30 21:05:00
浏览次数:107
分类:精选文章
本文共 9450 字,大约阅读时间需要 31 分钟。
OAuth2协议与Spring Boot密码模式认证服务器搭建
OAuth2协议简介
OAuth2是一种广泛用于授权管理的协议,主要用于规范令牌的发放过程。其最新版本为2.0,与之前的1.0不兼容,主要提供了四种授权模式:授权码模式、简化模式、密码模式和客户端模式。本文将重点介绍密码模式,因为前端系统采用用户名密码登录。
密码模式认证流程
在密码模式中,用户向客户端提供用户名和密码,客户端通过认证服务器获取令牌。整个流程分为三个步骤:
系统搭建
项目依赖管理
我们需要一个完整的Spring Boot项目架构,以下是项目的POM文件配置:
4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.6.RELEASE demo security 0.0.1-SNAPSHOT security Spring Boot Security Demo Project 1.8 Greenwich.SR1 org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-oauth2 org.springframework.cloud spring-cloud-starter-security org.apache.commons commons-lang3 org.springframework.boot spring-boot-starter-data-redis io.jsonwebtoken jjwt 0.9.1 org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import org.springframework.boot spring-boot-maven-plugin
Redis配置
为了存储认证信息,我们选择Redis作为token存储。以下是Redis配置文件示例:
spring: redis: host: 127.0.0.1 port: 6379 password: KCl9HfqbVnhQ5c3n database: 0
安全配置类
定义一个安全配置类SecurityConfig,用于管理用户认证:
package com.example.demo.security.config;import com.example.demo.security.service.UserDetailService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.core.annotation.Order;import org.springframework.security.authentication.AuthenticationManager;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;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.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.crypto.password.PasswordEncoder;@EnableWebSecurity@Order(2)public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailService userDetailService; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Override protected void configure(HttpSecurity http) throws Exception { http.requestMatchers().antMatchers("/oauth/**") .and() .authorizeRequests() .antMatchers("/oauth/**").authenticated() .and() .csrf().disable(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailService).passwordEncoder(passwordEncoder()); }} 资源服务器配置
定义一个资源服务器配置类ResourceServerConfig,用于管理资源访问权限:
package com.example.demo.security.config;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;@Configuration@EnableResourceServerpublic class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.csrf().disable() .requestMatchers().antMatchers("/**") .and() .authorizeRequests() .antMatchers("/**").authenticated(); }} 认证服务器配置
定义一个认证服务器配置类AuthorizationServerConfig,用于管理令牌颁发:
package com.example.demo.security.config;import com.example.demo.security.service.UserDetailService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.security.authentication.AuthenticationManager;import org.springframework.security.crypto.password.PasswordEncoder;import org.springframework.security.oauth2.config.annotation.configuers.ClientDetailsServiceConfigurer;import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;import org.springframework.security.oauth2.config.annotation.web.configuers.AuthorizationServerEndpointsConfigurer;import org.springframework.security.oauth2.provider.token.DefaultTokenServices;import org.springframework.security.oauth2.provider.token.TokenStore;import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;@Configuration@EnableAuthorizationServerpublic class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Autowired private RedisConnectionFactory redisConnectionFactory; @Autowired private UserDetailService userDetailService; @Autowired private PasswordEncoder passwordEncoder; @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("auth") .secret(passwordEncoder.encode("123456")) .authorizedGrantTypes("password", "refresh_token") .scopes("all"); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) { endpoints.tokenStore(tokenStore()) .userDetailsService(userDetailService) .authenticationManager(authenticationManager) .tokenServices(defaultTokenServices()); } @Bean public TokenStore tokenStore() { return new RedisTokenStore(redisConnectionFactory); } @Primary @Bean public DefaultTokenServices defaultTokenServices() { DefaultTokenServices tokenServices = new DefaultTokenServices(); tokenServices.setTokenStore(tokenStore()); tokenServices.setSupportRefreshToken(true); tokenServices.setAccessTokenValiditySeconds(60 * 60 * 24); tokenServices.setRefreshTokenValiditySeconds(60 * 60 * 24 * 7); return tokenServices; }} 用户DetailsService
定义一个用户DetailsService类UserDetailService,用于用户认证:
package com.example.demo.security.service;import com.example.demo.security.entity.AuthUser;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.security.core.authority.AuthorityUtils;import org.springframework.security.core.userdetails.User;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.crypto.password.PasswordEncoder;import org.springframework.stereotype.Service;@Servicepublic class UserDetailService implements UserDetailsService { @Autowired private PasswordEncoder passwordEncoder; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { AuthUser user = new AuthUser(); user.setUsername(username); user.setPassword(passwordEncoder.encode("123456")); return new User(username, user.getPassword(), user.isEnabled(), user.isAccountNonExpired(), user.isCredentialsNonExpired(), user.isAccountNonLocked(), AuthorityUtils.commaSeparatedStringToAuthorityList("user:add")); }} 测试与验证
通过Postman测试可以验证系统的各个功能:
发送POST请求获取令牌:
- URL: http://localhost:8081/oauth/token
- 请求头:Basic base64(client_id:client_secret)
- 参数:grant_type=password&username=admin&password=123456
发送GET请求获取资源:
- URL: http://localhost:8081/oauth/test
- 请求头:Authorization: Bearer access_token
发送DELETE请求注销令牌:
- URL: http://localhost:8081/loginOut
- 请求头:Authorization: Bearer access_token
发送POST请求刷新令牌:
- URL: http://localhost:8081/oauth/token
- 请求头:Authorization: Bearer refresh_token
- 参数:grant_type=refresh_token
通过以上步骤,可以验证系统的完整认证流程是否正常工作。
发表评论
最新留言
不错!
[***.144.177.141]2026年05月29日 14时45分14秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
php将多个值的数组去除重复元素
2023-03-01
php局域网上传文件_PHP如何通过CURL上传文件
2023-03-01
PHP工具插件大全
2023-03-01
php布尔值的++
2023-03-01
PHP常量、变量作用域详解(一)
2023-03-01
PHP应用目录结构设计
2023-03-01
PHP应用程序连接MSQL数据库Demo(附crud程序)
2023-03-01
PHP应用程序连接Oracle数据库Demo(附Oracle客户端安装文件)
2023-03-01
PHP开发api接口安全验证
2023-03-01
PHP开发规范PSR
2023-03-01
PHP开发遇到错误0001
2023-03-01
php异常处理
2023-03-01
PHP引入了泛型和集合两大重要特性,大大改善 PHP 代码的可维护性和可读性
2023-03-01
PHP引擎php.ini参数优化
2023-03-01
PHP引用(&)使用详解
2023-03-01
php引用及垃圾回收
2023-03-01
php当前时间的集中写法
2023-03-01
php微信 开发笔记,微信WebApp开发总结笔记
2023-03-01
php微信公众号开发access_token获取
2023-03-01