代码地址 https://gitee.com/shenduedu/auth2.git
本例子 有四个模块
eureka 注册中心
oauth oauth2认证中心
认证中心 注册了 两个客户端,一个为password授权模式,一个为 client 授权模式
clients.inMemory().withClient("client_1")
.resourceIds(DEMO_RESOURCE_ID)
.authorizedGrantTypes("client_credentials", "refresh_token")
.scopes("select")
.authorities("client")
.secret("123456")
.and().withClient("client_2")
.resourceIds(DEMO_RESOURCE_ID)
.authorizedGrantTypes("password", "refresh_token")
.scopes("select")
.authorities("client") //权限信息
.secret("123456")
.and().withClient("ssoclient").secret("ssosecret")
.autoApprove(true)
.authorizedGrantTypes("authorization_code", "refresh_token").scopes("openid");
注册了三个 用户,都赋予了 admin 角色
@Bean
@Override
protected UserDetailsService userDetailsService(){
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("user_1").password("123456").roles("admin").build());
manager.createUser(User.withUsername("user_2").password("123456").roles("admin").build());
manager.createUser(User.withUsername("admin").password("admin").roles("admin").build());
return manager;
}
暴露了 资源服务 获取用户信息的端点
@RequestMapping(value = "/current",method = RequestMethod.GET)
public Principal getUser(Principal principal){
return principal;
}
resource-server模块 ,资源服务
提供了 受保护的 访问资源,当 请求 携带 access_token 访问 受保护资源时,资源服务会携带token,向认证服务器认证,认证
通过则通过该请求
该资源服务器开启了 方法级别的保护
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter{
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/user/login").permitAll()
.anyRequest().authenticated();
}
}
login 模块, 算是属于消费者模块,我在这里让它充当浏览器的角色,让用户登录后,首先会认证该用户是否存在,存在则通过,restTemplate 访问 认证服务,将返回的access_token保护,然后每次访问 资源服务都 携带 该token
@Controller
public class LoginController {
@Autowired
protected RestTemplate restTemplate;
@RequestMapping("/")
public String toLogin(){
return "login";
}
@ResponseBody
@RequestMapping("login")
public String login(String username,String password){
if(!"admin".equals(username)||!"admin".equals(password)){
return "账号密码不正确";
}
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> params= new LinkedMultiValueMap<>();
String token = getToken(username,password);
Gson gson = new Gson();
Map<String,String> map = gson.fromJson(token, Map.class);
String acccessToken = map.get("access_token");
if(acccessToken!=null){
MultiValueMap<String, String> resourceparams= new LinkedMultiValueMap<>();
resourceparams.add("access_token",acccessToken);
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(resourceparams, headers);
ResponseEntity<String> response = response = restTemplate.postForEntity("http://localhost:8081/product/1", requestEntity, String.class);
token = response.getBody();
}
return token;
}
@RequestMapping("getToken")
public String getToken(String username,String password){
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> params= new LinkedMultiValueMap<>();
params.add("client_id","client_2");
params.add("client_secret","123456");
params.add("scope","select");
params.add("grant_type","password");
params.add("username",username);
params.add("password",password);
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);
ResponseEntity<String> response = restTemplate.postForEntity("http://localhost:8080/oauth/token", requestEntity, String.class);
String token = response.getBody();
return token;
}
}
欢迎加入 微服务交流群 222700500