如何在具有友好用户登录页面的Thinktecture 2的单独asp.net mvc认证网站中配置声明身份验证?

时间:2021-12-29 06:06:01

Can anybody tell me what is going wrong with this approach for single sing on?

任何人都能告诉我这种单唱方式出了什么问题?

I have a website A with the authentication logic inside. The user can select the role to access the portal that he wants to go. The problem is how can I configure properly those websites to redirect correctly, because when I redirect, I lose the token(redirect is a GET), I never had the cookie on the portal that I want to go. Do I am missing something in my implementation? Maybe a configuration on the portal that I want to redirect? I am not using the audienceUri on the webconfig, Is this related with the problem? I am using a service that gives me a token if the user is authenticated. Then with that token, I want to redirect the page to the corresponding portal.

我有一个内部有身份验证逻辑的网站A.用户可以选择角色来访问他想要访问的门户。问题是如何正确配置这些网站以正确重定向,因为当我重定向时,我丢失了令牌(重定向是一个GET),我从未在门户网站上找到我想去的cookie。我在实施中遗漏了什么吗?也许我想要重定向的门户网站上的配置?我没有在webconfig上使用audienceUri,这与问题有关吗?我正在使用一个服务,如果用户通过身份验证,它会给我一个令牌。然后使用该令牌,我想将页面重定向到相应的门户。

如何在具有友好用户登录页面的Thinktecture 2的单独asp.net mvc认证网站中配置声明身份验证?

如何在具有友好用户登录页面的Thinktecture 2的单独asp.net mvc认证网站中配置声明身份验证?

Said that I will show you the Login Method in AccountController

说我将在AccountController中显示Login方法

 [HttpPost]
    public async Task<ActionResult> Login(string ddlRoles, string ddlUrls, LoginModel user)
    {
        var service = new AuthenticationServiceAgent(user.Username, user.Password);
        var securityService = new SecurityServiceAgent(service.GetToken());

       ...processing the claims
       //AT THIS POINT THE USER IS AUTHENTICATED
       FederatedAuthentication.WSFederationAuthenticationModule.SetPrincipalAndWriteSessionToken(token, true);
       .... get the url to redirect 
      Response.Redirect(urlToRedirect, false);
    }

My Proxy class looks like this

我的Proxy类看起来像这样

