Spring Boot整合OAuth2,附详细注释

源码:https://github.com/xxiangzh/sso-server

功能:

1.短信验证码登录、账号密码登录,并可扩展

2.jwt加密token,jwt信息增强,并使用redis缓存

3.自定义登录controller和返回类

4.客户端详情存MySQL,并集成缓存,附表sql

5.认证时异常翻译

6.提供注销接口

 

示例代码:

import com.xzh.sso.common.SecurityConstants;
import com.xzh.sso.exception.CustomWebResponseExceptionTranslator;
import com.xzh.sso.granttype.ResourceOwnerSmsTokenGranter;
import com.xzh.sso.service.UserDetailsServiceImpl;
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.data.redis.connection.RedisConnectionFactory;
import org.springframework.http.HttpMethod;
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;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.CompositeTokenGranter;
import org.springframework.security.oauth2.provider.OAuth2RequestFactory;
import org.springframework.security.oauth2.provider.TokenGranter;
import org.springframework.security.oauth2.provider.password.ResourceOwnerPasswordTokenGranter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 授权服务器配置
 *
 * @author 向振华
 * @date 2020/11/05 17:43
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;

    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Autowired
    private AuthenticationManager authenticationManager;

    /**
     * 配置令牌端点(内置的/oauth/* 接口)的安全约束
     *
     * @param security
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) {
        security
                // 允许访问/oauth/token授权接口
                .allowFormAuthenticationForClients()
                // 开启/oauth/check_token访问
                .checkTokenAccess("permitAll()");
    }

    /**
     * 配置客户端详情
     *
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        // 读DB客户端详情
        clients.withClientDetails(new RedisClientDetailsService(dataSource));

        // 客户端详情配置
//        clients
//                .inMemory()
//                // 客户端ID
//                .withClient("order-client-id")
//                // 客户端密码
//                .secret(passwordEncoder.encode("123456"))
//                // 授权的类型
//                .authorizedGrantTypes("password", "refresh_token")
//                // 令牌有效期
//                .accessTokenValiditySeconds(120)
//                // 范围
//                .scopes("all");
    }

    /**
     * 配置令牌管理
     *
     * @param endpoints
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        List<TokenGranter> tokenGranters = getTokenGranters(endpoints.getTokenServices(), endpoints.getClientDetailsService(), endpoints.getOAuth2RequestFactory());
        endpoints
                // 登录模式
                .tokenGranter(new CompositeTokenGranter(tokenGranters))
                // 请求方式
                .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
                // 用户账号密码认证
                .userDetailsService(userDetailsService)
                // 指定认证管理器
                .authenticationManager(authenticationManager)
                // 指定token存储位置
                .tokenStore(tokenStore())
                // JWTToken
                .tokenEnhancer(jwtTokenConverter())
                // 是否重复使用refresh_token
                .reuseRefreshTokens(false)
                // 自定义异常翻译
                .exceptionTranslator(new CustomWebResponseExceptionTranslator());
    }

    /**
     * 获取登录类型
     *
     * @param tokenServices
     * @param clientDetailsService
     * @param requestFactory
     * @return
     */
    private List<TokenGranter> getTokenGranters(
            AuthorizationServerTokenServices tokenServices,
            ClientDetailsService clientDetailsService,
            OAuth2RequestFactory requestFactory) {
        return new ArrayList<>(Arrays.asList(
                // 内置的密码模式登录
                new ResourceOwnerPasswordTokenGranter(authenticationManager, tokenServices, clientDetailsService, requestFactory),
                // 短信验证码登录
                new ResourceOwnerSmsTokenGranter(tokenServices, clientDetailsService, requestFactory)
        ));
    }

    /**
     * 于Redis实现,令牌保存到缓存
     *
     * @return
     */
    @Bean
    public TokenStore tokenStore() {
        RedisTokenStore tokenStore = new RedisTokenStore(redisConnectionFactory);
        // redis key 前缀
        tokenStore.setPrefix(SecurityConstants.TOKEN_KEY);
        return tokenStore;
    }

    /**
     * JWT
     *
     * @return
     */
    @Bean
    protected JwtAccessTokenConverter jwtTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        // 设置JWT签名密钥
        converter.setSigningKey(SecurityConstants.JWT_SIGNING);
        // JWT加入额外信息
        converter.setAccessTokenConverter(new CustomAccessTokenConverter());
        return converter;
    }
}

短信验证码登录展示

源码:https://github.com/xxiangzh/sso-server

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值