Null authentication when error handling 403 - grails

I'm running now Grails 3.1.15 with org.grails.plugins:spring-security-core:3.1.1.
When I return a status code 403 my ErrorController should generate an appropriate error page (this is mapped in UrlMappings). It requires a springSecurityService.currentUser to generate that error page.
Turns out that I get NPE in that process since springSecurityService.currentUser is null as well as the authentication object.
This was working fine in Grails2 and the v2 of spring-security-plugin.
I've encountered this question: Spring SecurityContext returning null authentication on error pages and the suggestion there is that the ExceptionTranslationFilter has to be in place.
In Grails2 it is indeed in place but in Grails3 it was replaced/extended with UpdateRequestContextHolderExceptionTranslationFilter - it's still in the filter chain.
What can I do to prevent that from happening (getting a null authentication) when error handling a 403
Remarks:
the whole situations happens only in production env when deployed in Tomcat - not reproducible in dev mode

Have you tried setting this in application.yml? This has helped me in both Grails 2 and Grails 3.
grails:
plugin:
springsecurity:
adh:
errorPage: null

Related

Configure the landing page after SSO authentication

I want to know how to setup the relay state with the new saml library. Basically once I am authenticated via the asserting party, I want to have a relay state url (a JSP in my application), where I should land. In the saml extensions library, as far as I know, the relay state url was set in the SAMLMessageContext object.
Actual Behaviour The mechanism of setting the page where I would be redirected to after SAML login has changed. I am not sure how to set the desired JSP where I want to land in the new library.
Expected behavior After the successful call to the assertionConsumerServiceLocation in my application, I should be taken to a Url configured by me (Relaystate). I need help in configuring this URL.
I tried to set up the relay state like this :-
Saml2AuthenticationRequestResolver authenticationRequestResolver(
RelyingPartyRegistrationResolver registrations) {
OpenSaml4AuthenticationRequestResolver authenticationRequests =
new OpenSaml4AuthenticationRequestResolver(registrations);
authenticationRequests.setRelayStateResolver(relayStateResolver);
return authenticationRequests;
}
I have defined the relayStateResolver like the following :-
private Converter<HttpServletRequest, String> relayStateResolver = (request) -> "my_desired_jsp_url_string";
Are my above configurations correct, and would they help me in landing on the desired JSP page after successful login?
Currently, below is the error I am facing with the above implementation. I am working to fix that (I need to get the Opensaml4 from Shibboleth's repository of artifacts), but wanted to know if the above configuration is correct before making that fixing effort.
Jan 03, 2023 5:54:28 AM org.apache.catalina.core.StandardWrapperValve
invoke SEVERE: Servlet.service() for servlet [dispatcher] in context
with path [/company] threw exception [Filter execution threw an
exception] with root cause java.lang.NoSuchMethodError:
org.opensaml.saml.saml2.core.AuthnRequest.setIssueInstant(Ljava/time/Instant;)V
at
org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver.lambda$resolve$1(OpenSaml4AuthenticationRequestResolver.java:60)
at
org.springframework.security.saml2.provider.service.web.authentication.OpenSamlAuthenticationRequestResolver.resolve(OpenSamlAuthenticationRequestResolver.java:133)
at
org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver.resolve(OpenSaml4AuthenticationRequestResolver.java:59)
at
org.springframework.security.saml2.provider.service.web.Saml2WebSsoAuthenticationRequestFilter.doFilterInternal(Saml2WebSsoAuthenticationRequestFilter.java:184)
at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
Because RelayState can be used for several things and is not always used to describe the post-login redirect URL (the spec says MAY), it is not defaulted to do this.
You can configure Spring Security to redirect to the RelayState parameter by configuring a SimpleUrlAuthenticationSuccessHandler like so:
#Bean
public SecurityFilterChain appEndpoints(HttpSecurity http) {
SimpleUrlAuthenticationSuccessHandler successHandler =
new SimpleUrlAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter(Saml2ParameterNames.RELAY_STATE);
http
.saml2Login((saml2) -> saml2
.authenticationSuccessHandler(successHandler)
// ...
)
// ...
return http.build();
}
You will also need to configure the relay state resolver, as you have already shown in your post.

Spring Security OAuth2 configuring failureUrl makes the url inaccessible

I have a spring security based boot application for which I have configured an endpoint names /test for which I return a test.html page
#RequestMapping("/test")
public String test() {
return "test.html";
}
The endpoint works fine by itself, however if I set it as an OAuth2 failureUrl it becomes unavailable...
http.csrf().disable()
.httpBasic().disable()
.formLogin().disable()
.authorizeRequests()
.antMatchers("/test").permitAll()
.anyRequest().authenticated()
.and()
.oauth2Login()
.failureUrl("/test");
Is this expected behavior? When I do this, spring security properly redirects to /test on authentication failure but /test is inaccessible and it ends up showing a generated page.
The behaviour of failureUrl differs based on whether or not a custom loginPage is configured.
Since you have not customized loginPage, the framework will intercept the failure URL ("/test") and generate the default error page, which is simply the default login page with an error message.
That is why you see the generated login page with accessing "/test".
Your Controller mapping for "/test" is ignored.
To tell the framework not to generate the error page, you can configure the failureHandler instead.
http
.oauth2Login((oauth2Login) -> oauth2Login
.failureHandler(new SimpleUrlAuthenticationFailureHandler("/test"))
);
Note: This may be confusing because the Javadoc for failureUrl does not describe its behaviour properly. I have created a GitHub issue in the Spring Security backlog to fix this.

jasig cas too many redirects issue

I'm trying to secure a spring-boot web application using spring security and spring-security-cas (SSO with Jasig CAS).
I'm facing a too many redirects error when trying to access a protected resources. The project is available here
Do you see any error in my configuration?
Thanks in advance
redirect loop error screenshot
Finally found out the error:
In SpringSecurity 4.x, CasAuthenticationFilter's defaultFilterProcessesUrl path is changed. So Change '/j_spring_cas_security_check' to '/login/cas' in Configuration.
So in my application.properties file, i had to change
app.service.security=http://localhost:7777/j_spring_cas_security_check
to
app.service.security=http://localhost:7777/login/cas
So the ServiceProperties Bean would become
#Bean
public ServiceProperties serviceProperties() {
ServiceProperties serviceProperties = new ServiceProperties();
serviceProperties.setService("http://localhost:7777/login/cas");
serviceProperties.setSendRenew(false);
return serviceProperties;
}
Hope it'll help someone else!

Error in Zuul SendErrorFilter during forward

When my Zuul Filter is unable to route to a configured URL, the 'RibbonRoutingFilter' class throws a ZuulException saying "Forwarding error" and the control goes to the 'SendErrorFilter' class.
Now when the SendErrorFilter class tries to do a forward, another exception happens during this forward call.
dispatcher.forward(ctx.getRequest(), ctx.getResponse());
The exception happening during this forward call is
Caused by: java.lang.IllegalArgumentException: UT010023: Request org.springframework.cloud.netflix.zuul.filters.pre.Servlet30WrapperFilter$Servlet30RequestWrapper#6dc974ea was not original or a wrapper
at io.undertow.servlet.spec.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:103) ~[undertow-servlet-1.1.3.Final.jar:1.1.3.Final]
at org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter.run(SendErrorFilter.java:74) ~[spring-cloud-netflix-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
at com.netflix.zuul.ZuulFilter.runFilter(ZuulFilter.java:112) ~[zuul-core-1.0.28.jar:na]
at com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:197) ~[zuul-core-1.0.28.jar:na]
Finally when the control comes to my custom ZuulErrorFilter , i do not get the original exception. Instead the exception object i get is the one that occurs during the forward.
Update:
I found that a errorPath property can be configured to point to a Error Handling Service. If it is not configured, Zuul by default looks for a service named /error and tries to dispatch to that service. Since we did not have any service for /error , the dispatcher.forward() was throwing error.
Question
How can we skip this fwd to an error handling service ? We have a ErrorFilter to log the error. We do not want to have a error handling service.
We had faced the same issue and there is a simple solution to fix the Undertow "eating" the original exception, following my blog post:
http://blog.jmnarloch.io/2015/09/16/spring-cloud-zuul-error-handling/
You need to set the flag allow-non-standard-wrappers to true. In Spring Boot this is doable through registering custom UndertowDeploymentInfoCustomizer. Example:
#Bean
public UndertowEmbeddedServletContainerFactory embeddedServletContainerFactory() {
UndertowEmbeddedServletContainerFactory factory = new UndertowEmbeddedServletContainerFactory();
factory.addDeploymentInfoCustomizers(new UndertowDeploymentInfoCustomizer() {
#Override
public void customize(DeploymentInfo deploymentInfo) {
deploymentInfo.setAllowNonStandardWrappers(true);
}
});
return factory;
}
Now regarding the question, either way I would highly encourage you to implement your own ErrorController, because otherwise you may experience odd Spring Boot behaviour (in our setup - ralying on the default was always generating the Whitelabel error page with 200 HTTP status code - which never happens on Tomcat in contradiction) and in this way was not consumable by AJAX calls for instance.
Related Github issue: https://github.com/spring-cloud/spring-cloud-netflix/issues/524

Grails redirect redirects to invalid location

I'm running my app in development environment.
Using this simple controller:
class MyController {
def index() {
redirect uri: '/'
}
}
I'm getting redirected to http://localhost:8080/[:]/ location for some reason.
$appName seems good inside Config.groovy. grails.serverURL looks also OK.
What's the problem?
UPDATE 1
I'm using grails 2.2.4
UPDATE 2
The problem is with invalid grails.serverURL value. When I'm debugging the app, it has a correct value inside Config.groovy. When I'm printing out this value from servlet method it's set to http://localhost:8080/[:]/ for some reason. I'm using Spring Security Core 1.2.7.3 and Spring Security UI 0.2, I think that for some reason grails.serverURL is overwritted inside this plugin.
How to fix it?
The answer was simple. I've included MyConfig.groovy inside Config.groovy like this:
grails.config.locations = [ "classpath:${appName}-config.properties",
"classpath:${appName}-config.groovy",
MyConfig,
"file:${userHome}/.grails/${appName}-config.properties",
"file:${userHome}/.grails/${appName}-config.groovy"]
there was also environments.production, environments.development and environments.test sections however, $appName is undefined there. I've removed setting of grails.serverURL from MyConfig.groovy and its worked now.

Resources