zoukankan      html  css  js  c++  java
  • SpringBoot 整合 spring security oauth2 jwt完整示例 附源码

    废话不说直接进入主题(假设您已对spring security、oauth2、jwt技术的了解,不懂的自行搜索了解)

    依赖版本

    • springboot 2.1.5.RELEASE
    • spring-security-oauth2 2.3.5.RELEASE
    • jjwt 0.9.1

    新增JWTokenConfig

    @Configuration
    public class JWTokenConfig {
    
        @Bean
        public TokenStore jwtTokenStore() {
            return new JwtTokenStore(jwtAccessTokenConverter());
        }
    
        @Bean
        public JwtAccessTokenConverter jwtAccessTokenConverter() {
            JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
            accessTokenConverter.setSigningKey("entfrm"); //对称加密key
            return accessTokenConverter;
        }
    
        @Bean
        public TokenEnhancer tokenEnhancer() {
            return new JWTTokenEnhancer(); // token增强
        }
    }
    

    JwtAccessTokenConverter:TokenEnhancer的子类,帮助程序在JWT编码的令牌值和OAuth身份验证信息之间进行转换。
    此处定义token 签名的方式,采用对称加密方式。

    增加JwtTokenEnhancer类

    public class JWTTokenEnhancer implements TokenEnhancer {
    
        @Override
        public OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication oAuth2Authentication) {
            Map<String, Object> info = new HashMap<>();
            info.put("license", "entfrm");
            ((DefaultOAuth2AccessToken) oAuth2AccessToken).setAdditionalInformation(info);
            //设置token的过期时间120分钟
            Calendar nowTime = Calendar.getInstance();
            nowTime.add(Calendar.MINUTE, 120);
            ((DefaultOAuth2AccessToken) oAuth2AccessToken).setExpiration(nowTime.getTime());
            return oAuth2AccessToken;
        }
    }
    

    重写TokenEnhancer的enhance方法,根据个人需求实现关键字段注入到 JWT 中,方便资源服务器使用。在此处也可以定义token过期时间。

    新增AuthorizationServerConfig类,继承AuthorizationServerConfigurerAdapter

    @Configuration
    @AllArgsConstructor
    @EnableAuthorizationServer
    public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    
        private final AuthenticationManager authenticationManager;
        private final EntfrmUserDetailService userDetailService;
        private final TokenStore jwtTokenStore;
        private final JwtAccessTokenConverter jwtAccessTokenConverter;
        private final TokenEnhancer tokenEnhancer;
        private final DataSource dataSource;
    
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
            TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
            List<TokenEnhancer> enhancers = new ArrayList<>();
            enhancers.add(tokenEnhancer);
            enhancers.add(jwtAccessTokenConverter);
            enhancerChain.setTokenEnhancers(enhancers);
    
            endpoints.authenticationManager(authenticationManager)
                    .tokenStore(jwtTokenStore)
                    .tokenEnhancer(enhancerChain)
                    .accessTokenConverter(jwtAccessTokenConverter)
                    .userDetailsService(userDetailService)
                    .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);//允许 GET、POST 请求获取 token,即访问端点:oauth/token
    
            endpoints.reuseRefreshTokens(true);//oauth2登录异常处理
            endpoints.exceptionTranslator(new EntfrmWebResponseExceptionTranslator());//oauth2登录异常处理
        }
    
        @Override
        public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
            oauthServer
                    .checkTokenAccess("isAuthenticated()")
                    .allowFormAuthenticationForClients();//允许表单认证
        }
    
        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.withClientDetails(clientDetails());
        }
    
        @Bean
        public ClientDetailsService clientDetails() {
            return new JdbcClientDetailsService(dataSource);//客户端配置 使用jdbc数据库存储
        }
    }
    

    endpoints的tokenEnhancer方法需要我们提供一个token增强器链对象TokenEnhancerChain,所以我们需要在链中加入我们重写的TokenEnhancer和jwtAccessTokenConverter,然后放入endpoints。同时我们将客户端配置放到了jdbc数据库中,方便多种客户端的扩展,这儿需要在数据库中创建一张表oauth_client_details,表sql脚本如下:

    CREATE TABLE `oauth_client_details`  (
      `client_id` varchar(48) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
      `resource_ids` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `client_secret` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `scope` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `authorized_grant_types` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `web_server_redirect_uri` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `authorities` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `access_token_validity` int(11) NULL DEFAULT NULL,
      `refresh_token_validity` int(11) NULL DEFAULT NULL,
      `additional_information` varchar(4096) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `autoapprove` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      PRIMARY KEY (`client_id`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    

    以上就是OAuth 授权服务器配置。

    启动项目 查看效果

    获取token

    解析token

    从图中我们可以看到返回的token中携带了我们加入的扩展信息license,以及授权信息。

    源码地址

    下载源码 关注我

  • 相关阅读:
    基于zookeeper实现分布式锁(续)
    Jquery消息提示插件toastr使用详解
    【微服务架构】SpringCloud组件和概念介绍(一)
    elasticsearch(全文检索)的介绍和安装
    springboot+elasticsearch实现全局检索
    自动化框架学习各个模块,以及遇到的问题
    python重写方法
    自动化时,写时候的疑问
    自动化selenium,执行js,以及触屏操作,和类的解释
    写了个python脚本,循环执行某一个目录下的jmeter脚本————解决的问题,每次回归时,都得一个个拉取
  • 原文地址:https://www.cnblogs.com/entfrm/p/12583147.html
Copyright © 2011-2022 走看看