【Spring Security Oauth2】构建授权服务器(一):内存模式

一、构建授权服务器:内存模式 (学习视频

1、pom依赖

1.1、Spring Security Oauth2

		<dependency>
            <groupId>org.springframework.security.oauth.boot</groupId>
            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>

1.2、Spring Cloud

		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>

2、创建AuthorizationServer、TokenConfig、WebSecurityConfig

2.1、创建AuthorizationServer类继承AuthorizationServerConfigurerAdapter
描述:该类需要重写父类的这三个方法,顺序AuthorizationServerSecurityConfigurer(配置客户端详细信息,客户端标识、客户端秘钥、资源列表等等) -> AuthorizationServerEndpointsConfigurer(管理令牌:令牌生成和存储) -> ClientDetailsServiceConfigurer (用来配置令牌端点的安全约束:拦截控制)

// 用来配置客户端详情服务(ClientDetailsService),客户端详情信息在 这里进行初始化,你能够把客户端详情信息写死在这里或者是通过数据库来存储调取详情信息。
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {} 
// 用来配置令牌(token)的访问端点和令牌服务(token services)。 
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {}
// 用来配置令牌端点的安全约束
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {}
package com.cyun.security.oauth2.config;

import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.PasswordEncoder;
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;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;

/**
 * 授权服务器配置
 *
 * @author He PanFu
 * @date 2021-12-19 17:55:23
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {

    @Autowired private TokenStore tokenStore;
    @Autowired private ClientDetailsService clientDetailsService;
    @Autowired private AuthenticationManager authenticationManager;
    @Autowired private PasswordEncoder passwordEncoder;

    /**
     * 令牌服务
     * @return
     */
    @SuppressWarnings({"All"})
    @Bean
    public AuthorizationServerTokenServices tokenService() {
        DefaultTokenServices service = new DefaultTokenServices();
        // 是否刷新令牌
        service.setSupportRefreshToken(true);
        // 令牌存储策略
        service.setTokenStore(tokenStore);
        // 令牌默认有效期2小时
        service.setAccessTokenValiditySeconds(7200);
        // 刷新令牌默认有效期3天
        service.setRefreshTokenValiditySeconds(259200);
        return service;
    }

    @Bean
    public AuthorizationCodeServices authorizationCodeServices() {
        //设置授权码模式的授权码如何 存取,暂时采用内存方式
        return new InMemoryAuthorizationCodeServices();
    }

    /**
     * 配置客户端详细信息
     * TODO 将来改成在数据库中
     *
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //  暂时使用in‐memory存储
        clients.inMemory()
                // 客户端标识
                .withClient("c1")
                // 客户端秘钥
                .secret(passwordEncoder.encode("secret"))
                // 资源列表
                .resourceIds("res1")
                // 允许授权的五种类型
                .authorizedGrantTypes("authorization_code", "password", "client_credentials", "implicit", "refresh_token")
                // 允许的授权范围
                .scopes("all")
                // false=跳转到授权页面,true=直接方法令牌
                .autoApprove(false)
                // 加上验证回调地址
                .redirectUris("http://www.baidu.com");
    }



    /**
     * 管理令牌:用来配置令牌(token)的访问端点和令牌服务(token services)。
     *
     * @param endpoints
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        // 密码模式
        endpoints.authenticationManager(authenticationManager)
                // 授权码模式
                .authorizationCodeServices(authorizationCodeServices())
                .tokenServices(tokenService())
                // 支持的请求
                .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
    }

    /**
     * 用来配置令牌端点的安全约束
     * 拦截控制
     *
     * @param security
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        /*
         * /oauth/authorize:授权端点。
         * /oauth/token:令牌端点。
         * /oauth/confirm_access:用户确认授权提交端点。
         * /oauth/error:授权服务错误信息端点。
         * /oauth/check_token:用于资源服务访问的令牌解析端点。
         * /oauth/token_key:提供公有密匙的端点,如果你使用JWT令牌的话。
         */
        // token_key公开
        security.tokenKeyAccess("permitAll()")
                // check_token公开
                .checkTokenAccess("permitAll()")
                .allowFormAuthenticationForClients();
        // clientCredentialsTokenEndpointFilter(security);
        // security.addTokenEndpointAuthenticationFilter(clientCredentialsTokenEndpointFilter(null));
    }
}

2.2、创建TokenConfig类

package com.cyun.security.oauth2.config;

import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;

/**
 * 自定义 TokenConfig 配置
 *
 * @author He PanFu
 * @date 2021-12-19 17:55:23
 */
@Configuration
@RequiredArgsConstructor
public class TokenConfig {
    /**
     * token 保存正在内存中
     * @return
     */
    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }
}

2.3、创建WebSecurityConfig

package com.cyun.security.oauth2.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * Spring Security 配置
 *
 * @author He PanFu
 * @date 2021-12-19 17:55:23
 */
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true,jsr250Enabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        String encode = passwordEncoder().encode("1");

        auth.inMemoryAuthentication()
                .withUser("root").password(encode).roles("ADMIN", "DBA");
    }

    /**
     * 安全拦截机制(最重要)
     *
     * @param http HttpSecurity安全配置
     * @throws Exception 异常
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/r/r1").hasAnyAuthority("p1")
                .antMatchers("/login").permitAll()
                .antMatchers("/oauth/token").permitAll()
                .anyRequest().authenticated()
                .and().formLogin();
    }
}

二、启动服务,授权(安全性由高到低)

1、授权码模式(authorization_code)

在这里插入图片描述

获取授权码:localhost:7103/oauth/authorize?client_id=c1&response_type=code&scope=all&redirect_uri=http://www.baidu.com
授权码登录:http://localhost:7103/oauth/token?client_id=c1&redirect_uri=http://www.baidu.com&client_secret=secret&grant_type=authorization_code&code=7qw29a
结果展示:
在这里插入图片描述

2、简化模式(token):授权后直接登录,获取到参数access_token、token_type、expires_in

在这里插入图片描述

URL:http://localhost:7103/oauth/authorize?client_id=c1&response_type=token&scope=all&redirect_uri=http://www.baidu.com
结果展示:
在这里插入图片描述

3、账号密码模式(password)

在这里插入图片描述

URL:http://localhost:7103/oauth/token?client_id=c1&client_secret=secret&grant_type=password&username=root&password=1
结果展示:
在这里插入图片描述

4、客户端模式(client_credentials)

在这里插入图片描述

URL:http://localhost:7103/oauth/token?client_id=c1&client_secret=secret&grant_type=client_credentials
结果展示:
在这里插入图片描述

5、刷新token模式(refresh_token)。当token过期后,调用次接口获取新token。

URL:http://localhost:7103/oauth/token?grant_type=refresh_token&refresh_token=2ae3ca8f-0cff-4e7d-ad7c-b193a0e7aceb&client_id=c1&client_secret=secret在这里插入图片描述

三、问题总结

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值