Spring OAuth2:如何在客户端从外部Oauth服务器持久存取访问令牌

时间:2018-02-22 13:10:02

标签: java spring spring-mvc spring-security oauth-2.0

我有一个spring MVC应用程序和一个远程OAuth2授权服务器。应使用远程服务器登录Web和移动应用程序,并授权微服务。用于授权的OAuth2服务器工作,当我直接调用获取令牌的路径时,该请求会正确返回访问和刷新令牌。

Spring Boot中AuthorizationServerConfigurerAdapter服务器应用程序上的Oauth2类看起来像这样:

package com.mydomain.oauth2.configuration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 
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.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;

@Configuration
@EnableAuthorizationServer
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {

 @Autowired
 @Qualifier("userDetailsService")
 private UserDetailsService userDetailsService;

 @Autowired
 private AuthenticationManager authenticationManager;

 @Autowired
 private TokenStore tokenStore;

 @Bean
 public BCryptPasswordEncoder bCryptPasswordEncoder() {
      return new BCryptPasswordEncoder();
 }

 @Override
 public void configure( AuthorizationServerSecurityConfigurer oauthServer)  throws Exception {
      oauthServer
          .tokenKeyAccess("permitAll()")
          .checkTokenAccess("isAuthenticated()")
          .allowFormAuthenticationForClients();
 }

 @Override
 public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
     clients
          .inMemory()
          .withClient("acme")
          .secret("acmesecret")
          .accessTokenValiditySeconds(3600)
          .scopes("read", "write")
          .redirectUris("http://localhost:8080/login")
          .authorizedGrantTypes("password", "refresh_token")
          .autoApprove(true)
          .resourceIds("resource");
  }

  @Override
  public void configure(AuthorizationServerEndpointsConfigurer configurer) throws Exception {
          configurer.authenticationManager(authenticationManager);
          configurer.userDetailsService(userDetailsService);
          configurer.tokenStore(tokenStore);
  }
}

我在Spring上编写的不是Spring Boot的Web应用程序的WebSecurityConfigurerAdapter类看起来像这样:

package com.domain2.web.configurations;

import java.util.Arrays;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.client.token.AccessTokenRequest;
import org.springframework.security.oauth2.client.token.DefaultAccessTokenRequest;
import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordAccessTokenProvider;
import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;

@Configuration
@EnableWebSecurity
@EnableOAuth2Client
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
OAuth2ClientContext oauth2ClientContext;

@Autowired
DataSource dataSource;

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
      .authorizeRequests()
      .antMatchers("/login*", "/forgot-password*", "/signup**", "/signup/**", "/resources/**", "/403", "/storage/api/download/**", "/test/public/**").permitAll()
      .antMatchers("/user**").anonymous()
      .anyRequest().authenticated()
      .and()
            .exceptionHandling().accessDeniedPage("/403")
      .and().exceptionHandling()
      .and()
            .logout()
            .logoutUrl("j_spring_security_logout")
            .logoutSuccessUrl("/login")
            .deleteCookies("JSESSIONID")
        .and()
        .csrf().disable();
}

@Bean
protected OAuth2ProtectedResourceDetails resource() {

    ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
    resource.setAccessTokenUri("http://localhost:9000/oauth/token");
    resource.setClientId("acme");
    resource.setClientSecret("acmesecret");
    resource.setGrantType("password");
    resource.setScope(Arrays.asList("read", "write"));

    return resource;
}

@Bean
public OAuth2RestTemplate restTemplate() {
    ResourceOwnerPasswordAccessTokenProvider accessTokenProvider = new ResourceOwnerPasswordAccessTokenProvider();
    AccessTokenRequest atr = new DefaultAccessTokenRequest();
    OAuth2RestTemplate template = new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(atr));
    template.setAccessTokenProvider(accessTokenProvider);
    return template;
}   

}

我的登录控制器:

@Autowired
private OAuth2RestOperations oaut2Template;

@RequestMapping(value="/login", method = RequestMethod.POST)
public String login(@RequestParam(value = "password") String password, @RequestParam(value = "username") String username){

    oaut2Template.getOAuth2ClientContext().getAccessTokenRequest().set("username", username);
    oaut2Template.getOAuth2ClientContext().getAccessTokenRequest().set("password", password);

    System.out.println("Token *******: " + oaut2Template.getAccessToken().getValue());


    return "dashboard";
}

我的问题是如何在登录控制器上将我的Web应用程序中的访问令牌和Principal用户存储起来。在登录控制器中获取的访问令牌是有效的,但我没有找到具有外部oaut2授权服务器的实现ResourceOwnerPasswordResourceDetails的示例,我很长时间都无法做到这一点。我将不胜感激任何帮助

0 个答案:

没有答案