java Spring Security 和 Facebook OAuth 2.0 与 Graph API 的集成

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4650433/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 07:22:29  来源:igfitidea点击:

Spring Security & Facebook OAuth 2.0 Integration with Graph API

javafacebookspringfacebook-graph-apispring-security

提问by Mat B.

Please, at least pseudo (but from working environment not "maybe this should work") application context and controller/filter that will authenticate and/or auto-register Facebook users.

请,至少是伪(但从工作环境不是“也许这应该工作”)应用程序上下文和控制器/过滤器,将验证和/或自动注册 Facebook 用户。

This link: http://blog.kadirpekel.com/2009/11/09/facebook-connect-integration-with-spring-security/will not do. Actually I will put minus point to anyone who will post it as answer. I spend 2 hours with the thing and I didn't get it to work. I ended bit more bolder and feeling more stupid than usual after this endeavor :-(

这个链接:http: //blog.kadirpekel.com/2009/11/09/facebook-connect-integration-with-spring-security/不会做。实际上,我会给任何将其发布为答案的人加减分。我在这件事上花了 2 个小时,但没有让它发挥作用。经过这次努力,我比平时更加​​大胆,感觉更加愚蠢:-(

I would really like to see OAuth 2.0solution for facebook connect. And restrict the use of Facebook JavaScript API to absolute minimum.

我真的很想看到用于 facebook 连接的OAuth 2.0解决方案。并将 Facebook JavaScript API 的使用限制在绝对最低限度。

Following link shows about what I need: http://www.richardnichols.net/2010/06/implementing-facebook-oauth-2-0-authentication-in-java/

以下链接显示了我需要的内容:http: //www.richardnichols.net/2010/06/implementing-facebook-oauth-2-0-authentication-in-java/

Please post only code to this question. I already got all the advice I can handle.

请仅发布此问题的代码。我已经得到了我能处理的所有建议。

UPDATE

更新

I have servlet solution and posted answer here if anyone is interested: Facebook Connect example in JSP (tomcat)

如果有人感兴趣,我有 servlet 解决方案并在此处发布答案: JSP 中的 Facebook Connect 示例(tomcat)

采纳答案by Mulki

Here's an MVC implementation of facebook OAuth 2.0 The code's in C# and hopefully its similarity with java helps you out.

这是 facebook OAuth 2.0 的 MVC 实现代码在 C# 中,希望它与 java 的相似性可以帮助您。

Controller(Entry point):Controller(in MVC) is the point in the code where the control reaches after someone clicks on the login link.

Controller(Entry point):Controller(in MVC)是代码中的点,当有人点击登录链接后控件到达的点。

 public ActionResult Authenticate()
        {
                var oauthFacebook = new FacebookOAuth();
                if (Request["code"] == null)
                {
                    //Redirect the user to Facebook for authorization.
                    Response.Redirect(oauthFacebook.AuthorizationLinkGet());
                }
                else
                {
                    //Get the access token and secret.
                    oauthFacebook.AccessTokenGet(Request["code"]);
                    if (oauthFacebook.Token.Length > 0)
                    {
                        //We can now make our api calls
                        var user = oauthFacebook.GetAttributes();
                    }
                }
        }

FacebookOAuth Class

FacebookOAuth 类

public class FacebookOAuth : Oauth
    {
        public FacebookOAuth()
        {
            Authorize = "https://graph.facebook.com/oauth/authorize";
            AccessToken = "https://graph.facebook.com/oauth/access_token";
            CallbackUrl = "http://<YourURLHere>/Authenticate";
            AttributesBaseUrl = "https://graph.facebook.com/me/?access_token=";
            ConsumerKey = ConfigurationManager.AppSettings["FacebookConsumerKey"];//Ur Consumer Key goes here
            ConsumerSecret = ConfigurationManager.AppSettings["FacebookConsumerSecret"];//Ur Consumer secret goes here
            Provider = "Facebook";
        }

        public override string AuthorizationLinkGet()
        {
            return
                string.Format(
                    "{0}?client_id={1}&redirect_uri={2}&scope=email,user_education_history,user_location,user_hometown",
                    Authorize, ConsumerKey, CallbackUrl);
        }

        public User GetAttributes()
        {
            string attributesUrl = string.Format("{0}{1}", AttributesBaseUrl, Token);
            string attributes = WebRequest(Method.Get, attributesUrl, String.Empty);
            var FacebookUser = new JavaScriptSerializer().Deserialize<FacebookUser>(attributes);
            return new User()
            {
                FirstName = FacebookUser.first_name,
                MiddleName = FacebookUser.middle_name,
                LastName = FacebookUser.last_name,
                Locale = FacebookUser.locale,
                UserEmail = FacebookUser.email,
                AuthProvider = Provider,
                AuthToken=Token
            };
        }
    }

OAuth baseclass(Class from which FacebookOAuth derives)

