我已经用Spring Security模块实现了OAuth2密码授权。我添加了自己的UserDetails和UserDetailsService (jdbc)实现。我将用户注入到我控制器中:
@AuthenticationPrincipal User user
其中User是我的UserDetails实现。现在我想添加在不刷新令牌的情况下更改用户数据的可能性。
我尝试更新校长:
User updatedUser = ...
Authentication newAuth = new UsernamePasswordAuthenticationToken(updatedUser, updatedUser.getPassword(), updatedUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(newAuth);
但它不起作用,当我调用另一个控制器方法时,它会返回旧的User对象。
有没有办法在不刷新令牌的情况下更改用户数据?是否有任何解决方案可以使Spring Security性始终从数据库(而不是从缓存)加载用户数据?
我不确定,但这只是一个猜测,我想你也需要清除SecurityContext
。
首先,使用<code>SecurityContextHolder清除安全上下文。clearContext() 然后您的代码设置身份验证
Authentication newAuth = new UsernamePasswordAuthenticationToken(updatedUser, updatedUser.getPassword(), updatedUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(newAuth);
我从这个答案中找到了一种方法来实现这一点。我创建了HttpSessionSecurityContextRepository
@Bean
public ReloadUserPerRequestHttpSessionSecurityContextRepository userDetailContextRepository() {
return new ReloadUserPerRequestHttpSessionSecurityContextRepository();
}
并将其添加到我的HttpSecurity
,从WebSecurityConfigurerAdapter
类中,如下所示:
.and()
.csrf()
.csrfTokenRepository(csrfTokenRepository())
.and()
.securityContext()
.securityContextRepository(userDetailContextRepository())
下面是在每次请求时获取更新用户信息的示例代码。您可以从API服务器或oauth2配置的用户信息url
获取。
public class ReloadUserPerRequestHttpSessionSecurityContextRepository extends HttpSessionSecurityContextRepository {
@Override
public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder) {
SecurityContext context = super.loadContext(requestResponseHolder);
Authentication auth = context.getAuthentication();
if (auth != null && auth instanceof OAuth2Authentication) {
OAuth2Authentication oldAuth = (OAuth2Authentication) auth;
if (oldAuth.getPrincipal() instanceof LinkedHashMap) {
createNewUserDetailsFromPrincipal(oldAuth.getPrincipal());
}
context.setAuthentication(oldAuth);
}
return context;
}
@SuppressWarnings("unchecked")
private void createNewUserDetailsFromPrincipal(Object principal) {
LinkedHashMap<String, Object> userDetailInfo = (LinkedHashMap<String, Object>) principal;
// fetch User informations from your API server or your database or
// 'user-info-url' of oauth2 endpoint
userDetailInfo.put("name", "EDITED_USER_NAME");
}
}
问题内容: 这是一个非常基本的问题-但我无法通过在线搜索找到答案。 我正在使用python控制ArcGIS,并且有一个简单的python脚本,该脚本调用了一些预先编写的代码。 但是,当我对预写代码进行更改时,它似乎没有导致任何更改。我导入了此模块,并尝试刷新它,但是没有任何反应。 我什至将它调用的文件移到了另一个位置,脚本仍然可以正常工作。昨天我做的一件事是我将所有python文件都添加到sys路
我试图在Angular应用程序中调用我的登录服务,但我遇到了CORS错误。我已经在WebSecurity配置适配器上添加了cors配置。我已经尝试了下面的一些配置。邮递员一切都很好。 授权服务器配置RADAPTER 资源服务器配置RADAPTER Web安全配置r适配器
问题内容: 我有一个带有php include的Div Tag,该div用来填充该信息,我想要做的是使它每隔15秒调用一次,以便它可以在那里更新信息,而不必重新加载整个网页。我试图用JavaScript / jQuery做到这一点,但似乎无法正常工作 这是我在搜索一些内容后所拥有的,然后发生的是,它加载了Small.php,但不会每15秒刷新一次或更新信息。 请帮忙! 我应该添加所有应显示的php
问题内容: 我只是很好奇,因为我已经在FragmentActivity中设置了Fragment选项卡,如何从FragmentActivity或Fragment本身重新加载片段,以清除并重新加载该选项卡。我本质上需要重新选择选项卡以替换片段时发生的相同事情。有一种简单的方法可以执行此操作并重新加载片段吗? 问题答案: 创建一个方法,该方法开始FragmentTransaction,分离片段,然后提交
当用户从用户界面更改配置时,我想动态地重新加载log4j附加器(RollingFileAppender)。 我已经通过编程删除了追加器,并用新的配置值创建了新的追加器。在此之后,appender broked MaxBackupIndex和MaxFileSize无法正常工作。但是如果我更改了文件名(日志文件名),那么它可以正常工作。 能帮我解决这个问题吗?
我在我的应用程序中使用导航栏,每次我选择一个项目时,它都会加载一个片段。 我能够使用相同的文本字段和按钮保存片段的状态,但有一个片段可以加载地图、添加标记、集群并执行。 每次我转到另一个菜单项并返回时,它都会重新加载所有内容,例如AsyncTask、Cluster、Markers。我如何停止此片段以不再重新创建地图并在返回时保存状态: Udate 1:我更新了代码,但问题仍然存在 主要活动: 主片