IdentityServer / IdentityServer2

[deprecated] Thinktecture IdentityServer is a light-weight security token service built with .NET 4.5, MVC 4, Web API and WCF.
Other
410 stars 291 forks source link

How can I configure claim authentication in a separate asp.net mvc authentication website with Thinktecture 2 with friendly user login page? #847

Open zinov opened 9 years ago

zinov commented 9 years ago

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.

Said that I will show you the Login Method in AccountController

[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

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:

  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

I am attaching the link to stackoverflow too

http://stackoverflow.com/questions/30196008/how-can-i-configure-claim-authentication-in-a-separate-asp-net-mvc-authenticatio

zinov commented 9 years ago

Also I am trying to pass the user name and password to the website that I want to redirect, an there I can call my authentication service and I am writting this code but the cookie is not present at the end

           var service = new AuthenticationServiceAgent(user.Username, user.Password);
           GenericXmlSecurityToken token = service.GetToken() as GenericXmlSecurityToken;

            ClaimsPrincipal cPrincipal = GetClaimsPrincipal(token, user);

            var sesionToken = new SessionSecurityToken(cPrincipal)
            {
                IsReferenceMode = true,
                IsPersistent = true
            };

            FederatedAuthentication.WSFederationAuthenticationModule.SetPrincipalAndWriteSessionToken(
                        sesionToken, true);

            FederatedAuthentication.WSFederationAuthenticationModule.PersistentCookiesOnPassiveRedirects = true;
            FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sesionToken);
zinov commented 9 years ago

I opened a chat room too http://chat.stackoverflow.com/rooms/77736/windows-identity-federation

zinov commented 9 years ago

Do I need to create a cookie manually? If that is the solution, which are the values that I need to store?