D2L Valence:c#中的自动身份验证与app&用户ID /密钥

时间:2015-03-18 18:44:38

标签: c# desire2learn valence

以下是我的代码。

我正在构建一个c#窗口应用程序,无需登录即可自动登录,从网址获取一些信息。

这是窗口应用程序表单,当用户单击“接受”按钮时将输出课程。此代码基于价 - 客户端示例代码。我希望这个应用程序使用应用程序ID /密钥对和用户ID /密钥对登录,并获取课程产品并输出它们。但是,当我运行这个程序时,它只是在此行停止 var ctx = httpListener.GetContext(); 。我不希望它打开浏览器,但希望在c#中使用app和用户ID /密钥对自动登录,并从URL获取json响应。所以用户无需登录。

namespace CourseOfferingWindow
{
    class CourseOfferingResponse
{
    public string Identifier { get; set; }
    public string Name { get; set; }
    public string Code { get; set; }
    public bool IsActive { get; set; }
    public string Path { get; set; }
    public object StartDate { get; set; }
    public object EndDate { get; set; }
    public string CourseTemplate { get; set; }
    public string Semester { get; set; }
    public string Department { get; set; }
}

public partial class CourseOfferingWindowForm : Form
{
    public CourseOfferingWindowForm()
    {
        InitializeComponent();
    }

    private static ID2LUserContext InterceptUserTokens(HostSpec host, ID2LAppContext appContext) 
    {
        // Start HTTP server and listen for the redirect after a successful auth
        var httpListener = new HttpListener();
        httpListener.Prefixes.Add("http://localhost:31337/result/");
        httpListener.Start();

        // This call blocks until we get a response
        var ctx = httpListener.GetContext();

        // The LMS returns the user tokens via query parameters to the value provided originally in x_target
        // TODO: deal with "failed to login" case
        var userContext = appContext.CreateUserContext(ctx.Request.Url, host);

        // Send some JavaScript to close the browser popup
        // This is not 100% effective: for example, Firefox will ignore this.
        const string RESPONSE = "<!doctype html><meta charset=\"utf-8\"><script>window.close();</script><h1>You may now close your window</h1><p>You may or may not see this message, depending on your browser</p>";
        byte[] buffer = System.Text.Encoding.UTF8.GetBytes(RESPONSE);
        ctx.Response.ContentType = "text/html";
        ctx.Response.ContentLength64 = buffer.Length;
        ctx.Response.OutputStream.Write(buffer, 0, buffer.Length);
        ctx.Response.OutputStream.Close();
        httpListener.Stop();

        return userContext;
    }


    private static void DoApiStuff(string host, ID2LUserContext userContext)
    {
        const string COURSEOFFERING_ROUTE = "/d2l/api/lp/1.0/courses/644849";

        var client = new RestClient(host);
        var valenceAuthenticator = new D2L.Extensibility.AuthSdk.Restsharp.ValenceAuthenticator(userContext);
        var request = new RestRequest(COURSEOFFERING_ROUTE, Method.GET);
        valenceAuthenticator.Authenticate(client, request);

        var response = client.Execute<CourseOfferingResponse>(request);

        Console.WriteLine("Hello, " + {course offerings information} );
    }

    private void ButtonAccept_Click(object sender, EventArgs e)
    {   

        // This is the LMS we will interact with
        var host = new HostSpec("https", "www.foltest.ca", 443);

        // The appId/appKey come from our app.config - it is good to seperate access keys from the code that uses them.
        // Ideally you wouldn't have production keys committed to source control.
        string appId = ConfigurationManager.AppSettings["appId"];
        string appKey = ConfigurationManager.AppSettings["appKey"];

        // This is the port we will temporarily host a server on to intercept the user tokens after a successful login
        int port = int.Parse(ConfigurationManager.AppSettings["serverPort"]);

        // Create url for the user to login. If they have already done so they will not actually have to type their password (maybe).
        var appContextFactory = new D2LAppContextFactory();
        var appContext = appContextFactory.Create(appId, appKey);
        var authUrl = appContext.CreateUrlForAuthentication(host, new Uri("http://localhost:" + port + "/result/"));

        //OpenBrowser(authUrl);

        // This call will block until we have a result
        // TODO: you'll want better control flow and error handling here
        var userContext = InterceptUserTokens(host, appContext);

        // Now we can call Valence
        DoApiStuff(host.Scheme + "://" + host.Host + ":" + host.Port, userContext);

        // Pause the terminal
        Console.ReadKey();

    }


}

}

任何形式的帮助将不胜感激。谢谢,菲利普

1 个答案:

答案 0 :(得分:0)

而不是:

var authUrl = appContext.CreateUrlForAuthentication(host, new Uri("http://localhost:" + port + "/result/"));

//OpenBrowser(authUrl);

// call will block until we have a result
// TODO: you'll want better control flow and error handling here
var userContext = InterceptUserTokens(host, appContext);

// Now we can call Valence
DoApiStuff(host.Scheme + "://" + host.Host + ":" + host.Port, userContext);

做的:

const string userId = "a_user_id"; // Use the correct user id
const string userKey = "a_user_key"; // Use the correct user key
var userContext = appContext.CreateUserContext(userId, userKey, host);
DoApiStuff(host.Scheme + "://" + host.Host + ":" + host.Port, userContext);

这假设您拥有一个Valence用户ID和您想要使用的用户帐户的密钥。如果你不这样做,你需要在带外生成它们。