HTTP Post to Orchard controller from external app

Topics: Customizing Orchard
Sep 19, 2013 at 8:07 PM
I'm trying to connect Orchard to our internal ADFS server to authenticate users using this module: http://gallery.orchardproject.net/List/Modules/Orchard.Module.Authentication.Federated


The problem is that after a user logs into ADFS on the ADFS server it does a POST back to my controller (in the Orchard module). I'm running into the antiforgery exception after this POST because ADFS can't generate the Orchard Antiforgery token...

I can't control that POST, so I can't add in the token on that end. Is there any way to either disable the antiforgery token, or add a token on my controller's end?

I already made sure to set "AntiForgery: disabled" in the module.txt, but it's still trying to validate the token for some reason. Here's the controller code:

``` public ActionResult TestLogOn(string ReturnUrl)
    {
       return LogOn(ReturnUrl);
    }

    public ActionResult LogOn(string ReturnUrl)
    {
        // Redirect to sign-in URL, append ReturnUrl as well...
        var settings = this.SettingsService.Retrieve();

        if (string.IsNullOrEmpty(ReturnUrl))
        {
            ReturnUrl = "/";
        }
        ReturnUrl = "/FederatedAuthentication/ProcessToken?ReturnUrl=" + ReturnUrl;

        SignInRequestMessage req = new SignInRequestMessage(
            new Uri(settings.StsLoginUrl), settings.Realm, settings.ReturnUrlBase + ReturnUrl);

        return new RedirectResult(req.RequestUrl);
    }

    [ValidateInput(false)]
    [AlwaysAccessible]
    public ActionResult Authenticate(string ReturnUrl) {

        //hack to get around Orchard antiforgery
        //var OrchardToken = new Orchard.Mvc.AntiForgery.ValidateAntiForgeryTokenOrchardAttribute();
        //Request.Params.Add("__RequestVerificationToken", OrchardToken.ToString());

        if (Request.Form.Get(WSFederationConstants.Parameters.Result) != null)
        {
            var settings = this.SettingsService.Retrieve();

            // Parse sign-in response
            SignInResponseMessage message =
                WSFederationMessage.CreateFromFormPost(System.Web.HttpContext.Current.Request) as
                SignInResponseMessage;

            XmlTextReader xmlReader = new XmlTextReader(
                new StringReader(message.Result));
            XDocument xDoc = XDocument.Load(xmlReader);
            XNamespace xNs = "http://schemas.xmlsoap.org/ws/2005/02/trust";
            var rst = xDoc.Descendants(xNs + "RequestedSecurityToken").FirstOrDefault();
            if (rst == null)
            {
                throw new ApplicationException("No RequestedSecurityToken element was found in the returned XML token. Ensure an unencrypted SAML 2.0 token is issued.");
            }
            var rstDesc = rst.Descendants().FirstOrDefault();
            if (rstDesc == null)
            {
                throw new ApplicationException("No valid RequestedSecurityToken element was found in the returned XML token. Ensure an unencrypted SAML 2.0 token is issued.");
            }

            var config = new SecurityTokenHandlerConfiguration();
            config.AudienceRestriction.AllowedAudienceUris.Add(new Uri(settings.AudienceUrl));
            config.CertificateValidator = X509CertificateValidator.None;
            config.IssuerNameRegistry = new AccessControlServiceIssuerRegistry(
                settings.StsIssuerUrl, settings.X509CertificateThumbprint);

            var securityTokenHandlers = new SecurityTokenHandlerCollection(config);
            securityTokenHandlers.Add(new Saml11SecurityTokenHandler());
            securityTokenHandlers.Add(new Saml2SecurityTokenHandler());
            securityTokenHandlers.Add(new EncryptedSecurityTokenHandler());

            var token = securityTokenHandlers.ReadToken(rstDesc.CreateReader());

            ClaimsIdentityCollection claims = securityTokenHandlers.ValidateToken(token);
            IPrincipal principal = new ClaimsPrincipal(claims);

            // Map claims to local users
            string roleClaimValue = "";
            string usernameClaimValue = "";
            string emailClaimValue = "";
            foreach (var claimsIdentity in claims)
            {
                foreach (var claim in claimsIdentity.Claims)
                {
                    if (claim.ClaimType == "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" && settings.TranslateClaimsToOrchardRoles)
                    {
                        roleClaimValue = claim.Value;
                    }
                    else if (claim.ClaimType == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" && settings.TranslateClaimsToOrchardUserProperties)
                    {
                        emailClaimValue = claim.Value;
                    }
                    else if (claim.ClaimType == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name")
                    {
                        usernameClaimValue = claim.Value;
                    }
                    else if (claim.ClaimType == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" && string.IsNullOrEmpty(usernameClaimValue))
                    {
                        usernameClaimValue = claim.Value;
                    }
                }
            }

            if (string.IsNullOrEmpty(usernameClaimValue))
            {
                throw new SecurityException("Could not determine username from input claims. Ensure a \"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name\" or \"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier\" claim is issued by the STS.");
            }

            IUser user = MembershipService.GetUser(settings.FederatedUsernamePrefix + usernameClaimValue);
            if (user == null)
            {
                user = MembershipService.CreateUser(new CreateUserParams(settings.FederatedUsernamePrefix + usernameClaimValue,
                                                                      Guid.NewGuid().ToString(), emailClaimValue,
                                                                      Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), true));
            }

            AuthenticationService.SignIn(user, false);

            if (!string.IsNullOrEmpty(roleClaimValue))
            {
                var role = RoleService.GetRoleByName(roleClaimValue);
                if (role != null)
                {
                    UserRolesPartRecord currentRole =
                        UserRolesRepository.Get(r => r.UserId == user.Id && r.Role == role);
                    if (currentRole == null)
                    {
                        UserRolesRepository.Create(new UserRolesPartRecord {UserId = user.Id, Role = role});
                    }
                }
            }
        }

        return new RedirectResult(ReturnUrl);
    }