4

I want to protect some APIs using OAuth and I want to use Sitecore's new instance of IdentityServer 4. I could just build my own login logic and stick it in the API call. But I would like to use the existing Sitecore.

I found this JwtBearerAuthentication pipeline, but I think it is only used for Azure logins.

<processor type="Sitecore.Owin.Authentication.IdentityServer.Pipelines.Initialize.JwtBearerAuthentication, Sitecore.Owin.Authentication.IdentityServer" resolve="true" patch:source="Sitecore.Owin.Authentication.IdentityServer.config">
   <identityProviderName>SitecoreIdentityServer</identityProviderName>
   <audiences hint="raw:AddAudience">
   <audience value="https://SitecoreIdentityServerHost/resources"/>
   </audiences>
   <issuers hint="list">
   <issuer>https://SitecoreIdentityServerHost</issuer>
   </issuers>
</processor>

So imagine that a remote application wants to OAuth off of my Sitecore 9.1 Identity server. That seems to be fine, I can get a bearer token from the identity server. But I can not find a pipeline in Sitecore that will accept the bearer token to authorize my APIs.

When I dig into the Sitecore Commerce dlls, I find that the Sitecore .net Core apps are wired up to the identity server and can accept an Authentication property in the headers for authenticating bearer tokens. I just don’t see this for Sitecore yet.

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddIdentityServerAuthentication(options =>
{
    options.Authority = this.Configuration.GetSection("AppSettings:SitecoreIdentityServerUrl").Value;
    options.RequireHttpsMetadata = false;
    options.EnableCaching = false;
    options.ApiName = "EngineAPI";
    options.ApiSecret = "secret";
});

Also this post has provided the best so far for talking to the IS4 https://tothecore.sk/2018/07/25/setting-up-development-environment-with-postman-and-sitecore-experience-commerce-sxc-9/#comment-257

PowerShell

I found a little more code on how to generate tokens in PowerShell.

To use the PostMan scripts, you need a new client on the indentity server called postman-api. Add this to the file \wwwroot\xxx.identityserver\Config\production\Sitecore.IdentityServer.Host.xml. This will allow us to call out custom client for openid.

<Clients>
    <DefaultClient>
      <AllowedCorsOrigins>
        <AllowedCorsOriginsGroup1>https://habitathome.dev.local|https://habitathomebasic.dev.local</AllowedCorsOriginsGroup1>
      </AllowedCorsOrigins>
    </DefaultClient>
    <PasswordClient>
      <ClientSecrets>
        <ClientSecret1>ClientSecret</ClientSecret1>
      </ClientSecrets>
    </PasswordClient>
    <PostmanClient>
      <ClientId>postman-api</ClientId>
      <ClientName>postman-api</ClientName>
      <AccessTokenType>0</AccessTokenType>
      <AllowOfflineAccess>true</AllowOfflineAccess>
      <AlwaysIncludeUserClaimsInIdToken>false</AlwaysIncludeUserClaimsInIdToken>
      <AccessTokenLifetimeInSeconds>3600</AccessTokenLifetimeInSeconds>
      <IdentityTokenLifetimeInSeconds>3600</IdentityTokenLifetimeInSeconds>
      <AllowAccessTokensViaBrowser>true</AllowAccessTokensViaBrowser>
      <RequireConsent>false</RequireConsent>
      <RequireClientSecret>true</RequireClientSecret>
      <AllowedGrantTypes>
        <AllowedGrantType1>password</AllowedGrantType1>
      </AllowedGrantTypes>
      <AllowedCorsOrigins>
      </AllowedCorsOrigins>
      <AllowedScopes>
        <AllowedScope1>openid</AllowedScope1>
        <AllowedScope2>sitecore.profile</AllowedScope2>
        <AllowedScope3>sitecore.profile.api</AllowedScope3>
      </AllowedScopes>
      <ClientSecrets>
        <ClientSecret1>ClientSecret</ClientSecret1>
      </ClientSecrets>
      <UpdateAccessTokenClaimsOnRefresh>true</UpdateAccessTokenClaimsOnRefresh>
    </PostmanClient>
</Clients>

Finally you can use this PowerShell to generate a token. https://gist.github.com/johnkors/454c829aa63e7663745da5ebeb38dd86

The only issue I still have is that Sitecore will not validate the JWT token. My error is:

8604 01:14:45 ERROR Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationMiddleware - Authentication failed

Exception: Microsoft.IdentityModel.Tokens.SecurityTokenInvalidSignatureException Message: IDX10500: Signature validation failed. No security keys were provided to validate the signature.

Source: System.IdentityModel.Tokens.Jwt at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters) in C:\agent2_work\15\s\src\System.IdentityModel.Tokens.Jwt\JwtSecurityTokenHandler.cs:line 1057 at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken) in C:\agent2_work\15\s\src\System.IdentityModel.Tokens.Jwt\JwtSecurityTokenHandler.cs:line 768 at Microsoft.Owin.Security.Jwt.JwtFormat.Unprotect(String protectedText) at Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationHandler.d__0.MoveNext()

1

I finally got back the answer on using the right token for authentication with iDentity server Bearer tokens.

For anyone who comes behind, a sharable Postman set of APi calls can be found here. https://www.getpostman.com/collections/a98dc7091c404c879b77

Here is the basic super simple controller that returns json data. The important part is the [Authorize] attribute. This forces the controller through whatever security is registered with MVC.

public class MembershipController : Controller
{
    [HttpGet]
    [Authorize]
    public ActionResult Test()
    {
        var test = new {TestError = "this thing"};

        return Json(test, JsonRequestBehavior.AllowGet);
    }
}

In the image below, this is how you make a call to the identity server (https://sc910.identityserver/connect/token) to get the bearer token from the Sitecore identity server. You can find the client secret at \Config\production\Sitecore.IdentityServer.Host.xml in the root of the identity server.

The key to making this work is that the grant_type is password and client_id is SitecorePassword. When executed you will get a token.

enter image description here

Then we can call our api passing in the bearer token, in the header as the variable Authorization. You must add the word Bearer before your token. When executed, Sitecore with authentication you token and give you access.

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.