如何在Spring OAuth2安全性中的successHandler中获取登录成功后的访问令牌?

huangapple go评论64阅读模式
英文:

How to get access token just after login in successHandler in spring oauth2 security?

问题

目前,我正在进行一个项目,在这个项目中,一个要求是在Spring成功处理程序中收集 accessToken(访问令牌),就在登录后立即获取。我阅读了不同的博客,但没有找到任何可能的解决方案。下面是我尝试过的代码片段,

这是我的成功处理程序,在这里我试图获取accessToken。但是当我尝试将 authentication.getDetails() 转换为 OAuth2AuthenticationDetails 时,我遇到了异常。

@Component
public class AuthSuccessListener implements ApplicationListener<AuthenticationSuccessEvent> {
      
    @Override
    public void onApplicationEvent(AuthenticationSuccessEvent event) {
         
        UserDetails userDetails = (UserDetails) event.getAuthentication().getPrincipal();
        System.out.println(userDetails);
        System.out.println("密码是:" + userDetails.getPassword());
        System.out.println("用户名是:" + userDetails.getUsername());
    
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //Authentication authentication = event.getAuthentication();
    
        OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails();
        String accessToken = details.getTokenValue();
        System.out.println(accessToken);
            
    }
}

我不知道这个方法是否有效。如果有其他方法可以在成功处理程序或其他地方在登录后立即获取accessToken,那么请帮助解决这个问题。

英文:

Currently, I am working on a project where a requirement is accessToken need to be collected at spring success handler just after login. I read different blogs but couldn't found any possible solution. Here I am giving code snippet that I tried,

This is my success handler where I am trying to get accessToken. But when I am trying to cast authentication.getDetails() to OAuth2AuthenticationDetails I am getting exception.

@Component
public class AuthSuccessListener implements ApplicationListener&lt;AuthenticationSuccessEvent&gt; {
  
    @Override
    public void onApplicationEvent(AuthenticationSuccessEvent event) {
     
        UserDetails userDetails = (UserDetails) event.getAuthentication().getPrincipal();
        System.out.println(userDetails);
        System.out.println(&quot;pass is &quot; + userDetails.getPassword());
        System.out.println(&quot;username is &quot; + userDetails.getUsername());

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
       //Authentication authentication = event.getAuthentication();


        OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails();
        String accessToken = details.getTokenValue();
        System.out.println(accessToken);
        
    }
}

I don't know whether this approach is valid or not. If there any other way to get accessToken just after login in successHandler or somewhere else, then please help to solve this issue.

答案1

得分: 1

至少我找到了一个解决方案,在登录后立即在成功处理程序(succeshandler)中获取令牌。由于我没有在短时间内找到相关的解决方案,所以我正在发布这个答案。我是这样解决这个问题的。

@Component
public class AuthSuccessListener implements ApplicationListener<AuthenticationSuccessEvent> {

    private final TokenStore tokenStore;

    public AuthSuccessListener(TokenStore tokenStore) {
        this.tokenStore = tokenStore;
    }

    @Override
    public void onApplicationEvent(AuthenticationSuccessEvent event) {
        UserDetails userDetails = (UserDetails) event.getAuthentication().getPrincipal();
        String accessToken = null;
        List<OAuth2AccessToken> tokens = (List<OAuth2AccessToken>) tokenStore.findTokensByClientIdAndUserName("your Client Id", userDetails.getUsername());
        if (tokens.size() > 0) {
            accessToken = tokens.get(0).getValue();
        }
    }
}

在这里,你可以看到我使用了 TokenStore 来通过方法 tokenStore.findTokensByClientIdAndUserName("your Client Id", userDetails.getUsername()); 使用 clientIdusername 检索令牌。
就是这样。

英文:

At least I found a solution to get token at succeshandler just after login. As I haven't got relevant solution in short, that's why I am posting this answer. I solved the issue like this.

    @Component
    public class AuthSuccessListener implements ApplicationListener&lt;AuthenticationSuccessEvent&gt; {
    
        private final TokenStore tokenStore;
    
        public AuthSuccessListener(TokenStore tokenStore) {
            this.tokenStore = tokenStore;
        }
    
        @Override
        public void onApplicationEvent(AuthenticationSuccessEvent event) {
            UserDetails userDetails = (UserDetails) event.getAuthentication().getPrincipal();
            String accessToken = null;
            List&lt;OAuth2AccessToken&gt; tokens = (List&lt;OAuth2AccessToken&gt;) tokenStore.findTokensByClientIdAndUserName(&quot;your Client Id&quot;, userDetails.getUsername());
            if (tokens.size() &gt; 0) {
                accessToken = tokens.get(0).getValue();
            }
        }
    }

Here you can see I used TokenStore to reteive token by using clientId and username with method tokenStore.findTokensByClientIdAndUserName(&quot;your Client Id&quot;, userDetails.getUsername());
That's it.

huangapple
  • 本文由 发表于 2020年9月18日 11:28:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/63948931.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定