Achieve SSO using Identity Server 3 in MVC

  • Thread starter Thread starter Siddy Boy
  • Start date Start date
S

Siddy Boy

Guest
I have set up an identity server 3 in my app. Following is the code:

public void ConfigureAuth(IAppBuilder app)
{
// Configure Identity Server
// at the identity uri, you are going to find the identity server
app.Map("/identity", idsrvApp =>
{
idsrvApp.UseIdentityServer(new IdentityServerOptions
{
SiteName = "Embedded identity server",
//IssuerUri = "https://identitysrv3/embedded", // in real scenarios make sure this is unique. to uniquely identify users

Factory = new IdentityServerServiceFactory()
.UseInMemoryClients(Clients.Get())
.UseInMemoryScopes(Scopes.Get())
.UseInMemoryUsers(User.Get()),

// this is not for SSL, that will be provided by IIS or Azure where we deploy. This is to sign the tokens
SigningCertificate = LoadCertificate()
});
});

X509Certificate2 LoadCertificate()
{
return new X509Certificate2(
string.Format(@"{0}\bin\identityServer\idsrv3test.pfx", AppDomain.CurrentDomain.BaseDirectory), "idsrv3test");
}
}


With this for now I am using inmemory users. Do I have to implement ASP.NET identity to achieve SSO?.

This is my User class:

public static List<InMemoryUser> Get()
{
return new List<InMemoryUser>()
{
new InMemoryUser
{
Username = "Sidd",
Password = "secret",
Subject = "1",

Claims = new[]
{
new Claim(Constants.ClaimTypes.GivenName, "Sidd"),
new Claim(Constants.ClaimTypes.FamilyName, "Mehta"),
}
},
new InMemoryUser
{
Username = "Humpty",
Password = "secret",
Subject = "3",

Claims = new[]
{
new Claim(Constants.ClaimTypes.GivenName, "Humpty"),
new Claim(Constants.ClaimTypes.FamilyName, "Sharma"),
}
},
new InMemoryUser
{
Username = "Virat",
Password = "secret",
Subject = "4",

Claims = new[]
{
new Claim(Constants.ClaimTypes.GivenName, "Virat"),
new Claim(Constants.ClaimTypes.FamilyName, "Kohli"),
}
}
};
}

and this is my Clients class:

public static IEnumerable<Client> Get()
{
return new[]
{
new Client
{
Enabled = true,
ClientName = "Identity Server Web Access",
ClientId = "mvc",
Flow = Flows.Hybrid,
//RequireConsent = true,

RedirectUris=new List<string>
{
//"https://localhost:44329/"
AppConstants.IdClient,
AppConstants.IdClient2
},
AllowedScopes = new List<string>
{
"openid",
"profile",
}
}
};
}


The redirect uri's contains the MVC client application URLs.

With the identity and users already set, I make my MVC application client. Both the configurations of the application are similar. Following is the code:

Web Client 2:

public void Configuration(IAppBuilder app)
{
// For more information on how to configure your application, visit An Overview of Project Katana

app.UseCookieAuthentication(new Microsoft.Owin.Security.Cookies.CookieAuthenticationOptions
{
AuthenticationType = "Cookies"
});

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = "mvc",
Authority = AppConstants.IdSrv,
RedirectUri = AppConstants.IdClient2,
SignInAsAuthenticationType = "Cookies",
ResponseType = "code id_token",
Scope = "openid",

Notifications = new OpenIdConnectAuthenticationNotifications()
{
MessageReceived = async n =>
{
EndpointAndTokenHelper.DecodeAndWrite(n.ProtocolMessage.IdToken);
}

}
});
}

Web Client 1:

public void Configuration(IAppBuilder app)
{
// For more information on how to configure your application, visit An Overview of Project Katana

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap = new Dictionary<string, string>();

AntiForgeryConfig.UniqueClaimTypeIdentifier = "unique_user_key";

app.UseCookieAuthentication(new Microsoft.Owin.Security.Cookies.CookieAuthenticationOptions
{
AuthenticationType="Cookies"
});

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = "mvc",
Authority = AppConstants.IdSrv,
RedirectUri = AppConstants.IdClient,
SignInAsAuthenticationType = "Cookies",
ResponseType = "code id_token token",
Scope = "openid profile",

Notifications = new OpenIdConnectAuthenticationNotifications()
{
MessageReceived = async n =>
{
//EndpointAndTokenHelper.DecodeAndWrite(n.ProtocolMessage.IdToken);
//EndpointAndTokenHelper.DecodeAndWrite(n.ProtocolMessage.AccessToken);

//var userinfo = await EndpointAndTokenHelper.CallUserInfoEndpoint(n.ProtocolMessage.AccessToken);
},

SecurityTokenValidated=async n =>
{
var userInfo = await EndpointAndTokenHelper.CallUserInfoEndpoint(n.ProtocolMessage.AccessToken);

var givenNameClaim = new Claim(
Thinktecture.IdentityModel.Client.JwtClaimTypes.GivenName,
userInfo.Value<string>("given_name"));

var familyNameClaim = new Claim(
Thinktecture.IdentityModel.Client.JwtClaimTypes.FamilyName,
userInfo.Value<string>("family_name"));

//var roles = userInfo.Value<JArray>("role").ToList();

var newIdentity = new ClaimsIdentity(
n.AuthenticationTicket.Identity.AuthenticationType,
Thinktecture.IdentityModel.Client.JwtClaimTypes.GivenName,
Thinktecture.IdentityModel.Client.JwtClaimTypes.Role);

newIdentity.AddClaim(givenNameClaim);
newIdentity.AddClaim(familyNameClaim);
}


}
});
}

I want to know what more settings need to be done in order to achieve SSO?. I am able to hit the identity server, input my user credentials, have my redirect uri's in place. When I log to both websites it asks me for user credentials when calling on the [Authorize] attribute in my home controller.
Any help on how to achieve SSO using above code I have would be great. Currently I am running on a localhost, but I would be putting both websites under one domain only.

Its very urgent and I need to prepare a demo, so any help quickly would be great.

Thanks in advance!

Continue reading...
 
Back
Top