赞
踩
OAuth 2.0定义了四种授权方式:
这里详细介绍客户端模式,通过client_id和client_secret获取access_token。
为了支持动态客户端注册,我们会把client_id保存在数据库中,而不是写死在配置文件中。
本文需要读者对spring security有一定的了解。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
注意这里我们引用了spring-jdbc, 因为我们会把 client_id 和 client_secret保存到数据库中。
应用入口:
@SpringBootApplication
@EnableAuthorizationServer
public class AuthCenterApplication {
/**
* 入口
* @param args 参数
*/
public static void main(String[] args) {
SpringApplication.run(AuthCenterApplication.class, args);
}
}
配置类:
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Override public void configure(final ClientDetailsServiceConfigurer clients) throws Exception { clients.jdbc(dataSource()).passwordEncoder(passwordEncoder()); } @Bean public DataSource dataSource() { final DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName")); dataSource.setUrl(env.getProperty("jdbc.url")); dataSource.setUsername(env.getProperty("jdbc.user")); dataSource.setPassword(env.getProperty("jdbc.pass")); return dataSource; } ... }
我们为应用程序配置了数据源。
下面是保存我们client信息的表
create table oauth_client_details (
client_id VARCHAR(256) PRIMARY KEY,
resource_ids VARCHAR(256),
client_secret VARCHAR(256),
scope VARCHAR(256),
authorized_grant_types VARCHAR(256),
web_server_redirect_uri VARCHAR(256),
authorities VARCHAR(256),
access_token_validity INTEGER,
refresh_token_validity INTEGER,
additional_information VARCHAR(4096),
autoapprove VARCHAR(256)
);
字段说明:
注意,一个客户端可能对应多个用户
INSERT INTO oauth_client_details
(client_id, client_secret, scope, authorized_grant_types,
web_server_redirect_uri, authorities, access_token_validity,
refresh_token_validity, additional_information, autoapprove)
VALUES
("fooClientIdPassword", "secret", "foo,read,write",
"password,authorization_code,refresh_token", null, null, 36000, 36000, null, true);
字段说明请看上节。
@Test public void givenDBUser_whenRevokeToken_thenAuthorized() { String accessToken = obtainAccessToken("fooClientIdPassword", "john123"); assertNotNull(accessToken); } private String obtainAccessToken(String clientId, String clientSecret) { Map<String, String> params = new HashMap<String, String>(); params.put("grant_type", "client_credentials"); params.put("client_id", clientId); params.put("client_secret", clientSecret); MvcResult result = mockMvc.perform(post("/oauth/token") .contentType(MediaType.APPLICATION_JSON) .params(param) .andReturn(); Gson gson = new Gson(); Map map = gson.fromJson(result.getResponse().getContentAsString(), Map.class); return map.get("access_token") }
注意,数据库表oauth_client_details中需要有对应的客户端数据。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。