Как войти в систему с помощью OWIN с заявкой SAML, возвращенной из ADFS с использованием ASP.NET MVC?

У меня есть веб-сайт, который имеет собственный экран входа в систему, где пользователь вводит свое имя пользователя и пароль. После нажатия кнопки входа в систему пользователь должен пройти аутентификацию через ADFS, и я должен получить токен SAML обратно. Это работает. На данный момент, однако, я не уверен, что мне нужно сделать, чтобы войти в систему пользователя. Причина, по которой я не уверен, заключается в том, что этот сайт немного искажен. Как я уже сказал, пользователь входит в систему через ADFS через страницу входа на нашем сайте. Однако если пользователь заходит на неавторизованную страницу, вместо того, чтобы перенаправлять пользователя на нашу страницу входа в систему, нам нужно перенаправить пользователя на нашу страницу входа в ADFS. Я начал весь проект таким образом. Пользователь проходит аутентификацию через страницу входа в ADFS. Это было сделано просто путем настройки моего метода ConfigureAuth (в StartupAuth.cs) следующим образом:

public void ConfigureAuth(IAppBuilder app)
{
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

    app.UseCookieAuthentication(new CookieAuthenticationOptions());

    app.UseWsFederationAuthentication(
        new WsFederationAuthenticationOptions
        {
            Wtrealm = realm,
            MetadataAddress = adfsMetadata
        });
}

Достаточно просто! Если я попытаюсь пойти на [Authorized] страница, это приводит меня к странице входа в ADFS. После этого пришло время поработать над другим способом входа в систему (через страницу входа для аутентификации в ADFS). Имейте в виду, что в любом случае, когда вы пытаетесь пройти аутентификацию, вы все равно проходите аутентификацию с помощью той же ADFS; один вы используете страницу входа в ADFS, а другой вы используете пользовательскую страницу входа. Поэтому я создаю пользовательскую страницу входа в систему с простой маленькой формой для входа в систему:

<form action="@Url.Action("SignIn", "Account")" method="post">
    <input type="text" name="username" />
    <input type="password" name="password" />
    <input type="submit" value="Login" />
</form>

Это работает просто отлично. После нажатия кнопки "Отправить" выполняется попытка входа. Действие SignIn выглядит следующим образом:

[HttpPost]
public ActionResult SignIn(string username, string password)
{
    if (!Request.IsAuthenticated)
    {
        const string _relyingPartyUri = "https://myrelayingparty/";
        const string _serverName = "myservername";
        const string certSubject = "CN=mycertsubject";
        string endpointUri = string.Format("https://{0}/adfs/services/trust/13/usernamemixed", _serverName);

        var factory = new WSTrustChannelFactory(new UserNameWSTrustBinding(), endpointUri)
        {
            TrustVersion = TrustVersion.WSTrust13
        };

        factory.Credentials.UserName.UserName = @"mydomain\" + username;
        factory.Credentials.UserName.Password = password;

        var rst = new RequestSecurityToken
        {
            RequestType = RequestTypes.Issue,
            AppliesTo = new EndpointReference(_relyingPartyUri),
            KeyType = KeyTypes.Bearer
        };

        var channel = factory.CreateChannel();

        var genericToken = channel.Issue(rst) as GenericXmlSecurityToken;

        if (genericToken != null)
        {
            //Setup the handlers needed to convert the generic token to a SAML Token
            var tokenHandlers = new SecurityTokenHandlerCollection(new SecurityTokenHandler[] { new SamlSecurityTokenHandler() });
            tokenHandlers.Configuration.AudienceRestriction = new AudienceRestriction();
            tokenHandlers.Configuration.AudienceRestriction.AllowedAudienceUris.Add(new Uri(_relyingPartyUri));

            var trusted = new TrustedIssuerNameRegistry(certSubject);
            tokenHandlers.Configuration.IssuerNameRegistry = trusted;

            //convert the generic security token to a saml token
            SecurityToken samlToken = tokenHandlers.ReadToken(new XmlTextReader(new StringReader(genericToken.TokenXml.OuterXml)));

            //convert the saml token to a claims principal
            var claimsPrincipal = new ClaimsPrincipal(tokenHandlers.ValidateToken(samlToken).First());


            HttpContext.GetOwinContext().Authentication.SignIn(new AuthenticationProperties { IsPersistent = true, RedirectUri = "Home/Homepage" },
                claimsPrincipal.Identities.ElementAt(0));
        }
    }

    return RedirectToAction("Index", "Home");
}

Он может успешно извлекать и создавать samlToken, а также может проверять его и создавать утверждений Principal. Я не уверен, что делать после этого, чтобы войти в систему. Я пытался использовать HttpContext.GetOwinContext().Authentication.SignIn(new AuthenticationProperties { IsPersistent = true, RedirectUri = "Home/Homepage" }, claimsPrincipal.Identities.ElementAt(0));, но если я проверю Request.IsAuthenticated после этого, это все еще ложно. У меня есть подозрение, что в моем файле StartupAuth.cs требуется дополнительная настройка, но я не уверен, поэтому обращаюсь к вам, ребята. Спасибо за любую помощь!

0 ответов

Другие вопросы по тегам