- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我是 spring 的新手,我正在使用 spring security 开发 spring boot REST,目前我实现了 JWT token 。我有一些问题,但似乎找不到答案。我尝试添加刷新 token 。
起初我以为我会把它和用户一起存储在数据库中,但是 spring security 会自动完成所有事情,我似乎无法找到如何将它存储在表用户的给定字段中。
因此,继续前进我决定我将尝试坚持使用 spring 安全自动化并将刷新 token 过期时间设置为 10 秒以测试它是否过期,但遗憾的是它没有按预期工作 - 我可以根据需要使用刷新 token 并用它生成新的 token 。
所以在这里我有几个问题:
1. 如何让刷新 token 在给定时间后过期?这是我的安全配置
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${security.signing-key}")
private String signingKey;
@Value("${security.encoding-strength}")
private Integer encodingStrength;
@Value("${security.security-realm}")
private String securityRealm;
@Autowired
private UserDetailsService userDetailsService;
@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().httpBasic()
.realmName(securityRealm).and().csrf().disable();
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(signingKey);
return converter;
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
defaultTokenServices.setRefreshTokenValiditySeconds(10);
return defaultTokenServices;
}
最佳答案
我确实找到了答案,只是忘了更新我的工单。所以在这里,默认情况下 JwtTokenStore 不支持刷新 token 。 Here's JwtTokenStore source code .所以这意味着,在设置中启用 token 实际上不会使其工作。我所做的是创建我自己的 JWT token 存储,它扩展了 JwtTokenStore 并编写了我自己的刷新 token 逻辑。
public class MyJwtTokenStore extends JwtTokenStore {
@Autowired
UserRepository userRepository;
public MyJwtTokenStore(JwtAccessTokenConverter jwtTokenEnhancer) {
super(jwtTokenEnhancer);
}
@Override
public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) {
String username = authentication.getUserAuthentication().getName();
User user = userRepository.findByEmail(username);
user.setToken(refreshToken.getValue());
userRepository.save(user);
}
@Override
public OAuth2RefreshToken readRefreshToken(String token) {
OAuth2Authentication authentication = super.readAuthentication(token);
String username = authentication.getUserAuthentication().getName();
User user = userRepository.findByEmail(username);
if (!token.equals(user.getToken())) {
return null;
}
OAuth2RefreshToken refreshToken = new DefaultOAuth2RefreshToken(token);
return refreshToken;
}
@Override
public void removeRefreshToken(OAuth2RefreshToken token) {
OAuth2Authentication authentication = super.readAuthentication(token.getValue());
String username = authentication.getUserAuthentication().getName();
User user = userRepository.findByEmail(username);
user.setToken(null);
userRepository.save(user);
}
在此之后,我刚刚更新了我的 TokenStore Bean
@Bean
public TokenStore tokenStore() {
MyJwtTokenStore jwtTokenStore = new MyJwtTokenStore(accessTokenConverter());
return jwtTokenStore;
// return new JwtTokenStore(accessTokenConverter());
}
最后,我将剩余的设置添加到我的 AuthorizationServerConfigurerAdapter 类中以支持刷新 token 并为其提供有效时间。
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Value("${security.jwt.client-id}")
private String clientId;
@Value("${security.jwt.client-secret}")
private String clientSecret;
@Value("${security.jwt.grant-type}")
private String grantType;
@Value("${security.jwt.grant-type-other}")
private String grantTypeRefresh;
@Value("${security.jwt.scope-read}")
private String scopeRead;
@Value("${security.jwt.scope-write}")
private String scopeWrite = "write";
@Value("${security.jwt.resource-ids}")
private String resourceIds;
@Autowired
private TokenStore tokenStore;
@Autowired
private JwtAccessTokenConverter accessTokenConverter;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private AppUserDetailsService userDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
configurer.inMemory()
.withClient(clientId)
.secret(passwordEncoder.encode(clientSecret))
.authorizedGrantTypes(grantType, grantTypeRefresh).scopes(scopeRead, scopeWrite)
.resourceIds(resourceIds).autoApprove(false).accessTokenValiditySeconds(1800) // 30min
.refreshTokenValiditySeconds(86400); //24 hours
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
enhancerChain.setTokenEnhancers(Arrays.asList(accessTokenConverter));
endpoints.tokenStore(tokenStore).accessTokenConverter(accessTokenConverter).tokenEnhancer(enhancerChain)
.reuseRefreshTokens(false).authenticationManager(authenticationManager)
.userDetailsService(userDetailsService);
}
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*"); // http://localhost:4200
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}
关于java - Spring Security JWT 刷新 token 未过期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48974646/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!