我创建了两个独立的示例应用程序,其中一个充当 oauth 客户端,另一个充当资源服务器,并且它们都使用外部身份验证服务器(在本示例中为 facebook)。
示例中的场景如下,用户打开app1(oauth客户端)被重定向到首页,点击登录后会被重定向到facebook登录,登录成功后会跳转到回到第一页。如果他点击第一个按钮,将调用同一应用程序中的 api,并将显示在消息 1 标签旁边,如果他点击第二个按钮,将调用 app2(资源服务器)中的 api完成后,该消息将显示在消息 2 标签旁边。
如果您检查了日志,您会发现从 app1 到 app2 的 api 调用在请求参数中包含访问令牌。
Logs for app1 calling app2
请在git仓库here找到源代码
这是 app1(oauth 客户端)的配置
app1 网络安全配置
@Configuration
@EnableOAuth2Sso
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**").authorizeRequests().antMatchers("/", "/login**", "/webjars/**", "/error**").permitAll()
.anyRequest().authenticated().and().logout().logoutSuccessUrl("/").permitAll().and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("GET");
config.addAllowedMethod("POST");
config.addAllowedMethod("PUT");
config.addAllowedMethod("DELETE");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
app1 应用程序属性
security:
oauth2:
client:
clientId: <your client id>
clientSecret: <your client secret>
accessTokenUri: https://graph.facebook.com/oauth/access_token
userAuthorizationUri: https://www.facebook.com/dialog/oauth?redirect_url=https://localhost:8443/
tokenName: access_token
authenticationScheme: query
clientAuthenticationScheme: form
registered-redirect-uri: https://localhost:8443/
pre-established-redirect-uri: https://localhost:8443/
resource:
userInfoUri: https://graph.facebook.com/me
logging:
level:
org.springframework.security: DEBUG
这是app2(资源服务器)的配置
app2 资源服务器配置
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
String[] ignoredPaths = new String[] { "/error", "/login", "/doLogut", "/home", "/pageNotFound", "/css/**",
"/js/**", "/fonts/**", "/img/**" };
@Value("${security.oauth2.resource.user-info-uri}")
private String userInfoUri;
@Value("${security.oauth2.client.client-id}")
private String clientId;
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers(ignoredPaths).permitAll().anyRequest().authenticated();
}
@Primary
@Bean
public UserInfoTokenServices tokenService() {
final UserInfoTokenServices tokenService = new UserInfoTokenServices(userInfoUri, clientId);
return tokenService;
}
}
app2 应用程序属性
security:
oauth2:
resource:
userInfoUri: https://graph.facebook.com/me
client:
client-id: <your client id>
logging:
level:
org.springframework.security: DEBUG
这是 app1 控制器调用 app2 上的 api (hi2 api)
@RestController
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class UserController {
@Autowired
OAuth2RestTemplate restTemplate;
@RequestMapping("/user")
public Principal user(Principal principal) {
return principal;
}
@RequestMapping("/hi")
public String hi(Principal principal) {
return "Hi, " + principal.getName();
}
@RequestMapping("/hi2")
public String hi2(Principal principal) {
final String greeting = restTemplate.getForObject("http://127.0.0.1:8082/api/hello", String.class);
System.out.println(greeting);
return greeting;
}
}