Azure ACS Set Up in C#

2019-02-19 20:31发布

问题:

I am looking at several examples for using ACS, and decidedly they do make me feel stupid.

I looked at the tutorial online it seems like all I need was the following line in the config:

  httpRuntime requestValidationMode="2.0"

But some other examples in this sample project SimpleMVC4 had no such line in its configuration. Worse, I didn't see anything in there that references ACS library whatever that might be.

The MVC3 sample on the other hand had a bunch of gibberish including an ajax request to a javascript huh!?

    public const string HrdPath = "v2/metadata/IdentityProviders.js";

    /// <summary>
    /// Gets the url with its query string representing this request
    /// </summary>
    /// <returns></returns>
    public string GetUrlWithQueryString()
    {
        uriBuilder.Path = HrdPath;
        uriBuilder.Query = parameters.ToQueryString();

        return uriBuilder.Uri.AbsoluteUri;
    }

and in the Raxor View

    $("#signIn").click(function () {
        //
        // Explicit JSONP callback can be used to do client side caching of identity provider data.
        //
        $.ajax({
            url: "@Html.Raw(Model.GetUrlWithQueryString())",
            dataType: "jsonp",

HUH!?

Look can I just get some simple (idiot proof) pointers?

  1. I am a relying party
  2. I have got an MVC controller action, I want to tell users here are the Identity Providers (IP) that they can use, and their respective URLs as well as generating the tokens that will be verified in step (3), below. How do I get to this in a C# code?
  3. Once, the client, ACS, IP are done with their business, I don't care what that is, as far as I'm concerned all those is between the client, ACS and the IP. I should get another request from the user. What do I do with this request? How do I verify if the user is kosher? And that they did not falsify the token from step (2) above.

回答1:

I too have gone through similar pain in recent past. I was a complete newbie with this and had quite a hard time understanding all this. I found Pluralsight Courses from Dominick Baier quite useful in understanding these concepts.

Now coming to your questions.

I have got an MVC controller action, I want to tell users here are the Identity Providers (IP) that they can use, and their respective URLs as well as generating the tokens that will be verified in step (3), below. How do I get to this in a C# code?

Do take a look at this blog post for creating the login page on your end: https://www.simple-talk.com/cloud/development/creating-a-custom-login-page-for-federated-authentication-with-windows-azure-acs/

Once, the client, ACS, IP are done with their business, I don't care what that is, as far as I'm concerned all those is between the client, ACS and the IP. I should get another request from the user. What do I do with this request? How do I verify if the user is kosher? And that they did not falsify the token from step (2) above.

I don't think you would need to do anything special here. ASP.Net pipeline takes care of it for you by setting the IsAuthenticated property of the Principal to true. Here's what my code currently looks like (mostly taken from the blog post above). For me, the entire application is protected and by default the user lands on the home page. I check if the user is authenticated or not. If they're not authenticated, I show them all Identity Providers configured in ACS and the user can login using any of those. Once the authentication is successful, ACS sends the user back to the same page and this time the user is authenticated. In my code, I do a bunch of claims transformation needed for my application if the user is authenticated.

Controller

public ActionResult Index()
        {
            if (!ClaimsPrincipal.Current.Identity.IsAuthenticated)
            {
                var idpsUrl = "IdentityProvidersUrl Taken from ACS Login Page";
                var webClient = new WebClient()
                {
                    Encoding = Encoding.UTF8,
                };
                var jsonList = webClient.DownloadString(idpsUrl);
                var acsResult = JsonConvert.DeserializeObject<List<IdentityProvider>>(jsonList);
                return View(acsResult);
            }
            else
            {
                var principal = ClaimsPrincipal.Current;
                var claims = principal.Claims;
                //If any claims transformation needs to be done, that can be done here.
            }
        }

View

@{
    ViewBag.Title = "Index";
}


<h2>Index</h2>

    @foreach (var p in Model)
    {
        <p>
            <a href="@p.LoginUrl">@p.ToString()</a>
        </p>
    }

Model

public class IdentityProvider
{
    public List<string> EmailAddressSuffixes { get; set; }
    public string ImageUrl { get; set; }
    public string LoginUrl { get; set; }
    public string LogoutUrl { get; set; }
    public string Name { get; set; }

    public override string ToString()
    {
        return Name;
    }
}