I am working on federation authentication via the Identity server in Sitecore 10.2 SXA. Created below class
public class DemoIdentityProvider : IdentityProvidersProcessor
{
private readonly ICookieManager cookieManager;
readonly string clientId = Sitecore.Configuration.Settings.GetSetting("ClientId");
readonly string redirectUri = Sitecore.Configuration.Settings.GetSetting("RedirectUri");
readonly string clientSecret = Sitecore.Configuration.Settings.GetSetting("ClientSecret");
readonly string authority = Sitecore.Configuration.Settings.GetSetting("Authority");
readonly string postLogoutRedirectUri = Sitecore.Configuration.Settings.GetSetting("PostLogoutRedirectUri");
readonly string errorUri = Sitecore.Configuration.Settings.GetSetting("ErrorMessage");
public DemoIdentityProvider(
FederatedAuthenticationConfiguration federatedAuthenticationConfiguration,
ICookieManager cookieManager,
BaseSettings settings) : base(federatedAuthenticationConfiguration, cookieManager, settings)
{
this.cookieManager = cookieManager ?? throw new ArgumentNullException(nameof(cookieManager));
}
protected override void ProcessCore(IdentityProvidersArgs args)
{
var authenticationType = this.GetAuthenticationType();
var identityProvider = this.GetIdentityProvider();
var saveSigninToken = identityProvider.TriggerExternalSignOut;
var oidcOptions = this.SetupOidcOptions(authenticationType, saveSigninToken);
args.App.UseOpenIdConnectAuthentication(oidcOptions);
}
public OpenIdConnectAuthenticationOptions SetupOidcOptions(
string authenticationType,
bool saveSigninToken)
{
var oidcOptions = new OpenIdConnectAuthenticationOptions
{
AuthenticationType = authenticationType,
AuthenticationMode = AuthenticationMode.Passive,
Authority = authority,
ClientId = clientId,
ClientSecret = clientSecret,
ResponseMode = OpenIdConnectResponseMode.FormPost,
ResponseType = OpenIdConnectResponseType.IdTokenToken,
RedirectUri = redirectUri,
PostLogoutRedirectUri = postLogoutRedirectUri,
RedeemCode = true,
Scope = OpenIdConnectScope.OpenIdProfile + " " + OpenIdConnectScope.OfflineAccess,
RequireHttpsMetadata = true,
Notifications = new OpenIdConnectAuthenticationNotifications
{
// RedirectToIdentityProvider = this.RedirectToIdentityProviderAsync,
SecurityTokenValidated = this.SecurityTokenValidatedAsync
},
TokenValidationParameters =
{
SaveSigninToken = saveSigninToken
},
CookieManager = cookieManager
};
return oidcOptions;
}
protected override string IdentityProviderName => "DemoIdentityProvider";
protected BaseLog Log { get; }
public Collection<string> Scopes { get; } = new Collection<string>();
private Task SecurityTokenValidatedAsync(SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
{
var identityProvider = this.GetIdentityProvider();
var identity = notification.AuthenticationTicket.Identity;
foreach (var current in identityProvider.Transformations)
{
current.Transform(identity, new TransformationContext(this.FederatedAuthenticationConfiguration, identityProvider));
}
return Task.CompletedTask;
}
}
Patch file
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
<sitecore>
<federatedAuthentication type="Sitecore.Owin.Authentication.Configuration.FederatedAuthenticationConfiguration, Sitecore.Owin.Authentication">
<identityProvidersPerSites hint="list:AddIdentityProvidersPerSites">
<mapEntry name="sites with extranet domain" type="Sitecore.Owin.Authentication.Collections.IdentityProvidersPerSitesMapEntry, Sitecore.Owin.Authentication" resolve="true" patch:instead="*[@name='sites with extranet domain']">
<sites hint="list">
<site>demo</site>
</sites>
<identityProviders hint="list:AddIdentityProvider">
<identityProvider ref="federatedAuthentication/identityProviders/identityProvider[@id='DemoIdentityProvider']" />
</identityProviders>
<externalUserBuilder type="Sitecore.Owin.Authentication.Services.DefaultExternalUserBuilder, Sitecore.Owin.Authentication" resolve="true">
<IsPersistentUser>false</IsPersistentUser>
</externalUserBuilder>
</mapEntry>
</identityProvidersPerSites>
<identityProviders>
<identityProvider id="DemoIdentityProvider" type="Sitecore.Owin.Authentication.Configuration.DefaultIdentityProvider, Sitecore.Owin.Authentication">
<param desc="name">$(id)</param>
<param desc="domainManager" type="Sitecore.Abstractions.BaseDomainManager" resolve="true" />
<caption>Go to login</caption>
<domain>extranet</domain>
<triggerExternalSignOut>true</triggerExternalSignOut>
<!--list of identity transfromations which are applied to the provider when a user signin-->
<transformations hint="list:AddTransformation">
<!--SetIdpClaim transformation-->
<transformation name="Idp Claim" type="Sitecore.Owin.Authentication.Services.SetIdpClaimTransform, Sitecore.Owin.Authentication" />
<!-- If external authentication is configured with "TokenValidationParameters = {SaveSigninToken = true}", this saves the value from "claimsIdentity.BootstrapContext" to the "id_token" claim. -->
<transformation name="set id_token claim" type="Sitecore.Owin.Authentication.Services.SaveIdTokenInClaim, Sitecore.Owin.Authentication" />
</transformations>
</identityProvider>
</identityProviders>
</federatedAuthentication>
<pipelines>
<owin.identityProviders>
<processor type="demo.Foundation.SSO.IdentityProvider.DemoIdentityProvider, demo.Foundation.SSO" resolve="true" id="DemoIdentityProvider">
<scopes hint="list">
<scope name="openid">openid</scope>
<scope name="profile">profile</scope>
<scope name="offline_access">offline_access</scope>
</scopes>
</processor>
</owin.identityProviders>
</pipelines>
</sitecore>
</configuration>
Scenario 1:
- I have created blank login component
- Added
loginPage
andrequireLogin
in Site Grouping.
- Selected login page in Site grouping. If I don't select login page then it throw error
No login page specified for current site: demo (method: System.Web.Mvc.ControllerActionInvoker.InvokeAuthenticationFiltersChallenge(ControllerContext controllerContext, IList
1 filters, ActionDescriptor actionDescriptor, ActionResult result)).`
Now while I am checking www.demo.com/login
nothing is happening
Scenario 2:
- On login component I did below code:
public override ActionResult Index()
{
var args = new GetSignInUrlInfoArgs("demo", "/");
GetSignInUrlInfoPipeline.Run(_pipelineManager, args);
model.Result = args.Result;
return View(model);
}
<div>
@foreach (var signIn in Model.Result)
{
using (Html.BeginForm(null, null, FormMethod.Post, new { @action = signIn.Href }))
{
<button type="submit">
<img src="@signIn.Icon" />
Login
</button>
}
}
</div>
- On login button click, below requests are going
- It is redirecting to
https://xxx-sso-dev.sharepointguild.com/Oops/Error?statusCode=403
- If I run get request in browser then it redirect to SSO and SSO is working but not on click of login button.
I am really not sure in scenario 1 and scenario 2 what is wrong? Please help.