{"id":1416,"date":"2023-03-19T11:43:28","date_gmt":"2023-03-19T03:43:28","guid":{"rendered":"https:\/\/www.appblog.cn\/?p=1416"},"modified":"2023-04-28T21:06:43","modified_gmt":"2023-04-28T13:06:43","slug":"spring-security-oauth2-redis-resource-server-configuration","status":"publish","type":"post","link":"https:\/\/www.appblog.cn\/index.php\/2023\/03\/19\/spring-security-oauth2-redis-resource-server-configuration\/","title":{"rendered":"Spring Security OAuth2 Redis \u8d44\u6e90\u670d\u52a1\u5668\u914d\u7f6e"},"content":{"rendered":"<h2>\u8d44\u6e90\u670d\u52a1\u5668\u76f8\u5173\u4f9d\u8d56<\/h2>\n<pre><code class=\"language-xml\">&lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-boot-starter-security&lt;\/artifactId&gt;\n&lt;\/dependency&gt;\n&lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-boot-starter-web&lt;\/artifactId&gt;\n&lt;\/dependency&gt;\n&lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.security.oauth&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-security-oauth2&lt;\/artifactId&gt;\n    &lt;version&gt;2.3.6.RELEASE&lt;\/version&gt;\n&lt;\/dependency&gt;\n&lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-boot-starter-data-redis&lt;\/artifactId&gt;\n&lt;\/dependency&gt;<\/code><\/pre>\n<p><!-- more --><\/p>\n<h2>\u8d44\u6e90\u670d\u52a1\u5668\u914d\u7f6e\u7c7b<\/h2>\n<pre><code class=\"language-java\">\/**\n * @Description: @EnableResourceServer\u6ce8\u89e3\u5b9e\u9645\u4e0a\u76f8\u5f53\u4e8e\u52a0\u4e0aOAuth2AuthenticationProcessingFilter\u8fc7\u6ee4\u5668\n * @Package: cn.appblog.security.oauth2.config.ResServerConfig\n * @Version: 1.0\n *\/\n@Configuration\n@EnableResourceServer\npublic class ResourceServerConfig extends ResourceServerConfigurerAdapter {\n\n    @Autowired\n    private RedisConnectionFactory redisConnectionFactory;\n    @Autowired\n    private UserAuthenticationEntryPoint userAuthenticationEntryPoint;\n    @Autowired\n    private UserAccessDeniedHandler userAccessDeniedHandler;\n    @Autowired\n    private UserAuthenticationSuccessHandler userAuthenticationSuccessHandler;\n\n    @Override\n    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {\n        resources\n                .tokenServices(tokenServices())\n                \/\/\u8d44\u6e90ID\n                .resourceId(&quot;resource_password_id&quot;)\n                \/\/\u7528\u6765\u89e3\u51b3\u533f\u540d\u7528\u6237\u8bbf\u95ee\u65e0\u6743\u9650\u8d44\u6e90\u65f6\u7684\u5f02\u5e38\n                .authenticationEntryPoint(userAuthenticationEntryPoint)\n                \/\/\u8bbf\u95ee\u8d44\u6e90\u6743\u9650\u76f8\u5173\u5f02\u5e38\u5904\u7406\n                .accessDeniedHandler(userAccessDeniedHandler);\n    }\n\n    @Override\n    public void configure(HttpSecurity http) throws Exception {\n        http.csrf().disable();\n        http\n            .authorizeRequests()\n            .antMatchers(&quot;\/resource\/auth&quot;)\n            .denyAll()\n            .and()\n            .authorizeRequests()\n            .anyRequest()\n            .permitAll();\n    }\n\n    \/**\n     * OAuth2 token\u6301\u4e45\u5316\u63a5\u53e3\n     *\/\n    @Bean\n    public TokenStore tokenStore() {\n        return new RedisTokenStore(redisConnectionFactory);\n    }\n\n    \/**\n     * \u4ee4\u724c\u670d\u52a1\n     *\/\n    @Bean\n    public DefaultTokenServices tokenServices() {\n        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();\n        defaultTokenServices.setTokenStore(tokenStore());\n        return defaultTokenServices;\n    }\n\n    \/**\n     * \u52a0\u5bc6\u65b9\u5f0f\n     *\/\n    @Bean\n    public PasswordEncoder passwordEncoder() {\n        return new BCryptPasswordEncoder();\n    }\n}<\/code><\/pre>\n<h2>\u914d\u7f6e\u6587\u4ef6<\/h2>\n<pre><code>server.port=9004\n##\u5355\u673a\u5e94\u7528\u73af\u5883\u914d\u7f6e\nspring.redis.host=127.0.0.1\nspring.redis.port=6379\n#spring.redis.password=\nspring.redis.database=0\n#spring.redis.timeout=\n\n##redis\u8fde\u63a5\u6c60\u914d\u7f6e\n## \u8fde\u63a5\u6c60\u4e2d\u7684\u6700\u5c0f\u7a7a\u95f2\u8fde\u63a5\uff0c\u9ed8\u8ba40\nspring.redis.jedis.pool.min-idle=0\n## \u8fde\u63a5\u6c60\u4e2d\u7684\u6700\u5927\u7a7a\u95f2\u8fde\u63a5\uff0c\u9ed8\u8ba48\nspring.redis.jedis.pool.max-idle=8\n## \u8fde\u63a5\u6c60\u6700\u5927\u963b\u585e\u7b49\u5f85\u65f6\u95f4\uff08\u4f7f\u7528\u8d1f\u503c\u8868\u793a\u6ca1\u6709\u9650\u5236\uff09\uff0c\u9ed8\u8ba4-1ms\nspring.redis.jedis.pool.max-wait=-1ms\n##\u8fde\u63a5\u6c60\u6700\u5927\u8fde\u63a5\u6570\uff08\u4f7f\u7528\u8d1f\u503c\u8868\u793a\u6ca1\u6709\u9650\u5236\uff09\uff0c\u9ed8\u8ba48\nspring.redis.jedis.pool.max-active=8\n\noauth.token.uri=http:\/\/127.0.0.1:9003\/oauth\/token\noauth.resource.id=resource_password_id\noauth.resource.client.id=client_password\noauth.resource.client.secret=secret\noauth.resource.user.id=user\noauth.resource.user.password=123456<\/code><\/pre>\n<h2>\u8d44\u6e90\u63a7\u5236\u5668<\/h2>\n<pre><code class=\"language-java\">\/**\n * @Description: \u8d44\u6e90\u670d\u52a1\u5668\n * @Package: cn.appblog.security.oauth2.api.ResourceController\n * @Version: 1.0\n *\/\n@Slf4j\n@RestController\n@RequestMapping(&quot;\/resource&quot;)\npublic class ResourceController {\n\n    @RequestMapping(value = &quot;context&quot;, method = RequestMethod.GET)\n    public ResponseEntity&lt;Object&gt; get(@RequestParam String username, @RequestParam int age) {\n        SecurityContext ctx = SecurityContextHolder.getContext();\n        log.info(JSON.toJSONString(ctx));\n        if (!&quot;anonymousUser&quot;.equals(ctx.getAuthentication().getPrincipal())) {\n            return new ResponseEntity&lt;&gt;(ctx, HttpStatus.OK);\n        }\n        return new ResponseEntity&lt;&gt;(ctx, HttpStatus.OK);\n    }\n\n    @RequestMapping(value = &quot;auth&quot;, method = RequestMethod.GET)\n    @ResponseBody\n    public Object getAuth() {\n        SecurityContext ctx = SecurityContextHolder.getContext();\n        return ctx.getAuthentication();\n    }\n}<\/code><\/pre>\n<h2>\u8bbf\u95ee\u6d4b\u8bd5<\/h2>\n<p>\uff081\uff09\u8bbf\u95ee\uff1a<a target=\"_blank\" rel=\"noopener\" href=\"http:\/\/127.0.0.1:9004\/resource\/context?username=joe&amp;age=20\">http:\/\/127.0.0.1:9004\/resource\/context?username=joe&#038;age=20<\/a><\/p>\n<pre><code class=\"language-json\">{\n    &quot;authentication&quot;:{\n        &quot;authorities&quot;:[\n            {\n                &quot;authority&quot;:&quot;ROLE_ANONYMOUS&quot;\n            }\n        ],\n        &quot;details&quot;:{\n            &quot;remoteAddress&quot;:&quot;127.0.0.1&quot;,\n            &quot;sessionId&quot;:null\n        },\n        &quot;authenticated&quot;:true,\n        &quot;principal&quot;:&quot;anonymousUser&quot;,\n        &quot;keyHash&quot;:-872685687,\n        &quot;credentials&quot;:&quot;&quot;,\n        &quot;name&quot;:&quot;anonymousUser&quot;\n    }\n}<\/code><\/pre>\n<p>\uff082\uff09\u8bbf\u95ee\uff1a<a target=\"_blank\" rel=\"noopener\" href=\"http:\/\/127.0.0.1:9004\/resource\/context?username=joe&amp;age=20&amp;access_token=b970020dc0e942d0ae4a0e01232ff05f\">http:\/\/127.0.0.1:9004\/resource\/context?username=joe&#038;age=20&#038;access_token=b970020dc0e942d0ae4a0e01232ff05f<\/a><\/p>\n<pre><code class=\"language-json\">{\n    &quot;authentication&quot;:{\n        &quot;authenticated&quot;:true,\n        &quot;authorities&quot;:[\n            {\n                &quot;authority&quot;:&quot;{&quot;interfaces&quot;:[&quot;\/a\/b&quot;,&quot;\/a\/c&quot;,&quot;\/oauth\/token&quot;]}&quot;\n            },\n            {\n                &quot;authority&quot;:&quot;{&quot;username&quot;:&quot;user&quot;}&quot;\n            }\n        ],\n        &quot;clientOnly&quot;:false,\n        &quot;credentials&quot;:&quot;&quot;,\n        &quot;details&quot;:{\n            &quot;remoteAddress&quot;:&quot;127.0.0.1&quot;,\n            &quot;tokenType&quot;:&quot;Bearer&quot;,\n            &quot;tokenValue&quot;:&quot;b970020dc0e942d0ae4a0e01232ff05f&quot;\n        },\n        &quot;name&quot;:&quot;user&quot;,\n        &quot;oAuth2Request&quot;:{\n            &quot;approved&quot;:true,\n            &quot;authorities&quot;:[\n\n            ],\n            &quot;clientId&quot;:&quot;client_password&quot;,\n            &quot;extensions&quot;:{\n\n            },\n            &quot;grantType&quot;:&quot;password&quot;,\n            &quot;refresh&quot;:false,\n            &quot;requestParameters&quot;:{\n                &quot;grant_type&quot;:&quot;password&quot;,\n                &quot;client_id&quot;:&quot;client_password&quot;,\n                &quot;username&quot;:&quot;user&quot;\n            },\n            &quot;resourceIds&quot;:[\n                &quot;resource_password_id&quot;\n            ],\n            &quot;responseTypes&quot;:[\n\n            ],\n            &quot;scope&quot;:[\n                &quot;all&quot;\n            ]\n        },\n        &quot;principal&quot;:{\n            &quot;accountNonExpired&quot;:true,\n            &quot;accountNonLocked&quot;:true,\n            &quot;authorities&quot;:[\n                {\n                    &quot;$ref&quot;:&quot;$.authentication.authorities[0]&quot;\n                },\n                {\n                    &quot;$ref&quot;:&quot;$.authentication.authorities[1]&quot;\n                }\n            ],\n            &quot;credentialsNonExpired&quot;:true,\n            &quot;enabled&quot;:true,\n            &quot;username&quot;:&quot;user&quot;\n        },\n        &quot;userAuthentication&quot;:{\n            &quot;authenticated&quot;:true,\n            &quot;authorities&quot;:[\n                {\n                    &quot;$ref&quot;:&quot;$.authentication.authorities[0]&quot;\n                },\n                {\n                    &quot;$ref&quot;:&quot;$.authentication.authorities[1]&quot;\n                }\n            ],\n            &quot;details&quot;:{\n                &quot;client_secret&quot;:&quot;secret&quot;,\n                &quot;grant_type&quot;:&quot;password&quot;,\n                &quot;client_id&quot;:&quot;client_password&quot;,\n                &quot;username&quot;:&quot;user&quot;\n            },\n            &quot;name&quot;:&quot;user&quot;,\n            &quot;principal&quot;:{\n                &quot;$ref&quot;:&quot;$.authentication.principal&quot;\n            }\n        }\n    }\n}<\/code><\/pre>\n<pre><code class=\"language-json\">{\n    &quot;status&quot;: 300,\n    &quot;message&quot;: &quot;\u767b\u5f55\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u767b\u5f55\u4fe1\u606f...,org.springframework.security.authentication.InsufficientAuthenticationException: Invalid access token: b970020dc0e942d0ae4a0e01232ff05f&quot;\n}<\/code><\/pre>\n<p>\u672c\u6587\u8f6c\u8f7d\u53c2\u8003 <a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/blog.csdn.net\/yaomingyang\/column\/info\/41645\" title=\"\u539f\u6587\">\u539f\u6587<\/a> \u5e76\u52a0\u4ee5\u8c03\u8bd5<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u8d44\u6e90\u670d\u52a1\u5668\u76f8\u5173\u4f9d\u8d56 &lt;dependency&gt; &lt;groupId&gt;org.springf [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[354],"tags":[353,153],"class_list":["post-1416","post","type-post","status-publish","format-standard","hentry","category-spring-security","tag-oauth2","tag-redis"],"_links":{"self":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/1416","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/comments?post=1416"}],"version-history":[{"count":0,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/1416\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/media?parent=1416"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/categories?post=1416"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/tags?post=1416"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}