I have configured my resource server with below http configuration. Basically I want to set configuration like permit few requests without authentication and all other request which I have not specified should be allowed only if the user has valid access token.
Note that I am using spring security oauth2 and spring boot.
#Override
public void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling()
.and()
.csrf()
.requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize"))
.disable()
.headers()
.frameOptions().disable().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.antMatcher("**")
.authorizeRequests()
.antMatchers("/hello/")
.permitAll()
.anyRequest()
.authenticated();
}
When I try to access http://localhost:8889/hello, It gives me below 401 UnAuthorized response even though I have configured it with permitAll
{
"error": "unauthorized",
"error_description": "An Authentication object was not found in the SecurityContext"
}
On the contrary I checked with below configuration
.authorizeRequests()
.antMatchers("/hello/").permitAll()
.antMatchers("/hello2/").permitAll()
.antMatchers("/secure/**").authenticated()
.antMatchers("/secure2/**").authenticated();
It worked well like hello an hello2 are allowed without token and, secure and secure2 gives error response if token is not passed or invalid token is passed.
Can someone please tell me what I am missing?
Related
I set up Auth0 with my Spring project to add authentication/authorization. It works well, but when I call the "/user/login" endpoint, I get a 403 error when it should allow all requests.
This is my custom configuration:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
.antMatchers(HttpMethod.POST, LOGIN_URL).permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthorizationFilter(authenticationManager()))
// this disables session creation on Spring Security
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
It works perfectly fine for the sign-up url.
What could be causing this issue?
I am building a rest application using Spring boot and Spring security. In the login module I want my code to read username and password, sent from a client, from Post body. But my code reads only from the url, like Get request.
I tried to make a request from the Postman. Set the method as Post. When i set the username and password in the request param field. I get the "200 ok", but when I send the parameters as json in Post request, I get 401 unauthorized. What configuration changes do I need to make?
my Spring security config:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.
authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/registration").permitAll()
.antMatchers("/admin/**").hasAuthority("Admin")
.antMatchers("/db").hasAuthority("DBA")
.antMatchers("/user").hasAuthority("USER").anyRequest()
.authenticated().and().csrf().disable().formLogin()
.loginPage("/login")
.failureHandler(customFailureHandler)
.successHandler(customSuccessHandler)
.usernameParameter("username")
.passwordParameter("password")
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/").and().exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
.accessDeniedPage("/access-denied");
}
I have a Spring boot web app that serves up both web content and exposes REST Services. The web content is protected by SiteMinder, the REST Services are protected by "Basic Auth".
I using Springs security 4.2.3. My Java code is extending the class WebSecurityConfigurerAdapter, my configure(HttpSecurity) method looks like:
#Override
protected void configure(HttpSecurity http) throws Exception {
RequestHeaderAuthenticationFilter siteMinderFilter = new RequestHeaderAuthenticationFilter();
siteMinderFilter.setAuthenticationManager(authenticationManager());
http
// Error page is for everyone
.authorizeRequests()
.antMatchers("/error.html")
.permitAll()
.anyRequest()
.anonymous()
// Basic Auth for our REST services
.and()
.authorizeRequests()
.antMatchers("/services/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint)
// Site-Minder protection for the web content
.and()
.addFilter(siteMinderFilter)
.authorizeRequests()
.antMatchers("/**").permitAll()
.anyRequest().hasRole(ApplicationConstants.SITE_MINDER_AUTHORITY);
http.addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class);
}
Is there something wrong with my configuration? Does my configuration create three separate filters? Maybe my question should be, how do I create the three filters?
When I attempt to call the REST Service using PostMan / "Basic Auth", I get the error message:
org.springframework.security.web.authentication.preauth.PreAuthenticatedCredentialsNotFoundException: SM_USER header not found in request.
I expect the service to get called, instead I get the SiteMinder filter firing.
I'm using Spring Boot and Thymeleaf. I have a custom 404 template page defined in src/main/resources/templates/error/404.html
This works properly when users are logged in.
However, when they are logged out, they do not get any type of 404 page, they just get redirected back to /login.
I'm thinking my security configuration needs to change but not sure what.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/","/register*","/resetPassword","/forgotPassword","/login","/404").permitAll()
.antMatchers("/admin/**").hasAuthority("ADMIN").anyRequest()
.authenticated().and().formLogin().loginPage("/login").failureUrl("/login?error")
.defaultSuccessUrl("/dashboard").successHandler(successHandler)
.usernameParameter("email").passwordParameter("password")
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login?logout").and()
.exceptionHandling().accessDeniedPage("/access-denied");
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/error**","/resources/**", "/static/**", "/css/**", "/js/**", "/img/**");
}
First of all I encourage you to use indentation when using java config to configure your security for your spring application. It helps with readability.
Note all top level methods on the first indentation (authRequest,formLogin,logout) all configure/update the HTTP object it self. All these elements are from the org.springframework.security.config.annotation.web.builders.HttpSecurity class.
The children of these classes further refine the HTTP security configuration.
http
.authorizeRequests()
.antMatchers("/","/register*","/resetPassword","/forgotPassword","/login","/404")
.permitAll()
.antMatchers("/admin/**").hasAuthority("ADMIN")
.anyRequest().authenticated() // <--------
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error")
.defaultSuccessUrl("/dashboard")
.usernameParameter("email").passwordParameter("password")
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout")
.and()
.exceptionHandling()
.accessDeniedPage("/access-denied");
Note .anyRequest().authenticated() is specifically stating that any request must be authenticated. So when you attempt to goto any missing url on your domain it will ask you to login rather than goto the 404 page.
So if you remove that statement it and then try an goto a missing url page it will redirect you to a 404 page.
If you remove .anyRequest().Authenticated() then you can log in without authenticated.
Therefore, do not try to delete. For example, if you go to the address "http://localhost:8080/user", then you will be taken to the authorization page. And if you try to enter the page "http://localhost:8080/user/" then you will be taken to the user page. Please note that links differ only by the forward slash at the end. Of course if you remove ".anyRequest().Authenticated()" in this case you need to add more parameters to antMatchers like "/user" and "/user/"
Therefore, be careful and attentive.
I followed the guide here: http://spring.io/guides/gs/rest-service/ to build my rest service example and now I am trying to enable the CSRF protection. I read that it should be enabled by default, so if I DON'T include:
http.csrf().disable()
in my WebSecurityConfigurerAdapter configuration, the CSRF protectection should be enabled by default, but it does not seem to to be the case. The problem is that the X-CSRF-TOKEN is not generated and not included in my HTTP response in any way.
What am I expected to do, to have the x-csrf-token generated and included in the response and, of course, the csrf protection fully working?
I noticed that, with a similar spring mvc configuration, I get the x-csrf-token generated simply including:
< security:csrf disabled="false"/>
in my security configuration file. But, with spring boot maybe I am getting something wrong and there is no way to have the csrf token generated. Can anybody help me, perhaps pointing me to a working example? My security configuration is:
#Override
protected void configure(HttpSecurity http) throws Exception
{
http
// .csrf().disable()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(new RestAuthenticationEntryPoint())
.and()
.formLogin()
.successHandler(new RestAuthenticationSuccessHandler())
.failureHandler(new SimpleUrlAuthenticationFailureHandler())
.and()
.logout()
.logoutSuccessHandler(new RestLogoutSuccessHandler());
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth.userDetailsService(restUserDetailService);
}
To include the CSRF Token in your csrf protection, you can include CSRFTokenRepository to generate tokens. To illustrate in your case adding a simple line is enough:
#Override
protected void configure(HttpSecurity http) throws Exception
{
http.
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) //HERE ! Defaults XSRF-TOKEN as cookie name and X-XSRF-TOKEN as header name
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(new RestAuthenticationEntryPoint())
.and()
.formLogin()
.successHandler(new RestAuthenticationSuccessHandler())
.failureHandler(new SimpleUrlAuthenticationFailureHandler())
.and()
.logout()
.logoutSuccessHandler(new RestLogoutSuccessHandler());}
Using Spring security 5.3.0.Final, one of the ways you can generate the CSRF token is by setting it in the cookie using the following code below.
http.csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()))
You also need to include the generated CSRF token in your request for the server to authorize.
<form>
<input type="hidden" name="_csrf" value="${cookie['XSRF-TOKEN'].getValue()}" />
//Code goes here
</form>
In the event you're using a JS framework, you need to include the token by setting it in the request header.
Here is an example for a JQuery ajax call.
// Get the CSRF token from the cookie
const csrfCookie= document.cookie.replace(/(?:(?:^|.*;\s*)XSRF-TOKEN\s*\=\s*([^;]*).*$)|^.*$/, '$1');
// Add the CSRF token to each ajax request header
settings.beforeSend = function(xhr) {
xhr.setRequestHeader('X-XSRF-TOKEN', springCsrfCookie);
};
$.ajax(settings);
There are other implementations that will suit your needs documented in the following link by Spring | https://docs.spring.io/spring-security/site/docs/5.3.0.RELEASE/reference/html5/#servlet-csrf
We had pretty similar issue during our security tests where we suspected that we accidentally disable csfr in configure method of websecurityconfig class,by default it is enabled. by changing the congfigure method as shown below , we had spring automatically generate csfr tokens.
websecurityconfig class configure method==>
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/login","/loginError","/home","/interruption").permitAll()
.antMatchers("/admin").hasAuthority(Roles.ROLE_PREFIX.role()+Roles.HALLEYYNT01.role())
.antMatchers("/requests").hasAuthority(Roles.ROLE_PREFIX.role()+Roles.CCHALLEYLOGIN.role())
.antMatchers("/solrequests").hasAuthority(Roles.ROLE_PREFIX.role()+Roles.SOLHALLEYLOGIN.role())
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
//.failureUrl("/loginError")
.loginProcessingUrl("/authenticate")
.defaultSuccessUrl("/")
.and()
.logout().clearAuthentication(true).invalidateHttpSession(true).deleteCookies("JSESSIONID")
.logoutSuccessUrl("/login");
//.and()
//.exceptionHandling().accessDeniedHandler(accessDeniedHandler);
}