episerver / Foundation

Foundation offers a starting point that is intuitive, well-structured and modular allowing developers to explore CMS, Commerce, Personalization, Search and Navigation, Data Platform and Experimentation.
https://docs.developers.optimizely.com/digital-experience-platform/docs/optimizely-foundation-demo-sites
Apache License 2.0
132 stars 137 forks source link

Add-on controller is not called #776

Open sl-mmuradov opened 2 years ago

sl-mmuradov commented 2 years ago

Hi there,

I built a simple Add-on, installed them to Foundation NET5 Core, but it doesn't work. I'm not sure it is mine issue, or Foundation/EPi12.

Ok, my add-on has only one class

using Microsoft.AspNetCore.Mvc;

namespace MyEPiModule
{
    public class HelloController : Controller
    {
        [HttpGet]
        public ActionResult Index()
        {
            return new ContentResult { Content = "Hello from my EPiServer module!" };
        }

        [HttpGet]
        public ActionResult Show()
        {
            return new ContentResult { Content = "Show: Hello from my EPiServer module!" };
        }
    }
}

It depends on EPiServer.CMS 12.2.1 only. module.config is simple

<?xml version="1.0" encoding="utf-8"?>
<module loadFromBin="false"
        moduleJsonSerializerType="Net"
        prefferedUiJsonSerializerType="Net"
        clientResourceRelativePath=""
        description="My first EPiServer NET5 Core module"
        tags="EPiServerModulePackage">
  <assemblies>
    <add assembly="MyEPiModule"/>
  </assemblies>

  <routes>
    <route url="{moduleArea}/{controller}/{action}/">
      <defaults>
        <add key="moduleArea" value="MyEPiModule" />
        <add key="controller" value="Hello"/>
        <add key="action" value="Index"/>
      </defaults>
    </route>
  </routes>
</module>

I put MyEPiModule.dll to bin folder near Foundation.dll. module.config is put under /modules/_protected/MyEPiModule.

Requests /episerver/myepimodule/hello/index and /episerver/myepimodule/hello/show response HTTP404 Not Found.

In EPi11 I had to desribe my add-on in web.config. But it is obsolete for Foundation NET5 Core (according to EPi doc).

Am I missed something? Are there additional steps for registering add-on in Foundation/EPi12?

lunchin commented 2 years ago

By default the module system does not autodiscover. You can either turn on autodiscover

services.Configure<ProtectedModuleOptions>(x => x.AutoDiscovery = EPiServer.Shell.Configuration.AutoDiscoveryLevel.Modules);

or register manually like

services.Configure<ProtectedModuleOptions>(x =>
            {
                if (!x.Items.Any(x => x.Name.Equals("MyEPiModule")))
                {
                    x.Items.Add(new ModuleDetails
                    {
                        Name = "MyEPiModule"
                    });
                }
            });
sl-mmuradov commented 2 years ago

It works! Thank you @lunchin! Good point to mention that somewhere in https://world.optimizely.com/documentation/developer-guides/CMS/add-ons/

sl-mmuradov commented 2 years ago

Found out one more issue. Add-on controller works fine in browser. It works with auth after login with username/password. But it shows login page in Postman after auth via OpenID. Content Delivery API request /api/episerver/v3.0/content/14 works fine in Postman (OpenID auth), but responses

{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.4","title":"Not Found","status":404,"detail":"Content not found","instance":"/api/episerver/v3.0/content/14","traceId":"00-0fcc7f10a1b91f4dab46163febf2ef3c-c6ad6aa9d43c2140-00","code":"NotFound"}

in browser. I saw doc about introducing OpenID in EPiServer https://world.optimizely.com/documentation/developer-guides/content-delivery-api/getting-started/api-authentication/ but

[Authorize(OpenIDConnectOptionsDefaults.AuthenticationScheme)]
public class MyApiController : ControllerBase
{
}

doesn't work for me. What did I missed to cause my add-on work with auth by OpenID? I appreciate any help. @lunchin I know you have a hidden knowledge ;-)

lunchin commented 2 years ago

In foundation https://github.com/episerver/Foundation/blob/main/src/Foundation/Startup.cs#L118 we register episerver.openconnect

To get a token

http://localhost:50244/epi/episerver/connect/token

grant_type=client_credentials client_id = postman-client client_secret= postman

sl-mmuradov commented 2 years ago

@lunchin yes, it works fine. epi/episerver/connect/token gives me accessToken. I use them as Authentication: Bearer {{accessToken}} for calling episerver/mymodule/hello/index but EPiServer responses with login page.

lunchin commented 2 years ago

Ahh I think the module has a default policy of "Cms Admins" when not configured in module.config.
authorizationPolicy="episerver:cmsadmin"

We plan to add ACL support for applications in future version, which can help with permissions. I think you can test bow using grant_type password with a admin user

grant_type=password client_id = postman-client client_secret= postman usernmae=name password=password

sl-mmuradov commented 2 years ago

Hi @lunchin Tried authorizationPolicy

<?xml version="1.0" encoding="utf-8"?>
<module loadFromBin="false"
        moduleJsonSerializerType="Net"
        prefferedUiJsonSerializerType="Net"
        clientResourceRelativePath=""
        description="My first EPiServer NET5 Core module"
        tags="EPiServerModulePackage"
        authorizationPolicy="episerver:cmsadmin">
  <assemblies>
    <add assembly="MyEPiModule"/>
  </assemblies>

  <routes>
    <route url="{moduleArea}/{controller}/{action}/">
      <defaults>
        <add key="moduleArea" value="MyEPiModule" />
        <add key="controller" value="Hello"/>
        <add key="action" value="Index"/>
      </defaults>
    </route>
  </routes>
</module>

and [Authorize(Policy = "episerver:cmsadmin")] but no luck. I checked both grant_types password and client_credentials. OpenID gives access_token, but server responses login page for a module again (

lunchin commented 2 years ago

okay i will put a sample together today