jeffwils / grails-spring-security-saml

Grails Spring Security SAML2.0 Plugin for Grails 3
8 stars 25 forks source link

Any chance getting this upgraded to work with Grails 5.1? #74

Open tucker-bluesage opened 2 years ago

tucker-bluesage commented 2 years ago

I've been doing an upgrade and found that one of my apps which uses optionally uses this plugin for security breaks with the following error:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'managementSecurityFilterChain' defined in class path resource [org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfiguration.class]: Unsatisfied dependency expressed through method 'managementSecurityFilterChain' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.security.config.annotation.web.builders.HttpSecurity' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:99)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:485)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:472)
        at grails.boot.GrailsApp$run.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:148)
        at lendingadmin2.Application.main(Application.groovy:13)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.security.config.annotation.web.builders.HttpSecurity' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1799)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1355)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1309)
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
        ... 29 common frames omitted

The same app will run just fine if I remove this plugin and a small amount of related code. Just taking a glance at it all the depdencies probably need to be updated in build.gradle, and I'm not sure what else that might cause in terms of updates.

Updated with the right stack trace. I've been chasing a couple of different errors in my upgrades.

jnunderwood commented 2 years ago

I am able to get the SAML plugin to work under all releases of Grails 5.1.x except v5.1.8. The latest release throws the following exception on startup:

Configuring Spring Security Core ...
... finished configuring Spring Security Core

Configuring Spring Security SAML ...
Importing beans from classpath:security/springSecuritySamlBeans.xml...
2022-06-02 15:47:51.263 [           @               ] ERROR --- org.springframework.boot.SpringApplication    : Application run failed

java.lang.NullPointerException: Cannot get property 'idpSelectionPath' on null object
        at org.codehaus.groovy.runtime.NullObject.getProperty(NullObject.java:60)
        at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:194)
        at org.codehaus.groovy.runtime.callsite.NullCallSite.getProperty(NullCallSite.java:46)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:329)
        at org.grails.plugin.springsecurity.saml.SpringSecuritySamlGrailsPlugin$_doWithSpring_closure1.doCall(SpringSecuritySamlGrailsPlugin.groovy:124)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:274)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1035)
        at groovy.lang.Closure.call(Closure.java:412)
        at groovy.lang.Closure.call(Closure.java:406)
        at grails.spring.BeanBuilder.invokeBeanDefiningClosure(BeanBuilder.java:759)
        at grails.spring.BeanBuilder.beans(BeanBuilder.java:588)
        at grails.spring.BeanBuilder.invokeMethod(BeanBuilder.java:531)
        at org.grails.plugins.DefaultGrailsPlugin.doWithRuntimeConfiguration(DefaultGrailsPlugin.java:543)
        at org.grails.plugins.AbstractGrailsPluginManager.doRuntimeConfiguration(AbstractGrailsPluginManager.java:166)
        at grails.boot.config.GrailsApplicationPostProcessor.postProcessBeanDefinitionRegistry(GrailsApplicationPostProcessor.groovy:171)
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311)
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:142)
        at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:99)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:485)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:472)
        at grails.boot.GrailsApp$run.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:148)
        at evc.Application.main(Application.groovy:14)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
        at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:59)
tucker-bluesage commented 2 years ago

@jnunderwood How did you get it working under 5.1.x? Did you at one point see the issue I had, and if you did how did you work around it?

jnunderwood commented 2 years ago

@tucker-bluesage I didn't have to do anything differently going from Grails v4.x to v5.1.x. I never had any issues at all until v5.1.8

valentingoebel commented 2 years ago

I have used the 4.0.4 version of this plugin on Grails 5.1.6 without any problems which is why I haven't bothered to update the plugin. When you consider that this plugin is a wrapper for the deprecated spring-security-saml extension that Spring offers it didn't make any sense to put in any effort and to instead redo the whole thing with Spring Security 5 which has SAML support via spring-security-saml-service-provider.

