ClientDetailsService
public interface ClientDetails extends Serializable {
String getClientId();//客户端id
Set<String> getResourceIds();//此客户端可以访问的资源。如果为空,则调用者可以忽略
boolean isSecretRequired();//验证此客户端是否需要secret
String getClientSecret();//获取客户端的secret
boolean isScoped();//此客户端是否仅限于特定范围
Set<String> getScope();//此客户端的范围。如果客户端未确定作用域,则为空
Set<String> getAuthorizedGrantTypes();//此客户端被授权的授权类型
Set<String> getRegisteredRedirectUri();//此客户端的预定义重定向redirect_url
Collection<GrantedAuthority> getAuthorities();//权限集合
Integer getAccessTokenValiditySeconds();//访问令牌有效期
Integer getRefreshTokenValiditySeconds();//刷新令牌有效期
boolean isAutoApprove(String scope);//测试客户端是否需要特定范围的用户批准
Map<String, Object> getAdditionalInformation();//额外的信息
}
public interface ClientDetailsService {
//通过clientId获取客户端详情信息
ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException;
}
客户端详情(Client Details)能够在应用程序运行的时候进行更新,可以通过访问底层的存储服务(例如将客户端详情存储在一个关系数据库的表中,就可以使用 JdbcClientDetailsService)或者通过 ClientDetailsManager 接口(同时你也可以实现 ClientDetailsService 接口)来进行管理
JDBC存储客户端信息
client_secret:客户端密码,此处不能是明文,需要加密
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.3.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.12.RELEASE</version>
</dependency>
@Configuration
public class MyOauth2Config {
/**
* druid数据源
*/
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource() {
return new DruidDataSource();
}
/**
* jdbc管理令牌
*/
@Bean
public TokenStore jdbcTokenStore() {
return new JdbcTokenStore(druidDataSource());
}
/**
* 授权码管理策略
*/
@Bean
public AuthorizationCodeServices jdbcAuthorizationCodeServices() {
//使用jdbc方式保存授权码到oauth_code中
return new JdbcAuthorizationCodeServices(druidDataSource());
}
/**
* 使用jdbc方式管理客户端信息
*/
@Bean
public ClientDetailsService jdbcClientDetailsService(){
return new JdbcClientDetailsService(druidDataSource());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
/**
* 当前需要使用内存方式存储了用户令牌,应当使用UserDetailsService才行,否则会报错
*/
@Component
public class MyUserDetailService implements UserDetailsService {
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
return new User("admin", passwordEncoder.encode("123456"),
AuthorityUtils.commaSeparatedStringToAuthorityList("admin_role"));
}
}
@EnableWebSecurity
public class OAuth2SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyUserDetailService myUserDetailService;
/**
* password密码模式要使用此认证管理器
*/
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
/**
* 用户类信息
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailService);
}
}
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthenticationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private MyUserDetailsService myUserDetailsService;
@Autowired
private TokenStore tokenStore;
@Autowired
private AuthorizationCodeServices jdbcAuthorizationCodeServices;
@Autowired
private ClientDetailsService jdbcClientDetailsService;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(jdbcClientDetailsService);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
endpoints.userDetailsService(myUserDetailsService);
//令牌管理策略
endpoints.tokenStore(tokenStore);
//授权码管理策略,针对授权码模式有效,会将授权码放到oauth_code表,授权后就删除它
endpoints.authorizationCodeServices(jdbcAuthorizationCodeServices);
}
}