完整项目代码:https://git.oschina.net/wang-bata/springboot-oauth2-server.gitjava
项目配置:java jdk1.8, springboot, springsecurity,springoauth2, 利用springOauth2.0来实现 oauth2.0协议 配置方式有xml和javaconfig 本文利用javaconfig 因为项目是用jar包方式启动因此页面显示用了 thmyleaf框架。git
1:资源服务器:web
资源服务器是指托管资源的服务器。好比,Facebook或Google就是资源服务器(或者有一个资源服务器)。spring
以下例子:sql
A公司处理是一个云存储公司,拥有用户的博客,文章,说说,动态等资源,此时这些数据应该被视为资源,但资源不单单是这些数据,还能够包括用户的 我的信息,不过这些信息比较敏感!跨域
资源服务器有2种配置方式,springboot
- 一个资源服务器对应一个资源ID (若是资源比较大,比较密集)
- 一个资源服务器对应多个资源ID (有时候一个资源服务比较小对系统消耗小,能够在一台服务器配置多个资源服务器 这样有利于公司资源的合理分配)
//一个资源服务器对应一个资源ID (若是资源比较大,比较密集) package com.wang.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore; import org.springframework.security.web.header.HeaderWriter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.sql.DataSource; @Configuration @EnableResourceServer public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { @Autowired private DataSource dataSource; @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { TokenStore tokenStore = new JdbcTokenStore(dataSource); resources.resourceId("user-services").tokenStore(tokenStore).stateless(true); } @Override public void configure(HttpSecurity http) throws Exception { http .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.NEVER) .and() .requestMatchers().antMatchers("/bata/**") .and() // For some reason we cant just "permitAll" OPTIONS requests which are needed for CORS support. Spring Security // will respond with an HTTP 401 nonetheless. // So we just put all other requests types under OAuth control and exclude OPTIONS. .authorizeRequests() .antMatchers(HttpMethod.GET, "/bata/**").access("#oauth2.hasScope('read')") .antMatchers(HttpMethod.POST, "/bata/**").access("#oauth2.hasScope('write')") .antMatchers(HttpMethod.PATCH, "/bata/**").access("#oauth2.hasScope('write')") .antMatchers(HttpMethod.PUT, "/bata/**").access("#oauth2.hasScope('write')") .antMatchers(HttpMethod.DELETE, "/bata/**").access("#oauth2.hasScope('write')") .and() // Add headers required for CORS requests. .headers().addHeaderWriter(new HeaderWriter() { @Override public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { response.addHeader("Access-Control-Allow-Origin", "*"); if (request.getMethod().equals("OPTIONS")) { response.setHeader("Access-Control-Allow-Methods", request.getHeader("Access-Control-Request-Method")); response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers")); } } }); } }
//一个资源服务器对应多个资源的配置 package com.wang.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfiguration; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore; import org.springframework.security.web.header.HeaderWriter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.sql.DataSource; import java.util.Arrays; import java.util.List; @Configuration public class ResourceServerConfig { @Autowired private DataSource dataSource; //配置jdbc数据源 @Bean protected ResourceServerConfiguration BataResources() { ResourceServerConfiguration resource = new ResourceServerConfiguration() { // Switch off the Spring Boot @Autowired configurers public void setConfigurers(List<ResourceServerConfigurer> configurers) { super.setConfigurers(configurers); } }; resource.setConfigurers(Arrays.<ResourceServerConfigurer>asList(new ResourceServerConfigurerAdapter() { @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { TokenStore tokenStore = new JdbcTokenStore(dataSource); resources.resourceId("bata-services").tokenStore(tokenStore).stateless(true); //设置资源ID } @Override public void configure(HttpSecurity http) throws Exception { http .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.NEVER) .and() .requestMatchers().antMatchers("/bata/**") //添加要进行资源隔离的路经 .and() .authorizeRequests() .antMatchers(HttpMethod.GET, "/bata/**").access("#oauth2.hasScope('read')") .antMatchers(HttpMethod.POST, "/bata/**").access("#oauth2.hasScope('write')") .antMatchers(HttpMethod.PATCH, "/bata/**").access("#oauth2.hasScope('write')") .antMatchers(HttpMethod.PUT, "/bata/**").access("#oauth2.hasScope('write')") .antMatchers(HttpMethod.DELETE, "/bata/**").access("#oauth2.hasScope('write')") .and() .headers().addHeaderWriter(new HeaderWriter() { @Override public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { response.addHeader("Access-Control-Allow-Origin", "*"); //配置跨域访问 if (request.getMethod().equals("OPTIONS")) { response.setHeader("Access-Control-Allow-Methods", request.getHeader("Access-Control-Request-Method")); response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers")); } } }); } })); resource.setOrder(3); return resource; } @Bean protected ResourceServerConfiguration UserResources() { ResourceServerConfiguration resource = new ResourceServerConfiguration() { // Switch off the Spring Boot @Autowired configurers public void setConfigurers(List<ResourceServerConfigurer> configurers) { super.setConfigurers(configurers); } }; resource.setConfigurers(Arrays.<ResourceServerConfigurer>asList(new ResourceServerConfigurerAdapter() { @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { TokenStore tokenStore = new JdbcTokenStore(dataSource); resources.resourceId("user-services").tokenStore(tokenStore).stateless(true); } @Override public void configure(HttpSecurity http) throws Exception { http .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.NEVER) .and() .requestMatchers().antMatchers("/user/**") .and() .authorizeRequests() .antMatchers(HttpMethod.GET, "/user/**").access("#oauth2.hasScope('read')") .antMatchers(HttpMethod.POST, "/user/**").access("#oauth2.hasScope('write')") .antMatchers(HttpMethod.PATCH, "/user/**").access("#oauth2.hasScope('write')") .antMatchers(HttpMethod.PUT, "/user/**").access("#oauth2.hasScope('write')") .antMatchers(HttpMethod.DELETE, "/user/**").access("#oauth2.hasScope('write')") .and() .headers().addHeaderWriter(new HeaderWriter() { @Override public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { response.addHeader("Access-Control-Allow-Origin", "*"); if (request.getMethod().equals("OPTIONS")) { response.setHeader("Access-Control-Allow-Methods", request.getHeader("Access-Control-Request-Method")); response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers")); } } }); } })); resource.setOrder(4); return resource; } }