oauth2 定义了下面四种授权方式:前面有讲
- 授权码模式(authorization code)
- 简化模式(implicit)
- 密码模式(resource owner password credentials)
- 客户端模式(client credentials
代码地址 https://github.com/wushu0725/shrek

资源 contrllor类
Oauth2认证服务
@Configuration
@EnableAuthorizationServer
public class MyAuthorzationServerConfig 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 {
String finalSecret=passwordEncoder().encode("demoAppSecret");
clients.inMemory()
.withClient("demoApp")
.secret(finalSecret)
.redirectUris("http://baidu.com")//code授权添加
.authorizedGrantTypes("authorization_code","client_credentials", "password", "refresh_token")
.scopes("all")
.resourceIds("oauth2-resource")
.accessTokenValiditySeconds(1200)
.refreshTokenValiditySeconds(50000);
}
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
资源服务器:
@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(){
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
// password 方案一:明文存储,用于测试,不能用于生产
// String finalPassword = "123456";
// password 方案二:用 BCrypt 对密码编码
String finalPassword = bCryptPasswordEncoder.encode("123456");
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("demoUser1").password(finalPassword).authorities("USER").build());
manager.createUser(User.withUsername("demoUser2").password(finalPassword).authorities("USER").build());
return manager;
}
/**
* 需要配置这个支持password模式
*/
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
测试方式
【密码授权模式-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