认证服务器:authorization-server
*********************
配置文件
spring:
application:
name: authorization-server
server:
port: 8081
*********************
service 层
@Service
public class UserService implements UserDetailsService {
@Resource
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
String name="gtlx";
String password=passwordEncoder.encode("123456");
String role="admin";
List list=new ArrayList<>();
list.add(new SimpleGrantedAuthority(role));
return new User(name,password,list);
}
}
*********************
config 层
WebSecurityConfig:web安全配置
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder initPasswordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().and().authorizeRequests()
.antMatchers("/**").permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("gtlx")
.password(initPasswordEncoder().encode("123456"))
.authorities("admin");
}
}
OAuth2AuthorizationServerConfig:认证服务器配置
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Resource
private UserService userService;
@Resource
private PasswordEncoder passwordEncoder;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.userDetailsService(userService);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("user")
.secret(passwordEncoder.encode("123456"))
.authorizedGrantTypes("authorization_code","refresh_token")
.redirectUris("http://localhost:8082/redirect")
.accessTokenValiditySeconds(3000)
.refreshTokenValiditySeconds(3000)
.autoApprove(true)
.scopes("user");
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.allowFormAuthenticationForClients()
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
}
资源服务器:resource-server
*********************
配置文件
spring:
application:
name: resource-server
server:
port: 8082
security:
oauth2:
client:
client-id: user
client-secret: 123456
user-authorization-uri: http://localhost:8081/oauth/authorize
access-token-uri: http://localhost:8081/oauth/token
resource:
id: user
token-info-uri: http://localhost:8081/oauth/check_token
*********************
config 层
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/hello").hasAuthority("admin")
.antMatchers("/hello2").hasAuthority("user")
.antMatchers("/redirect").permitAll();
}
}
*********************
controller 层
@RestController
public class HelloController {
@Value("${security.oauth2.client.access-token-uri}")
private String accessTokenUri;
@RequestMapping("/hello")
public String hello(){
return "hello world";
}
@RequestMapping("/hello2")
public String hello2(){
return "hello 瓜田李下";
}
@RequestMapping("/redirect") //获取授权码时的回调地址,使用获得的授权码获取access_token
public Map get(@RequestParam(value = "code") String code){
OkHttpClient httpClient=new OkHttpClient();
RequestBody requestBody=new FormBody.Builder()
.add("grant_type","authorization_code")
.add("client","user")
.add("redirect_uri","http://localhost:8082/redirect")
.add("code",code)
.build();
Request request=new Request.Builder()
.url(accessTokenUri)
.post(requestBody)
.addHeader("Authorization","Basic dXNlcjoxMjM0NTY=")
.build();
Map result=null;
try {
Response response=httpClient.newCall(request).execute();
System.out.println(response);
ObjectMapper objectMapper=new ObjectMapper();
result=objectMapper.readValue(Objects.requireNonNull(response.body()).string(),Map.class);
System.out.println("access_token:"+result.get("access_token"));
System.out.println("token_type:"+result.get("token_type"));
System.out.println("refresh_token:"+result.get("refresh_token"));
System.out.println("expires_in:"+result.get("expires_in"));
System.out.println("scope:"+result.get("scope"));
}catch (Exception e){
System.out.println(e.getMessage());
}
return result;
}
}
说明:获取授权码后需要设置redirect_uri,且需要与获取授权码时的redirect_uri地址一致,否则会报错
"error": "invalid_grant","error_description": "Redirect URI mismatch."
使用测试
*********************
获取授权码
localhost:8081/oauth/authorize?client_id=user&response_type=code&redirect_uri=http//localhost:8082/redirect
client的属性autoApprove:false手动授权,true自动授权
获取授权后跳转到回调地址:http://localhost:8082/redirect
*********************
refresh token操作
localhost:8081/oauth/token
查询参数:grant_type=refresh_token&refresh_token=86ba104c-7d96-4f0b-bcde-161cb12dbb4e
header:key:Authorization,value:Basic dXNlcjoxMjM0NTY=
*********************
获取数据
localhsot:8082/hello
header:key:Authorization,value:bearer 36c6a366-bfa1-462d-bf27-8c88c0893c45
localhost:8082/hello2
header:key:Authorization,value:bearer 36c6a366-bfa1-462d-bf27-8c88c0893c45