由于公司项目需要,进行SpringBoot集成Spring Security oauth2,几乎搜寻网上所有大神的案例,苦苦不能理解,不能完全OK。
以下是借鉴各大神的代码,终于demo完工,请欣赏
oauth2 定义了下面四种授权方式:
- 授权码模式(authorization code)
- 简化模式(implicit)
- 密码模式(resource owner password credentials)
- 客户端模式(client credentials)
具体每个模式的业务逻辑,请找百度君
以下是参数:
* response_type:表示授权类型,必选项,此处的值固定为"code" * client_id:表示客户端的ID,必选项 * redirect_uri:表示重定向URI,可选项 * scope:表示申请的权限范围,可选项 * state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。
先贴出项目结构:
直接贴代码:
SpringBoot项目入口,服务启动
package com.mingtong.demo_client; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DemoClientApplication { public static void main(String[] args) { SpringApplication.run(DemoClientApplication.class, args); } }
控制器Controller,获取资源,后面可以改造JDBC获取数据库,或者远程调用
@RestController @RequestMapping("/api") public class DemoController { @RequestMapping("/blog/{id}") public String getBlogById(@PathVariable long id) { return "this is blog "+id; } }
Oauth2认证服务
@Configuration @EnableAuthorizationServer public class OAuth2ServerConfig extends AuthorizationServerConfigurerAdapter { @Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer .realm("oauth2-resources") //code授权添加 .tokenKeyAccess("permitAll()") .checkTokenAccess("isAuthenticated()") //allow check token .allowFormAuthenticationForClients(); } /** * 注入authenticationManager * 来支持 password grant type */ @Autowired private AuthenticationManager authenticationManager; @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationManager) //允许 GET、POST 请求获取 token,即访问端点:oauth/token .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("demoApp") .secret("demoAppSecret") .redirectUris("http://baidu.com")//code授权添加 .authorizedGrantTypes("authorization_code","client_credentials", "password", "refresh_token") .scopes("all") .resourceIds("oauth2-resource") .accessTokenValiditySeconds(1200) .refreshTokenValiditySeconds(50000); } }
资源服务器:
@Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.requestMatchers().antMatchers("/api/**") .and() .authorizeRequests() .antMatchers("/api/**").authenticated(); } }
SpringSecurity配置
@EnableGlobalMethodSecurity(prePostEnabled = true) @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.csrf().disable(); http.requestMatchers().antMatchers("/oauth/**","/login/**","/logout/**") .and() .authorizeRequests() .antMatchers("/oauth/**").authenticated() .and() .formLogin().permitAll(); } //配置内存模式的用户 @Bean @Override protected UserDetailsService userDetailsService(){ InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); manager.createUser(User.withUsername("demoUser1").password("123456").authorities("USER").build()); manager.createUser(User.withUsername("demoUser2").password("123456").authorities("USER").build()); return manager; } /** * 需要配置这个支持password模式 */ @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } }
POM文件
<dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
【密码授权模式-client】 密码模式需要参数:username,password,grant_type,client_id,client_secret http://localhost:8080/oauth/token?username=demoUser1&password=123456&grant_type=password&client_id=demoApp&client_secret=demoAppSecret 【客户端授权模式-password】 客户端模式需要参数:grant_type,client_id,client_secret http://localhost:8080/oauth/token?grant_type=client_credentials&client_id=demoApp&client_secret=demoAppSecret 【授权码模式-code】 获取code http://localhost:8080/oauth/authorize?response_type=code&client_id=demoApp&redirect_uri=http://baidu.com
通过code换token http://localhost:8080/oauth/token?grant_type=authorization_code&code=Filepd&client_id=demoApp&client_secret=demoAppSecret&redirect_uri=http://baidu.com
祝君好运!