使用Spring社交集成定制Spring Security OAuth2

自定义Spring安全OAuth2工作正常,现在想添加Spring Social集成(facebook登录,google登录等),当用户点击Facebook登录(用户不提供任何用户名/密码)时,Facebook会返回access_token,但是这个access_token我们不能用来查询我的应用程序web服务,为了得到我的应用程序access_token,我们需要传递用户名和密码,并使用grant_type作为密码.以下是我的配置文件

AuthorizationServerConfiguration.java

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    @Autowired
    DataSource dataSource;

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(
            AuthorizationServerSecurityConfigurer oauthServer) 
                    throws Exception {
        oauthServer.allowFormAuthenticationForClients();
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) 
            throws Exception {
        clients.jdbc(dataSource);
    }

    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        tokenServices.setSupportRefreshToken(true);
        tokenServices.setTokenStore(tokenStore());
        tokenServices.setAccessTokenValiditySeconds(86400000);
        tokenServices.setRefreshTokenValiditySeconds(86400000);
        return tokenServices;
    }


    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) 
            throws Exception {
        endpoints
        .tokenServices(tokenServices())
        .authenticationManager(authenticationManager);
    }

    @Bean
    public TokenStore tokenStore() {
        return new JdbcTokenStore(dataSource);
    }
}

ResourceServerConfiguration.java

@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    private String resourceId = "rest_api";

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        // @formatter:off
        resources.resourceId(resourceId);
        // @formatter:on
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().authorizeRequests()
        .antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll()
        .antMatchers(HttpMethod.GET, "/**/login").permitAll()
        .antMatchers(HttpMethod.GET, "/**/callback").permitAll()
        .anyRequest().authenticated()
        .and()
        .formLogin().permitAll();
    }
}

最后是WebSecurityConfigurerAdapter.java

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) 
      throws Exception {
        auth.userDetailsService(userDetailsService);
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() 
      throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
         http.csrf().disable()
         .authorizeRequests()
         .antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll()
         .antMatchers(HttpMethod.GET, "/**/login").permitAll()
         .antMatchers(HttpMethod.GET, "/**/callback").permitAll()
         .anyRequest().authenticated()
         .and()
         .formLogin().permitAll();
    }
}

在SO中读过不同的帖子,但是没有得到任何有用的例子,请指导我.提前致谢.!

最佳答案
    String redirectURL = messages.getProperty(Constant.REDIRECT_URI.getValue());
    String clientSecret = messages.getProperty(Constant.CLIENT_SECRET.getValue());
    HttpHeaders header = new HttpHeaders();
    header.setContentType(org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED);

    String req = "client_id=myas&" + "client_secret=" + clientSecret + "&grant_type=authorization_code&"
            + "scope=user_profile&" + "code=" + loginReqeust.getCode() + "&redirect_uri="
            + loginReqeust.getRedirectURL();

    HttpEntity<String> body = new HttpEntity<String>(req, header);
    Map<Object, Object> mapRes = new LinkedHashMap<Object, Object>();

    // call to get access token
    mapRes = getEndpoint("https://auth.mygov.in/oauth2/token", null, body, null);
    String accessToken = mapRes.get("access_token").toString();


    // Call for getting User Profile

    String userUrl = "https://auth.mygov.in/myasoauth2/user/profile";

    HttpHeaders head = new HttpHeaders();
    head.add("Authorization", "Bearer " + accessToken);

    HttpEntity<String> ent = new HttpEntity<String>(head);
    Map<Object, Object> mapResponse = new LinkedHashMap<Object, Object>();
    mapResponse.put("userProfile", getEndpoint(userUrl, null, ent, null));

    //In my case userKey represents the username basically the email of the user using which he/she logged into facebook/google

    String userKey = (String) ((LinkedHashMap<Object, Object>) mapResponse.get("userProfile")).get("mail");

    // Store the user profile in your database with basic info like username & an autogenerated password for the time being and other basic fields.

    userService.save(userprofileInfo);                  

                mapResponse.put("username", "retrieved from facebook/google user's profile");
                mapResponse.put("password", "autogenerated by your application");   

    //send back this response (mapResponse) to your UI and then from there make a call by passing this username and pwd to retrieve the access_token from your own applicatioon.

转载注明原文:使用Spring社交集成定制Spring Security OAuth2 - 代码日志