1.体验四种模式

1.1项目搭建

1.1.1导入依赖

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-oauth2</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-web</artifactId>
  9. </dependency>
  10. </dependencies>

1.1.2编写配置类

1.SpringSecurity的配置类

  1. @EnableWebSecurity
  2. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  3. @Bean
  4. public PasswordEncoder passwordEncoder(){
  5. return new BCryptPasswordEncoder();
  6. }
  7. @Bean
  8. @Override
  9. public AuthenticationManager authenticationManagerBean() throws Exception {
  10. return super.authenticationManagerBean();
  11. }
  12. @Override
  13. protected void configure(HttpSecurity http) throws Exception {
  14. super.configure(http);
  15. }
  16. @Override
  17. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  18. auth.inMemoryAuthentication()
  19. .withUser("gaoxi")
  20. .password(passwordEncoder().encode("123456")).roles("admin");
  21. }
  22. }

2.AuthorizationServerConfig认证服务器配置类

  1. @Configuration
  2. @EnableAuthorizationServer
  3. public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
  4. @Autowired
  5. private PasswordEncoder passwordEncoder;
  6. @Autowired
  7. private AuthenticationManager authenticationManager;
  8. @Override
  9. public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
  10. endpoints.authenticationManager(authenticationManager);
  11. }
  12. @Override
  13. public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
  14. clients.inMemory().withClient("yurun")
  15. .secret(passwordEncoder.encode("yurun"))
  16. .resourceIds("demo")
  17. .scopes("all")
  18. .authorizedGrantTypes("password","refresh_token","implicit","client_credentials","authorization_code")
  19. .redirectUris("http://www.baidu.com");
  20. }
  21. @Override
  22. public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
  23. security.allowFormAuthenticationForClients()
  24. .checkTokenAccess("isAuthenticated()");
  25. }
  26. }

1.2授权码模式

1.浏览器输入 http://localhost:8080/oauth/authorize?response_type=code&client_id=yurun&redirct_uri=http://www.baidu.com&scope=all自动跳转到登录页面
image.png
2.输入用户名和密码(程序中设置的),并点击登录
image.png
3.浏览器提示是否授权,点击授权后,自动跳转到回调地址并携带授权码
image.png
image.png
4.使用postman获取accesstoken
image.png
image.png
5.点击发送后,得到access_token
image.png

1.3密码模式

1.使用post发送获取access_token的请求(http://localhost:8080/oauth/token?grant_type=password&username=gaoxi&password=123456&client_id=yurun&client_secret=yurun)
image.png
2.查看获取到的信息
image.png

1.4简化模式(implicit)

1.浏览器请求地址(http://localhost:8080/oauth/authorize?response_type=token&client_id=yurun
2.自动跳转到回调地址并携带tokenimage.png

1.5客户端模式

使用postman请求地址(http://localhost:8080/oauth/token?grant_type=client_credentials&client_id=yurun&client_secret=yurun
image.png

2.一个简单DEMO

功能描述:搭建2个服务,1个提供Oauth2的认证服务,颁发access_token。另一个作为资源服务。

2.1认证服务器的搭建

1.导入依赖

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-oauth2</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-web</artifactId>
  8. </dependency>

2.编写SpringSecurity配置类

  1. @EnableWebSecurity
  2. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  3. @Bean
  4. public PasswordEncoder passwordEncoder(){
  5. return new BCryptPasswordEncoder();
  6. }
  7. @Bean
  8. @Override
  9. public AuthenticationManager authenticationManagerBean() throws Exception {
  10. return super.authenticationManagerBean();
  11. }
  12. @Override
  13. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  14. auth.inMemoryAuthentication()
  15. .withUser("gaoxi")
  16. .password(passwordEncoder().encode("123456"))
  17. .roles("admin");
  18. }
  19. @Override
  20. protected void configure(HttpSecurity http) throws Exception {
  21. super.configure(http);
  22. }
  23. }

3.编写认证服务配置类

  1. @Configuration
  2. @EnableAuthorizationServer
  3. public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
  4. @Autowired
  5. private PasswordEncoder passwordEncoder;
  6. @Autowired
  7. private AuthenticationManager authenticationManager;
  8. @Override
  9. public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
  10. security.allowFormAuthenticationForClients()
  11. .checkTokenAccess("isAuthenticated()");
  12. }
  13. @Override
  14. public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
  15. endpoints.tokenStore(tokenStore())
  16. .authenticationManager(authenticationManager)
  17. .accessTokenConverter(jwtAccessTokenConverter());
  18. }
  19. @Override
  20. public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
  21. clients.inMemory()
  22. .withClient("yurun")
  23. .secret(passwordEncoder.encode("yurun"))
  24. .authorizedGrantTypes("refresh_token","password")
  25. .scopes("all")
  26. .resourceIds("resource1") ;
  27. }
  28. @Bean
  29. public JwtAccessTokenConverter jwtAccessTokenConverter(){
  30. JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
  31. converter.setSigningKey("my-sign-key"); //资源服务器需要配置此选项方能解密jwt的token
  32. return converter;
  33. }
  34. @Bean
  35. public TokenStore tokenStore(){
  36. return new JwtTokenStore(jwtAccessTokenConverter());
  37. }
  38. }

2.2资源服务器的搭建

1.pom文件(同上)
2.资源服务器配置类

  1. @Configuration
  2. @EnableResourceServer
  3. @EnableGlobalMethodSecurity(securedEnabled = true,jsr250Enabled = true,prePostEnabled = true)
  4. public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
  5. @Bean
  6. public JwtAccessTokenConverter jwtAccessTokenConverter(){
  7. JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
  8. converter.setSigningKey("my-sign-key");
  9. return converter;
  10. }
  11. @Bean
  12. public TokenStore tokenStore(){
  13. return new JwtTokenStore(jwtAccessTokenConverter());
  14. }
  15. @Override
  16. public void configure(HttpSecurity http) throws Exception {
  17. http.authorizeRequests()
  18. .anyRequest().authenticated();
  19. }
  20. @Override
  21. public void configure(ResourceServerSecurityConfigurer resources) {
  22. resources.resourceId("resource1").stateless(true);
  23. resources.tokenStore(tokenStore());
  24. }
  25. }

3.Controller层的编写

  1. @RestController
  2. public class MyController {
  3. //用户没有user角色,登录后也不可访问
  4. @Secured(value = "ROLE_user")
  5. @RequestMapping("queryList")
  6. public String queryList(){
  7. return "stu List";
  8. }
  9. //用户有admin角色,这个接口在登录后可以访问
  10. @Secured(value = "ROLE_admin")
  11. @RequestMapping("queryById")
  12. public String queryById(){
  13. return "user";
  14. }
  15. }

2.3运行流程

1.认证服务器在 8080端口、资源服务器在8081端口

2.尝试访问资源服务器上的2个接口
image.png
image.png

2.postman使用密码模式请求认证服务器(端口8080),获取access_token
image.png
3.拷贝access_token,放入请求资源服务的接口参数中
①对于queryById,需要角色admin,用户名为gaoxi的这个用户有admin角色所以可以访问成功
image.png
②对于queryList,需要user角色,此用户没有角色所以仍然访问失败
image.png
③用户名:gaoxi这个用户是放在内存中的,角色也是在代码中设定的。

image.png

3.错误默认返回整理

1.没有加入Authorization头

DENY 401image.png2.错误的token
DENY 401
image.png
3.过期的token
Deny 401
image.png