博客
关于我
Spring Security OAuth2--密码模式 实战
阅读量:106 次
发布时间:2019-02-25

本文共 9450 字,大约阅读时间需要 31 分钟。

OAuth2协议与Spring Boot密码模式认证服务器搭建

OAuth2协议简介

OAuth2是一种广泛用于授权管理的协议,主要用于规范令牌的发放过程。其最新版本为2.0,与之前的1.0不兼容,主要提供了四种授权模式:授权码模式、简化模式、密码模式和客户端模式。本文将重点介绍密码模式,因为前端系统采用用户名密码登录。

密码模式认证流程

在密码模式中,用户向客户端提供用户名和密码,客户端通过认证服务器获取令牌。整个流程分为三个步骤:

  • 用户访问客户端:用户通过客户端提交包含用户名和密码的请求,请求目标资源的访问令牌。
  • 认证服务器验证身份:认证服务器接收请求,验证用户的用户名和密码信息。
  • 返回访问令牌:认证通过后,认证服务器返回access_token给客户端。
  • 系统搭建

    项目依赖管理

    我们需要一个完整的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
  • 通过以上步骤,可以验证系统的完整认证流程是否正常工作。

    转载地址:http://ms.baihongyu.com/

    你可能感兴趣的文章
    PAT甲级——1007 Maximum Subsequence Sum (25分)
    查看>>
    PAT甲级——1009 Product of Polynomials (25分)(最后一个测试点段错误)
    查看>>
    Spring对jdbc的支持
    查看>>
    PayPal网站付款标准版(for PHP)
    查看>>
    Paystack Android SDK 集成与使用指南
    查看>>
    pbf格式详解,javascript加载导出pbf文件示例
    查看>>
    PBOC2.0与3.0的区别
    查看>>
    PbootCMS entrance.php SQL注入漏洞复现
    查看>>
    PbootCMS 前台RCE漏洞复现
    查看>>
    PBT
    查看>>
    PB级分析型数据库ClickHouse的应用场景和特性
    查看>>
    pc3-12800
    查看>>
    PCA---主成成分分析
    查看>>
    PCA和自动编码器:每个人都能理解的算法
    查看>>
    pca算法
    查看>>
    PCA降维demo
    查看>>
    SharePoint 2013 图文开发系列之定义站点模板
    查看>>
    PCB生产流程详解-ChatGPT4o作答
    查看>>
    PCB设计十条黄金法则
    查看>>
    SpringSecurity框架介绍
    查看>>