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,以及授权信息。

    源码地址

    下载源码 关注我

  • 相关阅读:
    Hibernate save, saveOrUpdate, persist, merge, update 区别
    Eclipse下maven使用嵌入式(Embedded)Neo4j创建Hello World项目
    Neo4j批量插入(Batch Insertion)
    嵌入式(Embedded)Neo4j数据库访问方法
    Neo4j 查询已经创建的索引与约束
    Neo4j 两种索引Legacy Index与Schema Index区别
    spring data jpa hibernate jpa 三者之间的关系
    maven web project打包为war包,目录结构的变化
    创建一个maven web project
    Linux下部署solrCloud
  • 原文地址:https://www.cnblogs.com/entfrm/p/12583147.html
Copyright © 2011-2022 走看看