Spring Boot Oauth2 扩展 DefaultTokenServices

2023-11-25

我有一个 OAuth2 实现,对于授予类型 = 密码运行良好。现在我需要添加一个逻辑,如果用户之前登录,则限制相同的用户/密码组合允许再次登录。 为此,我研究并认为我要创建一个扩展 DefaultTokenServices 类的新类 (MyDefaultTokenService),然后在重写的 createAccessToken 方法中添加我的逻辑。但由于某种原因,当我调试和测试时,我没有命中 MyDefaultTokenService 类中放置的断点。它总是会命中 Springboot 的 DefaultTokenServices 类。我不知道我哪里错了,有人可以请我吗?

授权配置.java

    package com.company.config;

import java.util.Arrays;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
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.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.TokenRequest;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;

import com.alcord.enums.Authorities;
import com.alcord.model.Account;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter
        implements EnvironmentAware {

    private static final String ENV_OAUTH = "authentication.oauth.";
    private static final String PROP_CLIENTID = "clientid";
    private static final String PROP_SECRET = "secret";
    private static final String PROP_TOKEN_VALIDITY_SECONDS = "tokenValidityInSeconds";

    private RelaxedPropertyResolver propertyResolver;

    @Autowired
    private DataSource dataSource;

    @Bean
    public TokenStore tokenStore() {
        return new JdbcTokenStore(dataSource);
    }

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

        final TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer()));
        endpoints.tokenStore(tokenStore()).tokenEnhancer(tokenEnhancerChain)
                .authenticationManager(authenticationManager);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory().withClient(propertyResolver.getProperty(PROP_CLIENTID)).scopes("read", "write")
                .authorities(Authorities.ROLE_ADMIN.name(), Authorities.ROLE_DRIVER.name(),
                        Authorities.ROLE_PASSENGER.name())
                .authorizedGrantTypes("password", "refresh_token", "authorization_code", "implicit")
                .secret(propertyResolver.getProperty(PROP_SECRET)).accessTokenValiditySeconds(
                        propertyResolver.getProperty(PROP_TOKEN_VALIDITY_SECONDS, Integer.class, 1800));
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.propertyResolver = new RelaxedPropertyResolver(environment, ENV_OAUTH);
    }

    @Bean
    public TokenEnhancer tokenEnhancer() {
        return new CustomTokenEnhancer();
    }

    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        MyTokenService tokenService = new MyTokenService();
        tokenService.setTokenStore(tokenStore());
        tokenService.setSupportRefreshToken(true);
        tokenService.setTokenEnhancer(tokenEnhancer());
        return tokenService;
    }

    class MyTokenService extends DefaultTokenServices {

        public MyTokenService() {
        }

        @Override
        public OAuth2AccessToken readAccessToken(String accessToken) {
            return super.readAccessToken(accessToken);
        }

        @Override
        public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) throws AuthenticationException {
            OAuth2AccessToken token = super.createAccessToken(authentication);
            Account account = (Account) authentication.getPrincipal();
            // This is where I will add my logic when it hits the breakpoint.
            return token;
        }

        @Override
        public OAuth2AccessToken refreshAccessToken(String refreshTokenValue, TokenRequest tokenRequest)
                throws AuthenticationException {

            OAuth2AccessToken token = super.refreshAccessToken(refreshTokenValue, tokenRequest);
            return token;
        }
    }
}

资源服务器配置

package com.company.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;

import com.alcord.security.CustomAuthenticationEntryPoint;
import com.alcord.security.CustomLogoutSuccessHandler;

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    // The DefaultTokenServices bean provided at the AuthorizationConfig
    @Autowired
    private DefaultTokenServices tokenServices;

    // The TokenStore bean provided at the AuthorizationConfig
    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;

    @Autowired
    private CustomLogoutSuccessHandler customLogoutSuccessHandler;

    @Override
    public void configure(HttpSecurity http) throws Exception {

        http.exceptionHandling().authenticationEntryPoint(customAuthenticationEntryPoint).and().logout()
                .logoutUrl("/oauth/logout").logoutSuccessHandler(customLogoutSuccessHandler).and().csrf().disable()
                .headers().frameOptions().disable().exceptionHandling().and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll().antMatchers("/api/v1/login/**").permitAll()
                .antMatchers("/api/v1/admin/**").permitAll().antMatchers("/api/v1/test/**").permitAll()
                .antMatchers("/oauth/token").permitAll().antMatchers("/api/**").authenticated();
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.tokenServices(tokenServices).tokenStore(tokenStore).resourceId("oauth2_id");

    }

}

对此的答案:需要打电话AuthorizationServerEndpointsConfigurer.tokenServices in the configure method.

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    final TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
    tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer()));
    endpoints
        .tokenStore(tokenStore())
        .tokenServices(tokenServices()) // missed this!
        .tokenEnhancer(tokenEnhancerChain)
        .authenticationManager(authenticationManager);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Boot Oauth2 扩展 DefaultTokenServices 的相关文章

