Maybe Misagh could put in his thoughts on this, but I would argue the 
opposite is more true in fact, having custom java code and having to 
register, etc.. rely's on way MORE base code in cas then the groovy 
methods. If you take a look at the way groovy scripts are written in cas it 
is mainly a simple execute groovy method passing the parameters and just 
reading the results. That code itself doesn't change much, we had thousands 
of lines of custom java code before the 6.x days, for all kinds of things. 
Now we maintain 2 individual java class files and working to get those 
changes pushed into cas, just need to write the test cases and scenarios.

One of the benefits to using groovy is the no compile time, they don't need 
to be compiled with your overlay! most if not all groovy scripts are 
reloaded on demand, when changed and take affect immediately with no 
restarts which makes a huge difference.

Not sure why the other posters simple-mfa wouldnt work but works no problem 
for us, it could be the trigger type being used, there is the 
cas.authn.mfa.core.provider-selector-groovy-script 
and what we use,  cas.authn.mfa.groovy-script and we have some 
vendors/external services that use database auth and mfa is fine, we also 
use surrogate and in our groovy we have parts written to either 
bypass/force for surrogate situations.

We have been using CAS since the 3.x days and when groovy webflow came 
along, it was a blessing!! It is soooo much easier to maintain then custom 
java code. See the attached, this is one of about 4 different flow 
modifiers, using the "properties" in a service definition, we utilize this 
flow to inject custom post fields for services that require a POST response 
instead of REDIRECT.

I think, in my opinion, groovy is way more sustainable to maintain then the 
other.

Thanks,
John

On Tuesday, July 25, 2023 at 7:18:07 AM UTC-5 spfma...@e.mail.fr wrote:

> Hi,
> Thanks for your reply.
> From what I have read in the recommendations in the docs, scripting is ok 
> but coding is better and more sustainable (build time vs run time I guess).
> So I am trying to understand how to implement something like what is 
> described here : 
> https://apereo.github.io/cas/6.6.x/mfa/Configuring-Multifactor-Authentication-Triggers-Custom.html
> But so far I don't even know where to put the code, how to even have a 
> single debug log line.
> Thanks for this example (I think I saw it a couple of monthes ago),if will 
> follow this way if it's the right one too.
> But I can't forget I have to replicate an old "login-webflow.xml", which 
> seems to be done programmatically only in current version.
> Regards
>
>
> Le 21-Jul-2023 20:00:53 +0200, rb...@uvic.ca a écrit:
>
> This may provide some direction 
> https://fawnoos.com/2018/11/22/cas5-groovy-mfa/
> There may be other posts on this site that can help.
>  
> Ray
>  
> On Fri, 2023-07-21 at 08:49 +0200, spfma.tech via CAS Community wrote:
>
> Notice: This message was sent from outside the University of Victoria 
> email system. Please be cautious with links and sensitive information.
>  
> Hi,
> I would like to implement some conditional MFA scenarios (using a 
> different provider depending on the network is the first one), but reading
> https://apereo.github.io/cas/6.6.x/mfa/Configuring-Multifactor-Authentication-Triggers-Custom.html
>  
> does not provide a lot of help.
> Is there some code snippet available somewhere I could use as an example ?
> Regards
>
> ------------------------------
> FreeMail powered by mail.fr 
>
>  
>
>  
>  
>
>
> ------------------------------
> FreeMail powered by mail.fr 

-- 
- Website: https://apereo.github.io/cas
- Gitter Chatroom: https://gitter.im/apereo/cas
- List Guidelines: https://goo.gl/1VRrw7
- Contributions: https://goo.gl/mh7qDG
--- 
You received this message because you are subscribed to the Google Groups "CAS 
Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to cas-user+unsubscr...@apereo.org.
To view this discussion on the web visit 
https://groups.google.com/a/apereo.org/d/msgid/cas-user/fd892674-8cea-4f49-a814-568482278b47n%40apereo.org.
    if (webflow.containsFlowState(loginFlow, 
CasWebflowConstants.STATE_ID_GENERATE_SERVICE_TICKET)) {
        logger.debug("Webflow: Found state that modifys the 
generateServiceTicketAction");

        def state = webflow.getState(loginFlow, 
CasWebflowConstants.STATE_ID_GENERATE_SERVICE_TICKET, ActionState.class)
        logger.debug("Webflow: State id is {}", state.id);

        state.getExitActionList().add({ requestContext ->
            def flowScope = requestContext.flowScope
            def httpRequest = 
WebUtils.getHttpServletRequestFromExternalWebflowContext(requestContext);
            def requestScope = requestContext.getRequestScope();
            def authentication = WebUtils.getAuthentication(requestContext) as 
Authentication;
            def principal = authentication.getPrincipal() as Principal;
            def service = WebUtils.getRegisteredService(requestContext);
            def serviceClass = service.class.getSimpleName().toLowerCase();
            
            if (serviceClass == "casregisteredservice") {
                def serviceProperties = service.properties;
                def serviceType = 
(StringUtils.isNotBlank(service.getResponseType())) ? 
service.getResponseType().toLowerCase() : "redirect";
                def serviceTicket = 
WebUtils.getServiceTicketFromRequestScope(requestContext);
                def servicePolicy = service.getAttributeReleasePolicy();
                def addCreds = 
servicePolicy.isAuthorizedToReleaseCredentialPassword();
                def userAttr = principal.getAttributes();
                def userProvider = service.getUsernameAttributeProvider();
                def uid = (userProvider.hasProperty("usernameAttribute")) ? 
userAttr.get(userProvider.usernameAttribute)[0] : principal.id;
            
               if (serviceType == "post") {
                    
                    logger.debug("Webflow: Response type POST is marked for 
inclusion");
                    logger.debug("Webflow: Checking for custom post fields");
                    
                    if (serviceProperties.containsKey("postFields")) {
                        if (serviceProperties.postFields.value) {
                            addFields = serviceProperties.postFields.value;
                            
                            logger.debug("Webflow: Custom post fields are 
defined, adding to scope {}", addFields);
                            
                            addFields.splitEachLine(",") {
                                it.each{ x ->
                                    def object = x.split("=")
                                    def fieldsObj = [:]
                                    fieldsObj.put(object[0], object[1])
                                    logger.debug("Webflow: Adding extra field 
{} with value {}", object[0], object[1]);
                                    requestScope.put("custom_fields", 
fieldsObj);
                                }
                            }
                            logger.debug("Webflow: Done adding custom post 
fields");
                        }
                    } else {
                        logger.debug("Webflow: Custom post fields are not 
defined so we will not add any");
                    }
                    
                    logger.debug("Webflow: Checking for custom post url");
                    if (serviceProperties.containsKey("postUrl")) {
                        if (serviceProperties.postUrl.value) {
                            paramAdd = "?";
                            post_url = serviceProperties.postUrl.value;
                            if (post_url.contains('?')) {
                                paramAdd = "&";
                            }
                            requestScope.put("custom_postUrl", post_url + 
paramAdd + "ticket=" + serviceTicket);
                            
                            logger.debug("Webflow: Custom post url is defined 
{}", post_url);
                        }
                    } else {
                        logger.debug("Webflow: Custom post url not defined so 
we will not add one");
                    }
                } else {
                    logger.debug("Webflow: Response type {} is excluded", 
serviceType);
                }
            }
            return null;
        })
    }

Reply via email to