There is an experimental 5.0.x branch that contains a release candidate that you can build yourself and upload (./gradlew artifactoryPublish with the artifactory plugin) to a self hosted artifactory instance in the meantime. You can also test it locally by running ./gradlew publishToMavenLocal which apparently is supposed to be the replacement for grails install.

Now that Bintray is gone, the alternative, i.e. uploading to maven central appears to be a chore so I haven't published anything yet.

valentingoebel commented 2 years ago

I moved the repository to https://github.com/grails-spring-security-saml/grails-spring-security-saml because I needed to verify ownership of the reverse domain name for maven central on sonatype.

The latest version of the plugin is available on maven central via

implementation 'io.github.grails-spring-security-saml:spring-security-saml:5.0.0-RC2'
jnunderwood commented 2 years ago

I tried the new repo on a project using Grails 5.1.8, running inside a Linux Docker container via JDK 11, but I got this exception on start up:

groovy.lang.MissingMethodException: No signature of method: java.util.LinkedHashMap.getProperty() is applicable for argument types: (String) values: [cleanhandsdev]
Possible solutions: hasProperty(java.lang.String), getProperties()
        at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:70)
        at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:46)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139)
        at org.grails.plugin.springsecurity.saml.SpringSecuritySamlGrailsPlugin.registrationFromMetadata(SpringSecuritySamlGrailsPlugin.groovy:378)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:362)
        at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:61)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:171)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:212)
        at org.grails.plugin.springsecurity.saml.SpringSecuritySamlGrailsPlugin$_doWithSpring_closure1$_closure7.doCall(SpringSecuritySamlGrailsPlugin.groovy:143)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:274)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1035)
        at groovy.lang.Closure.call(Closure.java:412)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.callClosureForMapEntry(DefaultGroovyMethods.java:6083)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2436)
        at org.codehaus.groovy.runtime.dgm$203.invoke(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:247)
        at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139)
        at org.grails.plugin.springsecurity.saml.SpringSecuritySamlGrailsPlugin$_doWithSpring_closure1.doCall(SpringSecuritySamlGrailsPlugin.groovy:141)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:274)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1035)
        at groovy.lang.Closure.call(Closure.java:412)
        at groovy.lang.Closure.call(Closure.java:406)
        at grails.spring.BeanBuilder.invokeBeanDefiningClosure(BeanBuilder.java:759)
        at grails.spring.BeanBuilder.beans(BeanBuilder.java:588)
        at grails.spring.BeanBuilder.invokeMethod(BeanBuilder.java:531)
        at org.grails.plugins.DefaultGrailsPlugin.doWithRuntimeConfiguration(DefaultGrailsPlugin.java:543)
        at org.grails.plugins.AbstractGrailsPluginManager.doRuntimeConfiguration(AbstractGrailsPluginManager.java:166)
        at grails.boot.config.GrailsApplicationPostProcessor.postProcessBeanDefinitionRegistry(GrailsApplicationPostProcessor.groovy:171)
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311)
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:142)
        at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:99)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:485)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:472)
        at grails.boot.GrailsApp$run.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:148)
        at cleanhands.Application.main(Application.groovy:14)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
        at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:59)
valentingoebel commented 2 years ago

@jnunderwood

groovy.lang.MissingMethodException: No signature of method: java.util.LinkedHashMap.getProperty() is applicable for argument types: (String) values: [cleanhandsdev]

The plugin is looking for a password for the key 'cleanhandsdev' in your keystore. I had to abandon the KeyManager and it is now always asking for a password. The plugin doesn't complain much on the happy path but it apparently breaks in unexpected places.

You need

grails:
    plugin:
        springsecurity:
            saml:
                keyManager:
                    passwords:
                        cleanhandsdev: <password>

and if necessary, you need to add the password to the keystore entry too. Use e.g. Keystore explorer to add the password.

jnunderwood commented 1 year ago

@valentingoebel I had already included a password in the SAML section as well as added a password to the keystore. Here is my SAML config:

grails:
    plugin:
        springsecurity:
            providerNames: [ 'samlAuthenticationProvider', 'anonymousAuthenticationProvider' ]
            saml:
                active: true
                afterLoginUrl: '/'
                afterLogoutUrl: '/'
                responseSkew: 300
                signatureAlgorithm: 'rsa-sha256'
                digestAlgorithm: 'sha256'
                userGroupAttribute: 'memberOf'
                autoCreate:
                    active: true
                    key: 'username'
                    assignAuthorities: false
                metadata:
                    defaultIdp: 'IDP_SERVER.saml2'
                    url: '/saml/metadata'
                    providers:
                        ping: 'security/MYAPP.idp.xml'
                    sp:
                        file: 'security/MYAPP.sp.xml'
                        defaults:
                            local: true
                            entityId: 'MYAPP'
                            alias: 'MYAPP'
                            securityProfile: 'metaiop'
                            signingKey: 'MYAPP'
                            encryptionKey: 'MYAPP'
                            tlsKey: 'MYAPP'
                            requireArtifactResolveSigned: false
                            requireLogoutRequestSigned: false
                            requireLogoutResponseSigned: false
                keyManager:
                    storeFile: 'classpath:security/MYAPP.jks'
                    storePass: 'MY_PASSWORD'
                    passwords:
                        'MYAPP': 'MY_PASSWORD'
                    defaultKey: ''

This hasn't changed since moving from Grails 5.1.7 to 5.1.8. Any insight you have would be greatly appreciated. Thanks.

valentingoebel commented 1 year ago

@jnunderwood I have released a new version:

    implementation 'io.github.grails-spring-security-saml:spring-security-saml:5.0.0-RC3'

This version contains warning and error messages for common configuration errors.

There is a catch though, metadata.url has must now contain {registrationId} to identify the registrations. You can leave it out, then it is the same as the Spring Security defaults:

https://docs.spring.io/spring-security/site/docs/5.2.1.RELEASE/reference/htmlsingle/#saml2 https://docs.spring.io/spring-security/reference/servlet/saml2/metadata.html

jnunderwood commented 1 year ago

Thank you for the new release. I have upgraded to SAML plugin v5.0.0-RC3, while remaining on Grails v5.1.7, and changed my saml.metadata.url to: /saml/metadata/{registrationId}. However, when I visit the web app, I am presented with the standard authentication page (from Spring Security?) at this URL: /login/auth. Based on the logs, it looks like SAML is configured but is not being invoked. I have turned on SAML logging, but there are no SAML-related messages (other than the configuration statement) and there are no exceptions.

valentingoebel commented 1 year ago

There are two options: You can use the taglib of the plugin:

<sec:loginLink class="nav-link"><g:message code="index.login.label"/></sec:loginLink>
<sec:logoutLink class="nav-link"><g:message code="index.logout.label"/></sec:logoutLink>

or you can just go to the path /saml2/authenticate/{registrationId}

For logout you can optionally to check if the current authentication is using SAML:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication instanceof Saml2Authentication) {
    url = "/logout/saml2"
}

then you can go to /logout/saml2

jnunderwood commented 1 year ago

Hmmm. I'm going directly to the path you suggested and it still takes me back to the standard /login/auth authentication page. The logs do not indicate that the SAML plugin is being invoked. I'm using the same config that worked in the previous version of the plugin, except that I updated the saml.metadata.url to include /{registrationId}.

valentingoebel commented 1 year ago

I can't pinpoint the problem. Try setting /saml2/** to permitAll` to get access to that path.

/login/auth is configured by loginFormUrl. You may need this:

grails:
    plugin:
        springsecurity:
            auth:
                loginFormUrl: '/saml2/authenticate/<insert_registrationId>'
jnunderwood commented 1 year ago

@valentingoebel I finally got everything to work. Reading the index.md file in https://github.com/grails-spring-security-saml/grails-spring-security-saml helped as well as all of your comments here. Thank you so much for you assistance. Much appreciated!