随机推荐

  • CSS 导入或带有“media”属性的

    在页面中包含 CSS 的最佳方法是什么 为什么 for eg or
  • JQuery旋钮显示数量变化

    我在用着jQuery 旋钮制作一些很酷的图表并且它运行得很好 但我有一个问题 我想让图表之间的显示数字有一个 符号连接 但我似乎无法让它发挥作用 通过 jquery 修改输入是行不通的 我尝试读入库的代码 但没有成功 以前有其他人遇到过这个
  • 当键盘出现时如何使视图控制器滚动到文本字段

    我想让我的uiviewcontroller xib滚动 我的视图控制器有大约 8 个文本字段 所以我的问题是当我想在第五期写点东西时textfield等等我的键盘覆盖了文本字段 我怎样才能摆脱这个问题 并使我的视图控制器滚动 由于我是iPh
  • 如何使用 Spring 4 和注释编写单元测试来验证异步行为?

    如何使用 Spring 4 和注释编写单元测试来验证异步行为 由于我习惯了 Spring 的 旧的 xml 风格 我花了一些时间才弄清楚这一点 所以我想我回答自己的问题是为了帮助别人 首先是公开异步下载方法的服务 Service publi
  • java中的3D Ray-Quad相交测试

    在 3D 空间中 我试图确定射线 直线是否与正方形相交 如果是 则确定它相交的正方形上的 x 和 y 位置 我有一条由两点表示的射线 R1 Rx1 Ry1 Rz1 and R2 Rx2 Ry2 Rz2 正方形由四个顶点表示 S1 Sx1 S
  • 将参与者添加到 XMPP 聊天室

    我想在我的应用程序中实现群聊 为此我使用 MUC 聊天室来实现相同的功能 在这里 我想向房间添加成员列表 我有 JID 我想将它们内部添加到列表中的所有成员中 我如何在不邀请他们的情况下添加他们 添加成员后 我想实现一项功能 每当聊天室的用
  • 是否可以在 Dart 类中将方法声明为 Final?

    在 Java 中 可以在类中声明方法以防止子类覆盖它 例如 class Foo final void bar some code here Dart中有类似的构造吗 package meta提供了一个 nonVirtual注解禁止覆盖方法和
  • 在 SecureRandom 类中使用“SHA1PRNG”

    我有一个基本问题 为什么在 SecureRandom 类中使用 SHA1PRNG 如果有人解释一下 将会很有帮助 提前致谢 前任 SecureRandom getInstance SHA1PRNG Warning 我认为直接依赖这个算法是不
  • 从平面列表创建 java 层次结构树集

    我有对象 T 的列表 它有一个父属性 其中顶部对象的父属性为 null 我想将所有对象放入 TreeSet 或 TreeMap 中 顶级对象将是所有没有父对象 父对象为空 的根对象 并且它们下面将有子对象 像这样的东西 o Ra Rb Rc
  • Ninject 和 ASP.NET Web API

    在我提出问题之前 您应该知道我从此页面获取了当前的代码 http www strathweb com 2012 05 using ninject with the latest asp net web api source 我正在尝试通过使
  • 在模板函数中包装 std::format 无法使用最新的 MSVC 编译器更新进行编译

    我有点困惑为什么这段代码突然停止编译 https godbolt org z hhM5GG78x 但如果我将编译器改回 v19 31 它将编译 https godbolt org z 11j8WbEzG 这是有问题的代码 include
  • 如何使用 LINQ 从字符串中删除字符

    我有一个像这样的字符串 XQ74MNT8244A 我需要删除所有char从字符串中 所以输出会像 748244 这个怎么做 请帮我做到这一点 new string XQ74MNT8244A Where char IsDigit ToArra
  • Redis 和 Membase 之间的主要区别是什么?

    Redis 和 Membase 之间的主要区别是什么 可扩展性 Membase 提供分布式键 值存储 就像 Memcache 一样 因此无论数据集有多大 写入和读取都将始终在可预测的恒定时间内执行 另一方面 Redis 只提供主从复制 可以
  • 当页面为 HTTPS 时 URLReferrer 为 null

    我们使用 URLReferrer 和在查询字符串中传递的代码来生成在线视频 以便只有我们的付费客户才能链接到我们的视频播放页面 该系统已经运行良好一段时间了 我知道 URL 引荐来源网址可能会被欺骗 但谁会告诉他们的客户做这样的事情来访问视
  • 使用字典替换文本文件中的单词

    我正在尝试打开一个文本文件 然后通读它 用存储在字典中的字符串替换某些字符串 根据以下问题的答案如何在 Python 中编辑文本文件 我可以在进行替换之前取出字典值 但循环字典似乎更有效 该代码不会产生任何错误 但也不会进行任何替换 imp
  • Node.js 中的 New Date() 时间错误

    考虑 root ubuntu firma Exotech heart beat heart beat service date Mon Apr 24 17 07 52 CEST 2017 root ubuntu firma Exotech
  • RabbitMQ 向每个消费者发送相同的消息

    我已经实现了 RabbitMQ 网站上的示例 RabbitMQ 示例 我已将其扩展为带有一个用于发送消息的按钮的应用程序 现在我在两台不同的计算机上启动了两个消费者 当我发送消息时 第一条消息发送到computer1 然后第二条消息发送到c
  • 如何使用 Javascript 动态嵌入 Java 小程序?

    我希望能够使用按下按钮时调用的 Javascript 函数动态地将 Java 小程序插入网页中 在页面加载时加载小程序会减慢速度太多 冻结浏览器等 我使用以下代码 它在 FF 中无缝工作 但在 IE8 Safari 4 和 Chrome 中
  • 简单 CRUD 的 EJB 3 会话 Bean 设计

    我正在编写一个应用程序 其唯一目的是执行 CRUD 操作以维护数据库中的记录 一些表 实体之间存在关系 我见过的创建会话 bean 的大多数示例都涉及与许多我没有的实体交互的复杂业务逻辑 操作 由于我的应用程序非常基础 那么会话 bean
  • Spring Boot Oauth2 扩展 DefaultTokenServices

    我有一个 OAuth2 实现 对于授予类型 密码运行良好 现在我需要添加一个逻辑 如果用户之前登录 则限制相同的用户 密码组合允许再次登录 为此 我研究并认为我要创建一个扩展 DefaultTokenServices 类的新类 MyDefa