OAuth 基类(FacebookOAuth 派生自的类)

  public abstract class Oauth
    {
        #region Method enum

        public enum Method
        {
            Get,
            Post,
            Delete
        } ;

        #endregion

        protected string AccessToken;
        protected string AttributesBaseUrl;
        protected string Authorize;
        protected string CallbackUrl;
        protected string ConsumerKey;
        protected string ConsumerSecret;
        public string Provider { get; protected set; }

        public string Token { get; set; }

        public virtual string AuthorizationLinkGet()
        {
            return
                string.Format(
                    "{0}?client_id={1}&redirect_uri={2}&scope=publish_stream,email,user_education_history,user_location",
                    Authorize, ConsumerKey, CallbackUrl);
        }

        public void AccessTokenGet(string authToken)
        {
            Token = authToken;
            string accessTokenUrl = string.Format("{0}?client_id={1}&redirect_uri={2}&client_secret={3}&code={4}",
                                                  AccessToken, ConsumerKey, CallbackUrl, ConsumerSecret, authToken);
            string response = WebRequest(Method.Get, accessTokenUrl, String.Empty);

            if (response.Length > 0)
            {
                //Store the returned access_token
                NameValueCollection qs = HttpUtility.ParseQueryString(response);

                if (qs["access_token"] != null)
                {
                    Token = qs["access_token"];
                }
            }
        }

        public string WebRequest(Method method, string url, string postData)
        {
            StreamWriter requestWriter;
            string responseData = string.Empty;

            var webRequest = System.Net.WebRequest.Create(url) as HttpWebRequest;
            if (webRequest != null)
            {
                webRequest.Method = method.ToString();
                webRequest.ServicePoint.Expect100Continue = false;
                webRequest.Timeout = 20000;

                if (method == Method.Post)
                {
                    webRequest.ContentType = "application/x-www-form-urlencoded";
                    //POST the data.
                    requestWriter = new StreamWriter(webRequest.GetRequestStream());
                    try
                    {
                        requestWriter.Write(postData);
                    }

                    finally
                    {
                        requestWriter.Close();
                    }
                }
                responseData = WebResponseGet(webRequest);
            }
            return responseData;
        }

        public string WebResponseGet(HttpWebRequest webRequest)
        {
            StreamReader responseReader = null;
            string responseData;
            try
            {
                responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());
                responseData = responseReader.ReadToEnd();
            }
            finally
            {
                if (webRequest != null) webRequest.GetResponse().GetResponseStream().Close();
                if (responseReader != null) responseReader.Close();
            }
            return responseData;
        }
    }

回答by El Guapo

I actually just finished my non-javascript, implementation of the Facebook Graph API Authentication last night. I was a gargantuan pain in the a**, but it works and it's working fairly well.

实际上,我昨晚刚刚完成了 Facebook Graph API 身份验证的非 JavaScript 实现。我是一个巨大的痛苦在 a**,但它的工作原理和它工作得相当好。

I used the example from the link you posted above as a starting point, as well as, the code from hereas a starting point. I had to write my own implementation of their FacebookGraphAuthenticationProvider and their FacebookGraphAuthenticationFilter, but now it works the way I want it to.

我使用您上面发布的链接中的示例作为起点,以及此处的代码作为起点。我必须编写自己的 FacebookGraphAuthenticationProvider 和 FacebookGraphAuthenticationFilter 实现,但现在它按我想要的方式工作。

You need to create implementations of both of these files, put your filter in the filter chain, and create a implementation of the Spring Security UserDetailsService that the Provider can use to manage your user account information. I have some code on my machine at home that I can send you via email if you like.

您需要创建这两个文件的实现,将过滤器放入过滤器链中,并创建 Spring Security UserDetailsS​​ervice 的实现,提供者可以使用它来管理您的用户帐户信息。我家里的机器上有一些代码,如果您愿意,我可以通过电子邮件发送给您。

Here are the steps I had to use to get the authentication to work:

以下是我必须使用的步骤才能使身份验证正常工作:

  1. Get an "code" for a user, this is done by making the following call: https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&scope=email,read_stream(The scope is all the permissions you want to request from FB). This call will create an "authentication code" which will then be sent back to your "redirect_uri" (which I stated as http://{my fb app registered domain}/j_spring_security_authentication_check.

  2. Once you have this "code", you need to make a call within your AuthenticationProvider that will retrieve an access_token for your user's session: this URL looks like: https://graph.facebook.com/oauth/access_token? client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&client_secret=YOUR_APP_SECRET&code=THE_CODE_FROM_ABOVE. You have to make sure your "redirect_uri" is the same as the one you did in #1. You'll make the above call using something like Apache's HttpClient, or the like.

  3. Now with this access_token (which comes in the body of above response), you can get your user's profile information with the following URL: https://graph.facebook.com/me?access_token={ACCESS_TOKEN from above). The response will be in JSON. You can also use the access_token with all of the graph API to post status, pictures, etc.

  1. 获取用户的“代码”,这是通过进行以下调用来完成的:https: //www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&scope =email,read_stream(范围是您想要的所有权限从FB请求)。此调用将创建一个“身份验证代码”,然后将其发送回您的“redirect_uri”(我将其声明为 http://{my fb 应用程序注册域}/j_spring_security_authentication_check。

  2. 获得此“代码”后,您需要在 AuthenticationProvider 中进行调用,该调用将为您的用户会话检索 access_token:此 URL 类似于:https://graph.facebook.com/oauth/access_token?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&client_secret=YOUR_APP_SECRET&code=THE_CODE_FROM_ABOVE。您必须确保您的“redirect_uri”与您在#1 中所做的相同。您将使用 Apache 的 HttpClient 之类的东西进行上述调用。

  3. 现在有了这个 access_token(出现在上述响应的正文中),您可以使用以下 URL 获取用户的个人资料信息:https: //graph.facebook.com/me ?access_token ={ACCESS_TOKEN from above)。响应将采用 JSON 格式。您还可以将 access_token 与所有图形 API 一起使用来发布状态、图片等。

I have some code at home that has my full implementation that I would be happy to share.

我在家里有一些代码,其中包含我很乐意分享的完整实现。

I hope this helps at least a bit. I suggest using the Spring Social app to get started with posting status, pictures, wall stuff, etc. This will be a good place to start looking at FB-Spring interaction.

我希望这至少有一点帮助。我建议使用 Spring Social 应用程序开始发布状态、图片、墙上的东西等。这将是开始查看 FB-Spring 交互的好地方。