2

我在 servlet 中使用 openid4java。我有两个 servlet - 一个执行第一步(将用户重定向到登录/接受应用程序访问),第二个处理结果信息

在文档中,写到 org.openid4java.consumer.ConsumerManager 类在两个步骤中必须是相同的实例。我可以为此创建单例吗?它是线程和请求安全的吗?

感谢您的回复!

4

2 回答 2

3

在来自官方 openid4java 示例的消费者 servlet 中,ConsumerManager 似乎是线程安全的——它们对所有会话使用单个 ConsumerManager 实例。我也以这种方式使用它,还没有注意到任何奇怪的行为。但是来自开发人员的关于线程安全的 javadoc 声明会很棒......

于 2011-09-19T07:41:09.427 回答
0

//目前仅与 google 合作 // 试试这个 - 这就是一个..

导入 java.io.IOException;
导入 java.net.MalformedURLException;
导入 java.net.URL;
导入 java.util.List;

导入 javax.servlet.ServletConfig;
导入 javax.servlet.ServletContext;
导入 javax.servlet.ServletException;
导入 javax.servlet.http.HttpServletRequest;
导入 javax.servlet.http.HttpServletResponse;

导入 org.apache.commons.logging.Log;
导入 org.apache.commons.logging.LogFactory;
//import org.jboss.web.tomcat.security.login.WebAuthentication;
导入 org.openid4java.OpenIDException;
导入 org.openid4java.consumer.ConsumerException;
导入 org.openid4java.consumer.ConsumerManager;
导入 org.openid4java.consumer.VerificationResult;
导入 org.openid4java.discovery.DiscoveryInformation;
导入 org.openid4java.discovery.Identifier;
导入 org.openid4java.message.AuthRequest;
导入 org.openid4java.message.AuthSuccess;
导入 org.openid4java.message.ParameterList;
导入 org.openid4java.message.ax.AxMessage;
导入 org.openid4java.message.ax.FetchRequest;
导入 org.openid4java.message.ax.FetchResponse;
公共类 OpenAuth 扩展 javax.servlet.http.HttpServlet {

 最终静态字符串 YAHOO_ENDPOINT = "https://me.yahoo.com";
 最终静态字符串 GOOGLE_ENDPOINT = "https://www.google.com/
帐户/o8/id";

      //更新版本的示例代码来自:
https://crisdev.wordpress.com/2011/03/23/openid4java-login-example/

       //在此处添加您的 servlet 脚本路径 - 所以如果身份验证失败或
成功它将执行操作 - 在 doGet 中检查以下内容
       公共字符串 scr="/servlets/MyServlet";

 私有 ServletContext 上下文;
 私人 ConsumerManager 经理;
 私人 ConsumerManager 杂志;

 //Vahid Hedayati 更新的代码 http://pro.org.uk
 //删除配置初始化 - 将帖子移动到 doGet - 因为之前的代码
要求它是一个帖子,但也需要包含标识符作为
网址
 //标识符也是用于标识符代码的相同变量 -
 //清理以产生不同的变量并减少混乱
 //doGet identifer 更改为 openid_identifier 并且现在看起来
对于 openid_username 这是从返回的默认变量
openid 选择器
 //http://groups.google.com/group/openid4java/browse_thread/thread/
5e8f24f51f54dc2c
 //读完上面的帖子 - 将管理器存储在会话对象中
雅虎身份验证失败我更改了经理的代码
 //管理

 公共无效doPost(HttpServletRequest请求,HttpServletResponse
响应) 抛出 ServletException,IOException {
 doGet(请求,响应);
 }


 protected void doGet(HttpServletRequest req, HttpServletResponse
resp) 抛出 ServletException, IOException {
       //新变量
       Stringouser=(String)req.getParameter("openid_username");
       如果(用户==空){用户=“”;}
  //mage如果是openid_consumer_manager的session值
null 它会生成一次
 //并且在代码中调用管理器的地方首先返回
经理通过查找会话价值来评估

mag=(ConsumerManager)req.getSession().getAttribute("open_id_consumer_manager");
       如果(mag==null){
               this.manager = new ConsumerManager();

req.getSession().setAttribute("open_id_consumer_manager", manager);
       }

       String identify=(String)req.getParameter("openid_identifier");
       if (identify==null) { identify="";}
       如果(!identify.equals(“”)){
               this.authRequest(识别,用户,req,resp);
       }别的{

       //如果他们成功了,它将返回他们欢迎
       //欢迎在下面的会话值中查找 NEWUSER = yes
如果是这样
       //scr 现在有 ip 城市/国家/邮政编码,所以它最终确定
通过添加用户 ip country/city/ip 作为他们的注册来添加用户

       // 如果不是新的,他们已经从
此代码已将相关会话值放入更新记录和
退还他们我的账户

       //如果这里的认证失败或者他们拒绝分享他们的
电子邮件然后返回登录页面

               标识符标识符 = this.verifyResponse(req);
               如果(标识符!= null){
                       resp.sendRedirect(scr+"?act=welcome");
               } 别的 {
                       resp.sendRedirect(scr+"?act=login");
               }
        }
 }

 // --- 发出认证请求 ---
 公共字符串 authRequest(字符串用户提供字符串,字符串 Ouser,
HttpServletRequest httpReq, HttpServletResponse httpResp) 抛出
IO异常{
 尝试 {
       // 配置应用程序将在其中的 return_to URL
收到
       // 来自 OpenID 提供者的身份验证响应
       字符串 returnToUrl = httpReq.getRequestURL().toString();

       // --- 转发代理设置(仅在需要时) ---
       // ProxyProperties proxyProps = new ProxyProperties();
       // proxyProps.setProxyName("proxy.example.com");
       // proxyProps.setProxyPort(8080);
       // HttpClientFactory.setProxyProperties(proxyProps);

       // 对用户提供的标识符执行发现

       //修改 - 从会话中查找经理值
        经理=(消费者经理)
httpReq.getSession().getAttribute("open_id_consumer_manager");

       列出发现 = manager.discover(userSuppiedString);

       // 尝试与 OpenID 提供者关联
       // 并检索一个服务端点进行身份验证
       DiscoveryInformation 发现 =
manager.associate(发现);

       // 将发现信息存储在用户的会话中
       httpReq.getSession().setAttribute("openid-disc", found);

       // 获取要发送到 OpenID 的 AuthRequest 消息
提供者
       AuthRequest authReq = manager.authenticate(发现,
returnToUrl);

       FetchRequest fetch = FetchRequest.createFetchRequest();
       如果(用户提供字符串.startsWith(GOOGLE_ENDPOINT)){
               fetch.addAttribute("email", "http://axschema.org/
联系方式/电子邮件", true);
               fetch.addAttribute("firstName", "http://axschema.org/
namePerson/first", true);
               fetch.addAttribute("lastName", "http://axschema.org/
namePerson/last", true);
       } else if (userSuppliedString.startsWith(YAHOO_ENDPOINT)) {
               fetch.addAttribute("email", "http://axschema.org/
联系方式/电子邮件", true);
               fetch.addAttribute("全名", "http://axschema.org/
namePerson", true);
       } 别的 {
               // 适用于 myOpenID
               fetch.addAttribute("全名", "http://
schema.openid.net/namePerson", true);
               fetch.addAttribute("email", "http://schema.openid.net/
联系方式/电子邮件", true);
       }
       httpReq.getSession().setAttribute("Ouser",Ouser);

       // 将扩展附加到身份验证请求
       authReq.addExtension(fetch);
       httpResp.sendRedirect(authReq.getDestinationUrl(true));

 } 捕捉(OpenIDException e){
       // 向用户显示错误
 }
 返回空值;
  }

  // --- 处理认证响应 ---
  公共标识符 verifyResponse(HttpServletRequest httpReq) {
 尝试 {
       // 从认证响应中提取参数
       //(来自 OpenID 提供者的 HTTP 请求)
       ParameterList 响应 = 新
参数列表(httpReq.getParameterMap());

       // 检索之前存储的发现信息
       DiscoveryInformation 发现 = (DiscoveryInformation)
httpReq.getSession().getAttribute("openid-disc");

       // 从 HTTP 请求中提取接收 URL
       StringBuffer 接收URL = httpReq.getRequestURL();
       字符串查询字符串 = httpReq.getQueryString();
       if (queryString != null && queryString.length() > 0)
       接收URL.append("?").append(httpReq.getQueryString());

       // 验证响应;ConsumerManager 需要相同
       //(静态)用于放置认证请求的实例

       //修改 - 在运行验证之前查找会话值
结果

       经理=(消费者经理)
httpReq.getSession().getAttribute("open_id_consumer_manager");
       验证结果验证 =
manager.verify(receivingURL.toString(), response, found);

       // 检查验证结果并提取已验证的
       // 标识符
       已验证标识符 = verify.getVerifiedId();
       字符串 id=verified.getIdentifier();
       如果(已验证!= null){
          AuthSuccess authSuccess = (AuthSuccess)
验证.getAuthResponse();
          如果(authSuccess.hasExtension(AxMessage.OPENID_NS_AX)){
                     FetchResponse fetchResp = (FetchResponse)
authSuccess.getExtension(AxMessage.OPENID_NS_AX);
                   列出电子邮件 =
fetchResp.getAttributeValues("email");
                   String email = (String) emails.get(0);

                                ///////////////////////////////////////// //////////////////////////
                       //每个人需要实现的自定义位
与他们的应用程序交互:

                       //验证用户,发送邮件验证是否
用户存在于本地系统上
                       //如果是{
                                       //
httpReq.getSession().setAttribute("USERNAME",usern);

httpReq.getSession().setAttribute("LOGGEDIN", "on");
                               //}别的{
                               字符串名字 =
fetchResp.getAttributeValue("firstName");
                                       字符串姓氏 =
fetchResp.getAttributeValue("lastName");
                               细绳
全名=fetchResp.getAttributeValue("全名");
                                       如果(全名==空)
{全名="";}
                               如果(名字==空)
{名字="";}
                               if (lastName==null) { lastName="";}
                                       if (!fullname.equals("")) {
                                        if (fullname.indexOf(",")>-1)
{

firstName=fullname.substring(0,fullname.indexOf(","));

lastName=fullname.substring(fullname.indexOf(","),fullname.length());
                                       }else if (fullname.indexOf("
")>-1){

firstName=fullname.substring(0,fullname.indexOf(" "));

lastName=fullname.substring(fullname.indexOf(" "),fullname.length());
                                        }
                               }
                                       //这是返回的用户名
从要求用户名的各种服务中 - 它返回为
openid_username
                               //当使用openid-selector时,它使用
openid_identifier 和 openid_username - 这就是这个程序现在的内容
寻找
                               细绳
ouser=(String)httpReq.getSession().getValue("Ouser");
                                       if (user==null) {user="";}
                               //Adduser -- 传递电子邮件地址和
用户
                               //在 Adduser 类中 - 如果用户为空
将电子邮件从 0 拆分为 substring.indexOf("@")
                               // 生成一个随机数 - 查找
当前用户 - 如果存在添加随机数到结束
                               //并添加带有电子邮件和新用户的用户
用户名
                               //返回新用户并登录
像上面一样。

httpReq.getSession().setAttribute("NEWUSER","YES");
                               //
httpReq.getSession().setAttribute("USERNAME",usern);

httpReq.getSession().setAttribute("LOGGEDIN", "on");

                       //}

                       退货验证;// 成功
                              }


               }
       } 捕捉(OpenIDException e){
               // 向用户显示错误
       }

       返回空值;
 }
于 2011-05-08T16:36:52.657 回答