Spring Oauth2 - 重新加载校长

时间:2015-11-19 12:28:42

标签: spring-security spring-oauth2

我已经使用spring安全模块实现了OAuth2密码授权。我添加了自己的UserDetails实现和UserDetailsS​​ervice(jdbc)。我将用户注入我的控制器:

@AuthenticationPrincipal User user

其中User是我对UserDetails的实现。 现在我想添加更改用户数据的可能性而不刷新令牌。

我尝试用以下内容刷新主体:

User updatedUser = ...
Authentication newAuth = new UsernamePasswordAuthenticationToken(updatedUser, updatedUser.getPassword(), updatedUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(newAuth);

但它不起作用,当我调用另一个控制器方法时,它返回旧的User对象。

有没有办法在没有刷新令牌的情况下更改用户数据?是否有任何解决方案使spring安全性始终从数据库(而不是从Cache)加载用户数据?

2 个答案:

答案 0 :(得分:2)

我找到了一种从this answer实现这一目标的方法。我创建了HttpSessionSecurityContextRepository

@Bean
public ReloadUserPerRequestHttpSessionSecurityContextRepository userDetailContextRepository() {
    return new ReloadUserPerRequestHttpSessionSecurityContextRepository();
}

并将其添加到HttpSecurityWebSecurityConfigurerAdapter中的 .and() .csrf() .csrfTokenRepository(csrfTokenRepository()) .and() .securityContext() .securityContextRepository(userDetailContextRepository())

user-info-url

以下是在每次请求时获取更新的用户信息的示例代码。您可以从API服务器或oauth2配置的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"); } } 中获取。

private final View.OnClickListener mOnClickListener = new View.OnClickListener() {
    @Override
    public void onClick(final View view) {
      .....
       .....
    }
};

答案 1 :(得分:2)

我不确定,但这只是猜测,我想你还需要清除SecurityContext

首先使用SecurityContextHolder.clearContext();清除安全上下文,然后使用您的代码设置身份验证

Authentication newAuth = new UsernamePasswordAuthenticationToken(updatedUser, updatedUser.getPassword(), updatedUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(newAuth);