Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
tucker-bluesage opened this issue Jun 3, 2022 · 14 comments
Open

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

tucker-bluesage opened this issue Jun 3, 2022 · 14 comments

Comments

@tucker-bluesage
Copy link

tucker-bluesage commented Jun 3, 2022

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
Copy link

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
Copy link
Author

@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
Copy link

@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
Copy link
Collaborator

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
Copy link
Collaborator

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
Copy link

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
Copy link
Collaborator

@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
Copy link

@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
Copy link
Collaborator

@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
Copy link

jnunderwood commented Jul 17, 2022

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
Copy link
Collaborator

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
Copy link

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
Copy link
Collaborator

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
Copy link

@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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants