apache oauth2

本文详细介绍了OAuth2.0授权流程的具体实现步骤,包括客户端如何发起授权请求、服务端如何处理请求并生成授权码,以及客户端如何利用授权码获取访问令牌。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.客户端调用:

this.oauth2Handler.beforeAuthrizedHandler(request, response);
		try {
			OAuthClientRequest oAuthClientRequest = OAuthClientRequest
					.authorizationLocation(this.oauth2Handler.getAuthorizeUri())
					.setClientId(this.oauth2Handler.getClientId())
					.setRedirectURI(this.oauth2Handler.getCallbackUri())
					.setResponseType("code")
					.setParameter("forcelogin", this.oauth2Handler.getForcelogin())
					.buildQueryMessage();
			log.info("跳转至oauth服务器进行授权认证:"+oAuthClientRequest.getLocationUri());
			response.sendRedirect(oAuthClientRequest.getLocationUri());
说明:(1)调用发生在 web项目的 servlet,转到登陆项目

    (2)OauthClientRequest 客户端用来封装请求参数

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">2.登陆系统处理:</span>

(1).解析请求参数

OAuthAuthzRequest oauthRequest = new OAuthAuthzRequest(request);
	         //client_id
	         String client_id=oauthRequest.getClientId();
	         //redirect_uri
	         String redirect_uri=oauthRequest.getRedirectURI();
	         //responseType
	         String responseType=oauthRequest.getResponseType();
	         //state
	         String state=oauthRequest.getState();
	         //forcelogin 是否强制登录
(2)登陆验证逻辑

 User user=this.loginService.getLoginUser(request);
	         if(forcelogin_r || null==user){
	        	//加载用户登录页面
		 		 request.getRequestDispatcher("/WEB-INF/pages/oauth2/authorize.jsp").forward(request, response);
	         }else{
	        	 //判断是否还需要加载用户授权页,如果用户已经有授权记录或来源系统是内部系统,则不需要加载用户授权页
	        	 if(application.getInnerFlag().intValue()==1 || null!=this.oauthAuthorizationService.getByUserId(user.getId())){
	        		//生成authorizationCode并返回给客户端
	 	 			sendAuthorizationCode(client_id,user.getId(),redirect_uri,request,response);
	 	 			return;
	        	 }else{
	        		//加载用户授权页面
	 	        	request.setAttribute("user", user);
	 	 			request.getRequestDispatcher("/WEB-INF/pages/oauth2/authorized.jsp").forward(request, response);
	        	 }
	        	 
	         }

说明:(1).没有user进入form表单

    (2)否则生成authorizationCode 返回客户端

    (3)sendAuthorizationCode代码

private void sendAuthorizationCode(String client_id,String user_id,String redirect_uri,
			HttpServletRequest request,HttpServletResponse response) throws OAuthSystemException, IOException{
		//生成authorizationCode
			String authorizationCode=this.oauth2Service.authorizationCode(client_id, user_id,redirect_uri, request);
		 //build OAuth response
         OAuthResponse resp = OAuthASResponse.authorizationResponse(request,HttpServletResponse.SC_FOUND)
             .setCode(authorizationCode)
             .location(redirect_uri)
             .buildQueryMessage();
         response.sendRedirect(resp.getLocationUri());
	}
(4) authorizationCode代码

@Override
	public String authorizationCode(String client_id, String user_id,
			String redirect_uri, HttpServletRequest request)
			throws OAuthSystemException {
		// oauthize_code生成器,这里使用md5的生成方式
		OAuthIssuer issuer = new OAuthIssuerImpl(new MD5Generator());
		String code = issuer.authorizationCode();
		// 将相关信息保存到Memchached缓存
		Calendar calendar = Calendar.getInstance();
		long time = calendar.getTimeInMillis();
		time += CODE_EXPIRYTIME;
		calendar.setTimeInMillis(time);
		SessionService.getInstance().saveOutTime(CODE_CLIENT_ID + code,
				client_id, calendar.getTime());
		SessionService.getInstance().saveOutTime(CODE_USER_ID + code, user_id,
				calendar.getTime());
		SessionService.getInstance().saveOutTime(CODE_REDIRECT_URI + code, redirect_uri,
				calendar.getTime());
		logger.info("生成authorizationCode:" + code);
		return code;
	}


(3) .客户端接受验证结果

	OAuthClient oAuthClient =new OAuthClient(new URLConnectionClient());
		String accessToken=null;
		String refreshToken=null;
		//access_token的数据
		AccessTokenModel atm=null;
		//接受oauth服务器返回的code
		try {
			OAuthAuthzResponse oar = OAuthAuthzResponse.oauthCodeAuthzResponse(request);
			String code = oar.getCode();
			log.info("获取authrizecode:"+code);
			//使用code交换access_token
			OAuthClientRequest oAuthClientRequest = OAuthClientRequest
		                .tokenLocation(this.oauth2Handler.getAccessTokenUri())
		                .setGrantType(GrantType.AUTHORIZATION_CODE)
		                .setClientId(this.oauth2Handler.getClientId())
		                .setClientSecret(this.oauth2Handler.getClientSecret())
		                .setRedirectURI(oauth2Handler.getCallbackUri())
		                .setCode(code)
		                .buildQueryMessage();
			log.info("换取access_token封装后的uri:"+oAuthClientRequest.getLocationUri());
		    OAuthJSONAccessTokenResponse oAuthResponse=null;
    	    oAuthResponse =oAuthClient.accessToken(oAuthClientRequest);
		    accessToken = oAuthResponse.getAccessToken();
		    refreshToken = oAuthResponse.getRefreshToken();
		    long expiresIn= oAuthResponse.getExpiresIn();
		    atm=new AccessTokenModel(accessToken, refreshToken, expiresIn);
		    
		    log.info("获取accessToken的结果->"+"accessToken:"+accessToken+",refreshToken:"+refreshToken+",expiresIn:"+expiresIn);
		} catch (Exception e) {
			log.info("使用code交换access_token发生异常:"+e.getMessage());
			e.printStackTrace();
			//如果获取access_token失败,则重新申请授权授权....
	    	response.sendRedirect(this.oauth2Handler.getToAuthorizeUri());
	    	return;
		}
		
		//认证成功后的逻辑处理
		//具体的逻辑实现由实现类决定
		this.oauth2Handler.afterAuthrizeHandler(atm, request, response);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值