public class UserNameTokenServiceProxy : TokenServiceProxy
    {
        #region Properties

        public SecurityCredential Credential { get; set; }

        #endregion

        #region Methods

        public override SecurityToken GetToken(ISecurityCredential credential = null)
        {
            if (null == credential)
            {
                throw new ArgumentNullException("credential");
            }

            var factory = new WSTrustChannelFactory(
                new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
                new EndpointAddress(StsEndPoint)
            );

            factory.TrustVersion = TrustVersion.WSTrust13;

            if (null != factory.Credentials)
            {
                factory.Credentials.UserName.UserName = credential.UserName;
                factory.Credentials.UserName.Password = credential.Password;
            }

            var rst = new RequestSecurityToken()
            {
                RequestType = RequestTypes.Issue,
                KeyType = KeyTypes.Symmetric,
                TokenType = TokenTypes.Saml11TokenProfile11,
                ***********RelyingPartyUri comes from a config file*********
                AppliesTo = new EndpointReference(RelyingPartyUri)
            };

            try
            {
                var channel = factory.CreateChannel();
                var sToken = channel.Issue(rst);

                return sToken;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        #endregion

    }

}

And the base class of that one is the following:

那个基类是如下:

public abstract class TokenServiceProxy
{
    #region Fields

    protected string StsEndPoint;
    protected string RelyingPartyUri;

    #endregion

    #region Constructors

    protected TokenServiceProxy()
    {
        StsEndPoint = ConfigurationManager.AppSettings["stsEndpoint"];
        if (null == StsEndPoint)
        {
            throw new Exception("STSEndPoint cannot be null");
        }

        RelyingPartyUri = ConfigurationManager.AppSettings["relyingPartyUri"];
        if (null == RelyingPartyUri)
        {
            throw new Exception("RelyingPartyUri cannot be null");
        }
        //StsEndPoint = <add key="stsEndpoint" value="https://sso.dev.MyCompany.com/idsrv/issue/wstrust/mixed/username"/>;
        //RelyingPartyUri = @"value="https://dev.MyCompany.com/MyCompanyPortal"/>";
    }

    #endregion

    #region Abstract Methods

    public abstract SecurityToken GetToken(ISecurityCredential credential = null);

    #endregion

}

Basically we are not using the default configuration for WS with the audienceUri and the federationConfiguration section, the equivalent would be:

基本上我们没有使用带有audienceUri和federationConfiguration部分的WS的默认配置,相当于:

  <system.identityModel.services>
    <federationConfiguration>
      <cookieHandler mode="Default" requireSsl="false" />
      <wsFederation passiveRedirectEnabled="true" issuer="https://sso.dev.MyCompany.com/idsrv/issue/wstrust/mixed/username" realm="https://dev.MyCompany.com/MyCompanyPortal" requireHttps="false" />
    </federationConfiguration>
  </system.identityModel.services>

1 个解决方案

#1


I'm not quite sure what are all the components in your solution, but in any case you seem to try to do too much on your own. SSO or not - each integrated application needs to maintain its own authentication state (with authentication cookie), and to do so it needs to get the security token from Identity Provider. In a most common scenario for WS-Federation (Relying Party initiated SSO), Relying Party application redirects user to Identity Provider, Identity Provider checks user credentials and POSTS security token back to Relying Party application, where it is handled by WS-Federation module to create authentication cookie. In your case I guess that you are trying to achieve "Identity Provider initiated" SSO (assuming, that your login page is part of Identity Provider). If this is the case, you need to POST created security token to selected Relying Party (as far as I know WS-Federation does not support sending tokens in GET query string). Of course you need to have proper WS-Federation configuration on your Relying Party side to accept this token and create authentication cookie - having that the authentication is done automatically by WS-Federation module.

我不太清楚你的解决方案中的所有组件是什么,但无论如何你似乎都试图自己做太多。是否SSO - 每个集成的应用程序都需要维护自己的身份验证状态(使用身份验证cookie),并且需要从身份提供程序获取安全令牌。在WS-Federation(依赖方启动的SSO)的最常见场景中,依赖方应用程序将用户重定向到身份提供者,身份提供者将用户凭据和POSTS安全令牌检回到依赖方应用程序,在那里由WS-Federation模块处理创建身份验证cookie。在您的情况下,我猜您正在尝试实现“身份提供商发起的”SSO(假设您的登录页面是身份提供商的一部分)。如果是这种情况,您需要将POST创建的安全令牌POST到选定的依赖方(据我所知,WS-Federation不支持在GET查询字符串中发送令牌)。当然,您需要在依赖方端进行适当的WS-Federation配置以接受此令牌并创建身份验证cookie - 由WS-Federation模块自动完成身份验证。

#1


I'm not quite sure what are all the components in your solution, but in any case you seem to try to do too much on your own. SSO or not - each integrated application needs to maintain its own authentication state (with authentication cookie), and to do so it needs to get the security token from Identity Provider. In a most common scenario for WS-Federation (Relying Party initiated SSO), Relying Party application redirects user to Identity Provider, Identity Provider checks user credentials and POSTS security token back to Relying Party application, where it is handled by WS-Federation module to create authentication cookie. In your case I guess that you are trying to achieve "Identity Provider initiated" SSO (assuming, that your login page is part of Identity Provider). If this is the case, you need to POST created security token to selected Relying Party (as far as I know WS-Federation does not support sending tokens in GET query string). Of course you need to have proper WS-Federation configuration on your Relying Party side to accept this token and create authentication cookie - having that the authentication is done automatically by WS-Federation module.

我不太清楚你的解决方案中的所有组件是什么,但无论如何你似乎都试图自己做太多。是否SSO - 每个集成的应用程序都需要维护自己的身份验证状态(使用身份验证cookie),并且需要从身份提供程序获取安全令牌。在WS-Federation(依赖方启动的SSO)的最常见场景中,依赖方应用程序将用户重定向到身份提供者,身份提供者将用户凭据和POSTS安全令牌检回到依赖方应用程序,在那里由WS-Federation模块处理创建身份验证cookie。在您的情况下,我猜您正在尝试实现“身份提供商发起的”SSO(假设您的登录页面是身份提供商的一部分)。如果是这种情况,您需要将POST创建的安全令牌POST到选定的依赖方(据我所知,WS-Federation不支持在GET查询字符串中发送令牌)。当然,您需要在依赖方端进行适当的WS-Federation配置以接受此令牌并创建身份验证cookie - 由WS-Federation模块自动完成身份验证。