Many thanks for this info, Erik.

I'll also take a note to add to docs, all great stuff.

Cheers
Dan


On 19 July 2016 at 11:42, Erik de Hair <[email protected]> wrote:

>
> On 07/19/2016 12:20 PM, Dan Haywood wrote:
>
>> Willie,
>>
>> thanks very much for taking the time to document all this; great to know
>> it's doable.
>>
>> It *is* in fact possible to add additional endpoints to the RO viewer; you
>> need to subclass RestfulObjectsApplication [1] to add your additional
>> endpoints and then to register in web.xml [2]
>>
> Our application uses this approach to make it easier to configure
> firewalls to access certain paths on the web server by different parties
> and because we use xml webservices of suppliers that deliver xml-messages
> to our application (because they dictate that).
>
> We added a servlet(mapping) to web.xml
>
> <servlet>
> <servlet-name>RestfulObjectsWebServiceDispatcher</servlet-name>
>
> <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
>         <init-param>
> <param-name>resteasy.servlet.mapping.prefix</param-name>
>             <param-value>/ws/</param-value>
>         </init-param>
>         <!-- used by RestEasy to determine the JAX-RS resources and other
> related
>         configuration -->
>         <init-param>
> <param-name>javax.ws.rs.Application</param-name>
> <param-value>webapp.PortalRestfulObjectsApplication</param-value>
>         </init-param>
>     </servlet>
> ...
> <servlet-mapping>
> <servlet-name>RestfulObjectsWebServiceDispatcher</servlet-name>
>         <url-pattern>/ws/*</url-pattern>
>     </servlet-mapping>
>
> The implementation of webapp.PortalRestfulObjectsApplication:
>
> public class PortalRestfulObjectsApplication extends
> AbstractJaxRsApplication {
>
>     public PortalRestfulObjectsApplication() {
>         addSingleton(new RestfulObjectsApplicationExceptionMapper());
>         addSingleton(new RuntimeExceptionMapper());
>         // add services
>         addClass(AccessAvailabilityService.class);
>         addClass(PortingXSService.class);
>     }
> }
>
> But I believe we had a problem starting multiple RestEasy applications and
> I think we had to add a filter to the web application to make sure they
> both start.
>
> public class ResteasyCleanupFilter implements Filter {
>     private FilterConfig config;
>
>     @Override
>     public void init(FilterConfig filterConfig) throws ServletException {
>         this.config = filterConfig;
>     }
>
>     @Override
>     public void doFilter(ServletRequest request, ServletResponse response,
> FilterChain chain) throws IOException, ServletException {
> config.getServletContext().setAttribute(ResteasyProviderFactory.class.getName(),
> null);
> config.getServletContext().setAttribute(Dispatcher.class.getName(), null);
>         chain.doFilter(request, response);
>     }
>
>     @Override
>     public void destroy() {
>         // TODO Auto-generated method stub
>     }
> }
>
> filter-config in web.xml
>
> <filter>
>         <filter-name>CleanupFilter</filter-name>
> <filter-class>webapp.restful.ResteasyCleanupFilter</filter-class>
>     </filter>
>     <filter-mapping>
>         <filter-name>CleanupFilter</filter-name>
>         <url-pattern>/*</url-pattern>
>     </filter-mapping>
>
> Part of implementation of PortingXSService.class (in this case it's a xml
> web service):
>
> @Path("portingxs")
> public class PortingXSService extends AbstractIsisSessionTemplate {
>     @Context
>     HttpHeaders httpHeaders;
>     @Context
>     UriInfo uriInfo;
>     @Context
>     Request request;
>     @Context
>     HttpServletRequest httpServletRequest;
>     @Context
>     HttpServletResponse httpServletResponse;
>     @Context
>     SecurityContext securityContext;
>
>     @POST
>     @Path("/")
>     @Consumes(MediaType.TEXT_XML)
>     @Produces({ MediaType.TEXT_XML })
>     public Response receive(final String input) {
>         final ObjectAdapter serviceAdapter =
> getServiceAdapter("nl.pocos.portingxs.PortingXSService");
>         nl.pocos.portingxs.PortingXSService service =
> (nl.pocos.portingxs.PortingXSService) serviceAdapter.getObject();
>         Object response = ...;
>         ResponseBuilder rb = Response.status(200).entity(response);
>         return rb.build();
>     }
>
>     protected ObjectAdapter getServiceAdapter(final String serviceId) {
>         final List<ObjectAdapter> serviceAdapters =
> getPersistenceSession().getServices();
>         for (final ObjectAdapter serviceAdapter : serviceAdapters) {
>             final Object servicePojo = serviceAdapter.getObject();
>             final String id = ServiceUtil.id(servicePojo);
>             if (serviceId.equals(id)) {
>                 return serviceAdapter;
>             }
>         }
>         throw
> RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.NOT_FOUND,
> "Could not locate service '%s'", serviceId);
>     }
> }
>
>>
>> I'll take a note to add this detail into the "ro viewer" guide [3], and
>> also to add your longer recipe as to how oauth can be added into the
>> "beyond the basics" guide [4]
>>
>> Or, if you/anyone else has the time, PRs on docs gratefully received!
>>
>> Thx again
>> Dan
>>
>>
>> [1]
>>
>> https://github.com/apache/isis/blob/master/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplication.java#L36
>> [2]
>>
>> https://github.com/apache/isis/blob/master/example/application/simpleapp/webapp/src/main/webapp/WEB-INF/web.xml#L272
>> [3]
>>
>> https://github.com/apache/isis/blob/master/adocs/documentation/src/main/asciidoc/guides/ugvro.adoc
>> [4]
>>
>> https://github.com/apache/isis/blob/master/adocs/documentation/src/main/asciidoc/guides/ugbtb.adoc
>>
>> On 28 June 2016 at 08:44, Willie Loyd Tandingan <[email protected]>
>> wrote:
>>
>> Hi Pedro and Dan,
>>>
>>> I've already opened the topic on open-sourcing the OAuth2 module we've
>>> implemented but I don't think it can be done sooner.
>>>
>>> What we did was basically find an implementation of OAuth2 and integrate
>>> it with Apache Isis. There are some suggested in [1] but are not well
>>> maintained. I have considered replacing Shiro with Spring Security but
>>> thought that it would take too much effort and time.
>>>
>>> In the end, we also had a hard time creating another JAX-RS application
>>> since resteasy used by RO viewer unfortunately doesn't support multiple
>>> applications. We wanted the OAuth2 module to be a detachable module on
>>> top
>>> of RO while maintaining no modifications to RO code, and with no changes
>>> to
>>> the existing wicket viewer. Due to these requirements, we had decided to
>>> use Restlet with its oauth extension, and integrated it with Shiro, RO,
>>> and
>>> Apache Isis. This also allowed us to create endpoints outside of RO. At
>>> the
>>> moment, we are needing only the password grant flow so the tokens are
>>> actually persisted but the client manager is in-memory.
>>>
>>> Basically we did the following to integrate Restlet with RO and Apache
>>> Isis:
>>>
>>> 1. Implement org.restlet.ext.oauth.internal.Token as domain object.
>>> 2. Implement org.restlet.ext.oauth.internal.TokenManager as domain
>>> service.
>>> 3. Implement org.restlet.ext.oauth.internal.Client. We implemented this
>>> in-memory.
>>> 4. Setup the Restlet OAuth2 token endpoint using the implementations
>>> above. Note they must be running under Isis context. We referred to the
>>> the
>>> security addon for integration patterns, and used similar techniques e.g.
>>> IsisContext to open session, execute closures using transaction manager,
>>> and close session.
>>> 5. Create transaction filter for this endpoint.
>>>
>>> Above will implement token generation, verification, and revocation. For
>>> integration with Shiro:
>>>
>>> 6. Implement org.restlet.ext.oauth.internal.ResourceOwnerManager. This
>>> creates wraps the username and password given for password grant flow in
>>> a
>>> AuthenticationRequestPassword, and passes it to Apache Isis
>>> AuthenticationManager.
>>> 7. Create implementations of AuthenticationRequestToken (we extended
>>> AuthenticationRequestPassword) and AuthenticationToken. This shall
>>> support
>>> token authentications while still maintaining username/password
>>> authentications (used in wicket and RO basic auth; since we still need to
>>> support both for prototyping and development).
>>> 8. Implement
>>> org.apache.isis.core.runtime.authentication.standard.Authenticator, and
>>> org.apache.isis.core.runtime.authorization.standard.Authorizer. We
>>> extended
>>> ShiroAuthenticatorOrAuthorizor to support token authentications.
>>> 9. Extend IsisModuleSecurityRealm to support getting authentication info
>>> for OAuth2 tokens. We had our own additions here since we need to support
>>> some forms of decoupled authentication vetos from other modules e.g. if
>>> tenant of the ApplicationUser is disabled then disallow login, password
>>> lockout policies, etc.
>>> 10.  Extend AuthorizationManagerStandardInstallerAbstract and create the
>>> new authorizer.
>>> 11. Create an AuthenticationSessionStrategy supported token
>>> authentication
>>> to be used in RO. Here, we parse the token from the HTTP header, create
>>> AuthenticationRequestToken, and pass to the Apache Isis
>>> AuthenticationManager.
>>>
>>> To use in your app:
>>>
>>> 12. In your AppManifest, return the installer class name created in #10
>>> for getAuthenticationMechanism and getAuthorizationMechanism.
>>> 13. In shiro.ini, set securityManager.realms to the security realm in #9
>>> 14. In web.xml, for the IsisSessionFilterForRestfulObjects, use the
>>> authentication session strategy created in 11 for the
>>> authenticationSessionStrategy init param. We also set whenNoSession to
>>> continue since we needed to provide different error messages on
>>> authentication failures by letting AuthenticationException propagate up
>>> to
>>> the authentication session strategy, and prettify the messages through
>>> another filter.
>>> 15. In web.xml, setup the Restlet servlet and the transaction filter in
>>> #5.
>>>
>>>
>>> I hope above makes sense. This was implemented a year ago and it's
>>> already
>>> a bit blurry to remember everything. I would advise to observe and study
>>> the authentication flow from viewer to the authentication realms, as well
>>> as the security addon. This helps in determining integration or
>>> customization points to adhere to your project's requirements.
>>>
>>> Best regards,
>>> Willie
>>>
>>> [1] https://issues.apache.org/jira/browse/SHIRO-119
>>>
>>> On Tue, Jun 28, 2016 at 5:35 AM, Dan Haywood <
>>> [email protected]
>>>
>>>> wrote:
>>>> Hi Pedro,
>>>> Apache Isis doesn't ship with oauth out of the box, but I recall Willie
>>>> mentioning in passing [1] that they had extended Isis in this direction.
>>>>
>>>> @Willie, would you be able to share any code around this?
>>>>
>>>> Thx
>>>> Dan
>>>>
>>>> http://markmail.org/message/ia76ut3mwuppdqow
>>>>
>>>> On 27 June 2016 at 15:18, Pedro Alba <[email protected]> wrote:
>>>>
>>>> Hello Dan.
>>>>>
>>>>> Dan, I have a question, I require implement OAuth authentication
>>>>> services to the rest exposing apache isis; how I can configure apache
>>>>> isis
>>>>> authentication OAUTH?
>>>>>
>>>>> Thanks.
>>>>>
>>>>> [image: Logo]
>>>>>
>>>>> *Pedro Antonio Alba *
>>>>> *Senior Development Analyst*
>>>>> Tel: (57) 1 703 17 77
>>>>> Cel: (57) 301 3379810
>>>>> E-mail: [email protected]
>>>>> Calle 93 # 19b - 66 Ofc 202
>>>>> Bogotá D.C., Colombia
>>>>> www.ticxar.com
>>>>>
>>>>>
>>>>>
>>>>>    [image: facebook]
>>>>> <http://www.facebook.com/pages/Ticxar/446503822192581> [image:
>>>>> twitter]
>>>>> <http://twitter.com/ticxar> [image: linkedIn]
>>>>> <http://www.linkedin.com/company/ticxar>
>>>>>
>>>>>
>>>>
>

Reply via email to