简体   繁体   English

Spring Security和Facebook OAuth 2.0与Graph API集成

[英]Spring Security & Facebook OAuth 2.0 Integration with Graph API

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. 这个链接: http//blog.kadirpekel.com/2009/11/09/facebook-connect-integration-with-spring-security/不会这样做。 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. 我花了2个小时的东西,我没有让它工作。 I ended bit more bolder and feeling more stupid than usual after this endeavor :-( 在这项努力之后,我结束了更大胆,感觉比平常更愚蠢:-(

I would really like to see OAuth 2.0 solution for facebook connect. 我真的很想看到facebook连接的OAuth 2.0解决方案。 And restrict the use of Facebook JavaScript API to absolute minimum. 并将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 UPDATE

I have servlet solution and posted answer here if anyone is interested: Facebook Connect example in JSP (tomcat) 如果有兴趣的话,我有servlet解决方案,并在这里发布答案: JSP中的Facebook连接示例(tomcat)

I actually just finished my non-javascript, implementation of the Facebook Graph API Authentication last night. 我实际上刚刚完成了我的非JavaScript,昨晚实施的Facebook Graph API身份验证。 I was a gargantuan pain in the a**, but it works and it's working fairly well. 我在a **中是一个巨大的痛苦,但它的工作原理并且运作得相当好。

I used the example from the link you posted above as a starting point, as well as, the code from here as 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. 您需要创建这两个文件的实现,将过滤器放在过滤器链中,并创建Spring Security UserDetailsS​​ervice的实现,供Provider可以使用它来管理您的用户帐户信息。 I have some code on my machine at home that I can send you via email if you like. 我家里的机器上有一些代码,如果你愿意,我可以通过电子邮件发送给你。

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). 获取用户的“代码”,方法是拨打以下电话: https//www.facebook.com/dialog/oauth?client_id = YOUR_APP_ID&redirect_uri = YOUR_URL& scope = email,read_stream (范围是您想要的所有权限)要求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. 此调用将创建一个“身份验证代码”,然后将其发送回您的“redirect_uri”(我称之为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 ? 获得此“代码”后,您需要在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. CLIENT_ID = YOUR_APP_ID&REDIRECT_URI = YOUR_URL&client_secret = YOUR_APP_SECRET&代码= THE_CODE_FROM_ABOVE。 You have to make sure your "redirect_uri" is the same as the one you did in #1. 你必须确保你的“redirect_uri”与你在#1中所做的相同。 You'll make the above call using something like Apache's HttpClient, or the like. 你可以使用像Apache的HttpClient之类的东西进行上述调用。

  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). 现在使用此access_token(在上面的响应主体中),您可以使用以下URL获取用户的个人资料信息: https ://graph.facebook.com/me access_token = {ACCESS_TOKEN from above)。 The response will be in JSON. 响应将采用JSON格式。 You can also use the access_token with all of the graph API to post status, pictures, etc. 您还可以使用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交互的好地方。

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. 控制器(入口点):控制器(在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;
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM