《SpringSecurityOauth2》 1.SpringSecurityOauth2实现认证服务器,和资源服务器

OAuth2协议是什么

OAuth协议致力于 使网站和应用程序(统称为消费方)能够在无须用户透露其认证证书的情况下,通过API访问某个web服务(统称为服务提供方)的受保护资源

OAuth允许用户提供一个令牌给第三方网站,一个令牌对应一个第三方网站,该令牌能在特定的时间内访问特定的资源。

https://oauth.net/2/ 官网

https://tools.ietf.org/html/rfc6749  具体步骤

OAuth2协议提供四种常用授权方式

翻译一下:

我们主要讲授权码模式。

主要分两步:

1.获取code

客户端跳转到服务器url, 四个参数:response_type,client_id,redirect_uri,scope。

服务端相应,回调, 跳转到redirect_uri ,  带参数code

code是服务端发放的同意许可。 

2.根据code获取token

客户端发送ajax请求,四个参数:grant_type,code,redirect_uri,scope 。认证信息client_id+client_secret

服务端返回token信息。

有了token你就可以为所欲为了。

客户端访问资源服务器接口, 添加参数Authorization =  token_type+" "+access_token;

---------------------------------------------------------------------------------分割线-------------------------------------------------------------------------------------------

SpringSecurityOauth2 是结合SpringSecurity封装了OAuth2相关流程. 

引入jar包

		<!-- 引入Web模块 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.security.oauth</groupId>
			<artifactId>spring-security-oauth2</artifactId>
		</dependency>

认证服务器:

@EnableAuthorizationServer

package com.zzy.demo.config.oauth;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;

@Configuration
@EnableAuthorizationServer
public class MyOauthServerConfig {

}

are you kidding me!!!   为何如此简单?   就是这么简单 !

这意味着, 本服务已经是一个认证服务器.  可以发Oauth2证书(token)了.. 

资源服务器:

@EnableResourceServer

package com.zzy.demo.config.oauth;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;

@Configuration
@EnableResourceServer
public class MyResourceServerConfig {

}

 这意味着当前服务的rest请求,都被保护起来了!

sso:

@EnableOAuth2Sso

这个也很简单,我们下回分解.

再次强调,  以上三个注解,必须在SpringSecurity环境下用.

下面我们模拟一个获取token的流程.

认证服务器端需要做两件事

1. @EnableAuthorizationServer 上面我们说过

2. 配置可被授权的客户端信息, 在application.properties中加入clientId,clientSecret.

security.oauth2.client.clientId=client1
security.oauth2.client.clientSecret=123456

客户端需要做三件事

1.  跳转到服务器url, 获取code

2. 根据code获取token

3. 根据token,访问资源服务器数据.

@Controller
@RequestMapping("/client")
public class DemoController {
	
	String ssoServerUrl="http://localhost:9999/server";
	String client_id="client1";
	String client_secret="123456";
	String redirect_uri="http://127.0.0.1:8011/client/oauth/token";
	String grant_type="authorization_code";
	
	@RequestMapping("/login")
	public String login(HttpServletRequest request, HttpServletResponse response, Model model) {
		
		 
		//http://localhost:8888/oauth/authorize?response_type=code&client_id=yue&redirect_uri=http://guokaige.com&scope=all
		String queryString="response_type=code"+
		                   "&client_id="+client_id+
		                   "&redirect_uri="+redirect_uri+
		                   "&scope=all";
		
		String str=ssoServerUrl+"/oauth/authorize?"+queryString;
		   System.out.println("------------------"+str+"----------------------");                
		 return "redirect:"+str;
	}
	
	
	
    /**
    *
    * 通过code换取token
    * @param code
    * @return
    * @throws IOException
    */
   @RequestMapping(value = "/oauth/token")
   @ResponseBody
   public String token(String code) throws IOException {
	   
       System.out.println("------------获取到code---------------"+code);//将请求得到的code输出到控制台
       
       String token_url = ssoServerUrl+"/oauth/token";
       
       String token = getToken(token_url,code);
       
       System.out.println("------获取到token--------"+token);//将通过code获取的access_token输出到控制台
       
       
       String userinfo_url=ssoServerUrl+"/user/index.json";
       
       String userInfo = getUserInfo(userinfo_url,token);
       
       System.out.println("------获取到userInfo--------"+userInfo);//将通过code获取的access_token输出到控制台
       
	return userInfo;
   }
   
   
   public String getToken(String url,String code) {
	   
	   Map<String, Object> params =new HashMap<String, Object>();
	   params.put("grant_type", grant_type);
	   params.put("code", code);
	   params.put("redirect_uri", redirect_uri);
	   params.put("scope", "all");
	   
	   
		// POST请求
		HttpResponse response = HttpRequest
				.post(url)
				.basicAuthentication(client_id, client_secret)
				.form(params)
				.header("Content-Type", "application/x-www-form-urlencoded")
				.send();
		
		//System.out.println("--------------------"+response.toString());
		return response.bodyText();
   }
   
   
   public String getUserInfo(String url,String token) {
	   
	   
	   JSONObject json = JSONObject.parseObject(token);
	   
       String token_type = json.getString("token_type");
	   
	   String access_token=json.getString("access_token");
	   
	   String authorization=token_type+" "+access_token;
	   
	   System.out.println("------Authorization:"+authorization);
	   
	   
	   
		// POST请求
		HttpResponse response = HttpRequest
				.post(url)
				//.basicAuthentication(client_id, client_secret)
				.header("Content-Type", "application/x-www-form-urlencoded")
				.header("Authorization",authorization )
				.send();
		
		//System.out.println("--------------------"+response.toString());
		return response.bodyText();
   }
   


}

 我们来跑一下看看效果

首先客户端端口是8011, 认证服务器端口9999 ,server.context-path=/server

1.访问客户端http://localhost:8011/client/login, 浏览器跳转到认证服务器登录页面http://localhost:9999/server/login

登陆完成后, 浏览器跳转 http://127.0.0.1:8011/client/oauth/token?code=IPbA7v

2.我们已经得到code, 我们来获取token。访问认证服务器 http://localhost:9999/server/oauth/token

   public String getToken(String url,String code) {
	   
	   Map<String, Object> params =new HashMap<String, Object>();
	   params.put("grant_type", grant_type);
	   params.put("code", code);
	   params.put("redirect_uri", redirect_uri);
	   params.put("scope", "all");
	   
	   
		// POST请求
		HttpResponse response = HttpRequest
				.post(url)
				.basicAuthentication(client_id, client_secret)
				.form(params)
				.header("Content-Type", "application/x-www-form-urlencoded")
				.send();
		
		//System.out.println("--------------------"+response.toString());
		return response.bodyText();
   }

 3.拿到token后,我们访问资源服务器

   public String getUserInfo(String url,String token) {
	   
	   
	   JSONObject json = JSONObject.parseObject(token);
	   
       String token_type = json.getString("token_type");
	   
	   String access_token=json.getString("access_token");
	   
	   String authorization=token_type+" "+access_token;
	   
	   System.out.println("------Authorization:"+authorization);
	   
	   
	   
		// POST请求
		HttpResponse response = HttpRequest
				.post(url)
				//.basicAuthentication(client_id, client_secret)
				.header("Content-Type", "application/x-www-form-urlencoded")
				.header("Authorization",authorization )
				.send();
		
		//System.out.println("--------------------"+response.toString());
		return response.bodyText();
   }

有什么不懂欢迎评论.

猜你喜欢

转载自blog.csdn.net/kaige8312/article/details/83112076