当前位置: 首页 > 工具软件 > Openid4j > 使用案例 >

OpenID使用方法

别子实
2023-12-01
  1. 网上找了半天,参考资料很少,好不容易写了一个,记录下来,
package com.jiuqi.crcc.controller;

import java.net.URLEncoder;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.openid4java.consumer.ConsumerManager;
import org.openid4java.consumer.InMemoryConsumerAssociationStore;
import org.openid4java.consumer.InMemoryNonceVerifier;
import org.openid4java.consumer.VerificationResult;
import org.openid4java.discovery.DiscoveryInformation;
import org.openid4java.discovery.Identifier;
import org.openid4java.message.AuthRequest;
import org.openid4java.message.AuthSuccess;
import org.openid4java.message.MessageExtension;
import org.openid4java.message.ParameterList;
import org.openid4java.message.ax.AxMessage;
import org.openid4java.message.ax.FetchRequest;
import org.openid4java.message.ax.FetchResponse;
import org.openid4java.message.sreg.SRegMessage;
import org.openid4java.message.sreg.SRegResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 
 * <p>
 * TODO OpenID认证
 * (需要填写loginUrl的具体地址,以及完善returnVerify()方法中的认证通过后的处理)
 * </p>
 *
 * <p>
 * Copyright: 版权所有 (c) 2002 - 2008<br>
 * Company: 久其
 * </p>
 *
 * @author
 * @version 
 */
@Controller
@RequestMapping("/openid")
public class OpenIdSecurity {
	/*
	 * 一些专有名词: EU:End User,用户。 RP:Relying Party ,用来代指OAuth2中的受信任的客户端,身份认证和授权信息的消费方;
	 * 
	 * OP:OpenID Provider,有能力提供EU身份认证的服务方(比如OAuth2中的授权服务),用来为RP提供EU的身份认证信息;
	 * 
	 * ID-Token:JWT格式的数据,包含EU身份认证的信息。
	 * 
	 * UserInfo Endpoint:用户信息接口(受OAuth2保护),当RP使用ID-Token访问时,返回授权用户的信息,此接口必须使用HTTPS
	 */
	// openid认证地址(请求地址)
	private String ENDPOINT = "认证地址";
	private String loginUrl="填写需要登录的网址";
	private static final Logger LOGGER = LoggerFactory.getLogger(OpenIdSecurity.class);
	public final ConsumerManager manager = new ConsumerManager();

	@RequestMapping("/login")
	public void login(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 创建ConsumerManager对象,这个对象是保持与OP端的通信的
		if (request.getAttribute("consumermanager") == null) {
			ConsumerManager newmgr = new ConsumerManager();
			// setAssociations方法设置与OP的关联存放的位置,这里我们将它存放在内存
			newmgr.setAssociations(new InMemoryConsumerAssociationStore());
			// setNonceVerifier方法设置记录response_nonce的位置。
			newmgr.setNonceVerifier(new InMemoryNonceVerifier(5000));
			request.setAttribute("consumermanager", newmgr);
		}
		// 告诉OP认证完成之后返回到哪个URL
		// String returnToUrl = "http://https://work.cr23g.com";
		String returnToUrl = "http://localhost:7007/openid/return";
//		String returnToUrl = "http://jmcauley.ucsd.edu/data/amazon/";

		// 对用户提供的标识符执行发现
		List discoveries = manager.discover(ENDPOINT);
		// 检索一个服务端点进行身份验证
		DiscoveryInformation discovered = manager.associate(discoveries);
		// 存储在用户Session中发现的 信息
		request.getSession().setAttribute("openid-disc", discovered);
		// 比较重要,通过关联句柄以及returnURL准备OP需要的参数以及参数值
		// 获取要发送到OpenID提供程序的AuthRequest消息
		AuthRequest authReq = manager.authenticate(discovered, returnToUrl);
		// attribute Exchange获取用户信息:
		FetchRequest fetch = FetchRequest.createFetchRequest();
		fetch.addAttribute("fullname", "http://openid.net/schema/namePerson/friendly", true);
		fetch.addAttribute("email", "http://openid.net/schema/contact/internet/email", true);
		// 将扩展附加到身份验证请求
		authReq.addExtension(fetch);
		// 重定向到OP认证  ENDPOINT
		
		response.sendRedirect(authReq.getDestinationUrl(true));

	}

	/**
	 * 验证openid OP便将用户重定向到RP,并发送认证信息给RP,RP需要接受认证信息,检查是否认证通过,获取用户信息,然后进行后续的处理。
	 * 
	 * @param request
	 * @param response
	 * @throws Exception void
	 */
	@RequestMapping("/return")
	public void returnVerify(HttpServletRequest request, HttpServletResponse response) {
		String fullname = null;
		String email = null;
		try {

			// 获取ConsumerManager认证对象
			ConsumerManager manager = (ConsumerManager) request.getAttribute("consumermanager");
			// 获取响应参数列表
			ParameterList params = new ParameterList(request.getParameterMap());
			DiscoveryInformation discovered = (DiscoveryInformation) request.getSession().getAttribute("openid-disc");
			StringBuffer url = request.getRequestURL();
			String query = request.getQueryString();
			if (query != null && query.length() > 0) {
				url.append("?").append(query);
			}
			// 根据参数列表,关联句柄以及url_query验证是否通过认证
			VerificationResult verification = manager.verify(url.toString(), params, discovered);
			Identifier verified = verification.getVerifiedId();

			if (verified != null) {
				AuthSuccess authSuccess = (AuthSuccess) verification.getAuthResponse();
				// 两种获取用户属性的方式处理是不同的,所以在return_url中这两种方式都要考虑到
				if (authSuccess.hasExtension(SRegMessage.OPENID_NS_SREG)) {
					MessageExtension ext = authSuccess.getExtension(SRegMessage.OPENID_NS_SREG);
					if (ext instanceof SRegResponse) {
						SRegResponse regResp = (SRegResponse) ext;
						email = regResp.getAttributeValue("email");
						fullname = regResp.getAttributeValue("fullname");
					}
				} else if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX)) {
					MessageExtension ext = authSuccess.getExtension(AxMessage.OPENID_NS_AX);
					if (ext instanceof FetchResponse) {
						FetchResponse fetchResp = (FetchResponse) ext;
						email = (String) fetchResp.getAttributeValues("email").get(0);
						fullname = (String) fetchResp.getAttributeValues("fullname").get(0);
					}
				}
				System.out.println(email + ">>>>>>>>" + fullname);
				// OpenID中没有提供Email或者姓名信息处理,验证通过跳转页面
				
				  if(email==null|email.length()==0) {
				  
				  }else if(fullname==null|fullname.length()==0){
					  
				  }else {
					//进行url编码,防止特殊字符被转义
	                email=URLEncoder.encode(email, "UTF-8");
	                 response.sendRedirect(loginUrl + "?email=" + email);
				  }
				
				// 后续的处理
			}
		} catch (Exception e) {
			LOGGER.error(e.getMessage(), e);
		}
		
	}

}

 类似资料: