Ignore WebSocket connection in Spring Security SavedRequest - grails

I have a Grails application with spring-security-core plugin and Atmosphere framework.
If I log out from a page that has opened a WebSocket connection, then Spring Security keeps the URL of the WebSocket connection as SavedRequest.
DEBUG savedrequest.HttpSessionRequestCache - DefaultSavedRequest added to Session: DefaultSavedRequest[http://localhost:8080/formx/formX/update]
DEBUG savedrequest.HttpSessionRequestCache - DefaultSavedRequest added to Session: DefaultSavedRequest[http://localhost:8080/formx/formX/notifications/?X-Atmosphere-Transport=close&X-Atmosphere-tracking-id=b5d8fde4-d950-41fd-9b49-02e06799a36f&conversationId=988080042]
The first entry in the log has the correct value for SavedRequest, but somehow it is overwritten by the Atmosphere WebSocket connection.
How do I tell Spring Security to not use the Atmosphere WebSocket connection as SavedRequest?
I guess I can use some Atmosphere Protocol Specific Header to distinguish connections.

In Java config you can set the RequestMatcher - then it's easy.
In WebSecurityConfigurerAdapter:
protected void configure(HttpSecurity http) {
HttpSessionRequestCache cache = new HttpSessionRequestCache(); //this one is used by default
cache.setRequestMatcher(AnyRequestMatcher.INSTANCE); //change the request matcher, so it do not match your Atmosphere requests
http.requestCache().requestCache(cache);
}

Related

Spring Authorization Server and Spring Resource Server in one server

Has anyone tried using both the newly release Spring Authorization Server 0.1.0 and the regular Spring Resource Server in 1 project and in 1 server such as:
The resource server is at http://localhost:8080 and the authorization server is also at http://localhost:8080? Any ideas on how to do it?
The problem is that at start up, the resource server checks the authorization server's /.well-known/openid-configuration which is obviously not yet avaialble.
Instead of issuer-uri, you can instead specify the jwk-set-uri, which isn't pinged at startup.
Or, since the authorization server and resource server will use the memory space for keys, you might construct your own Nimbus JWTProcessor instead so that you skip the internal HTTP request:
#Bean
JwtDecoder jwtDecoder() {
JWKSource<SecurityContext> source = // ... some internal store for the public keys, e.g. not RemoteJWKSet
ConfigurableJWTProcessor<SecurityContext> processor = new DefaultJWTProcessor<>();
JWSKeySelector<SecurityContext> selector = new JWSVerificationKeySelector(
JWSAlgorithm.RS256, source);
processor.setJWSKeySelector(selector);
NimbusJwtDecoder decoder = new NimbusJwtDecoder(processor);
decoder.setJwtValidator(... add any validation rules ...);
return decoder;
}
I believe you can just set your jwtDecoder as follows:
#Bean
JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
}
As you probably already have that defined as a Bean elsewhere when setting up your auth server
#Bean
public JWKSource<SecurityContext> jwkSource() {
// implementation ...
}

Spring security 5 and OAuth2 - Success Handler not being invoked and after login it is going into infinite loop

I am trying to migrate spring security to latest version (spring security 5.2.2 and Cloud OAuth2). As #EnableOAuth2Client is in maintenance mode now, I am trying to use http.oauth2Login() with customization for success handler. Following is my security class -
#Configuration
public class OAuth2SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2Login().successHandler(new SimpleUrlAuthenticationSuccessHandler("<url to redirect>"));
}
}
I have registered client with name as 'custom'. Following is the flow in the browser -
http://localhost:9000/oauth2/authorization/custom -> IDP's login page and successful login -> Get Authorization code on URL http://localhost:9000/login/oauth2/code/custom -> it again goes to http://localhost:9000/oauth2/authorization/custom and infinite loop. Successhandler is not invoked. Also, I don't see access token generation in logs.
I have tried many things in last two days like tweaking security config etc but nothing works.
Any help is appreciated.
The problem was with user info endpoint. My IDP has not exposed user info endpoint while it is mandatory in spring oauth2 where the request was failing. I needed to override the default OAuth2UserService implementation to resolve the issue.

Spring MVC Test MockMvc - how do I configure a url mapping prefix

I have a DispatcherServlet that has a URL mapping /api1 and subsequentially a Controller with a mapping #GetMapping("/resource1") for a controller method. So basically I have a valid URL /api1/resource1 that should be handled by the mentioned controller.
Also, the setup incorporates a Spring Security Filter that matches requests /* as it secures other URLs not handled by Spring (but Jersey for example).
The API secured by the Spring Security Filter is setup like
protected void configure(HttpSecurity http) throws Exception {
//#formatter:off
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.requestMatchers()
.antMatchers("/api1/**")
.and()
.authorizeRequests()
.antMatchers("/**")
.authenticated()
For testing I use the MockMvc* support to setup a mocked web environment including a Spring security setup
mvc = MockMvcBuilders
.webAppContextSetup(context)
.apply(springSecurity())
.build()
I want to test that security checks are applied and the controller method is called on successful security checks.
when:
def result = mvc.perform(
get('/api1/resource1')
.header(HttpHeaders.AUTHORIZATION, "Bearer " + apiToken))
then:
result.andExpect(status().isOk())
The code above is based on the Spock framework with the MockMvc stuff.
All of the security checks are passing so the Spring security setup is complete, but finally the controller should be invoked but fails with a 404 status i.e the resource - this is the mapped controller method - is not found.
I'm confident that it fails because the mocked setup does not incorporate a the /api dispatcher servlet mapping. To proof that assumption I can modify the controller method mapping to #GetMapping("/api1/resource1") and the test will result in a HTTP OK (200).
So, my question is, is it possible to configure a kind of URL prefix in the MockMvc setup?
There is one constraint, the code base is not using Spring Boot (and can't for a while in future)!
Edit:
I added the following to my test to have all requests set the servletPath.
static MockHttpServletRequestBuilder get(String urlTemplate, Object... uriVars) {
new MockHttpServletRequestBuilder(HttpMethod.GET, urlTemplate, uriVars)
.servletPath('/api1')
}
I think you just need to configure the contextPath for the request.
See org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder.contextPath(String) for details.

Spring Boot - Spring Security - Multiple configurations

I try desperately to configure Spring Security in a Spring Boot application this way :
One way with custom token for all services called by the application
One way with HTTP Basic only for REST API services that will be used by another application
The combination of the two ways causes problems...
I tried multiples solutions without any success. I read this section : http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#multiple-httpsecurity
My code looks like this :
#Override
protected void configure(HttpSecurity http) throws Exception {
// Function called by application
http.authorizeRequests(). antMatchers(HttpMethod.GET, "MyFunction").hasAnyRole("USER");
http.addFilterBefore(xAuthTokenFilter, UsernamePasswordAuthenticationFilter.class);
// Function API REST
http.antMatcher("/api/**").authorizeRequests().anyRequest().authenticated().and().httpBasic();
// Requests blocked by default
http.authorizeRequests().anyRequest().denyAll();
}
Adding httpbasic() causes "Security filter chain: no match" for my first function.
Do you have any idea of the right syntax... ?
Thanks in advance.

why Spring Security Exception Translation Filter creates 403 Response Code for default configuration

I am pretty new to Spring Security land. I am using programmatic configuration of Spring Security with servletApi() which is pretty neat.
Here is the configuration:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.securityContext().and()
.servletApi().and()
.authorizeUrls()
.antMatchers("/login").permitAll()
.antMatchers("/").permitAll()
.antMatchers("/**").authenticated();
}
I am using http servlet api login I am not using any filter for this.
In case a unauthorised request, ExceptionTranslationFilter uses Http403EntryForbiddenEntryPoint to return 403 forbidden status.
In my scenario:
If user does not authenticated, a 401 status code should return.
If user authenticated but not authorised, a 403 status code should return.
But default configuration creates 403 status for both case.
Here are my questions:
Why is the default entry point is Http403EntryForbiddenEntryPoint? It can be 401?
If I change Http403EntryForbiddenEntryPoint to Http401EntryForbiddenEntryPoint, does It create a problem?
Thanks

Resources