Spring Security and i18n - spring

I have problem with accessing when I change language on page.
Without .antMatchers("/login*").permitAll() doesn't work but with /login* is almost ok but when I provide in URL 'http://localhost:8080/login?lang=estest123' or sth not related with i18n after login I receive ??language.change_estest123??.
I tried add .regexMatchers("^login\\?lang=[a-zA-Z]{2}|^login\\?lang=_{1}[a-zA-Z]{2}").permitAll() but same result as /login*.
Is any possible to accessing only for i18n ? in other case providing error? Or maybe another way of configuration for i18n which allows in easy way to provide this?
My web security config:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**", "/registration").permitAll()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}

Does the presence of parameters affect the url parsing for Security? Just use /login and it should pass /login and /login?lang=xxx.
But if you want to use direct mapping in your config you can use both of them: .antMatchers("/login", "/login*").permitAll()

Related

Spring security - Disable CSRF and Authentication for specific URL (Java Conf)

I know this question is old but it is not working in my case.
I have a webapp using spring security authentication and CSRF enabled.
Now I want to expose couple of URL to expose to other application without authentication.
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.antMatchers("/rest/book").permitAll()
.antMatchers("/rest/check").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login")
.successHandler(customizeAuthenticationSuccessHandler)
//.defaultSuccessUrl("/")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.permitAll();
}
I have other urls with "/rest/" which are secure. I tried csrfMatcher and with that I am able to expose "/rest/book" but then other urls are giving unexpected behavior.
Unexpected behavior like, my default login page is /login when no authentication but it stopped.

How to access swagger endpoints securely?

I have added swagger ui in my application, earlier below two url's i was able to access directly without any authentication.
http://localhost:1510/swagger-ui.html
http://localhost:1510/v2/api-docs
i need secure swagger urls, don't want anybody directly see the api details of my application.
Note :- For authentication purpose i am using JWT with spring security in my application.
SO in order to secure swagger URLS , i have made entry in spring seurity config .. below code
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(problemSupport)
.accessDeniedHandler(problemSupport)
.and()
.csrf()
.disable()
.headers()
.frameOptions()
.disable()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/register").permitAll()
.antMatchers("/api/activate").permitAll()
.antMatchers("/api/userLogin").permitAll()
.antMatchers("/v2/api-docs").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/swagger-ui.html").hasAuthority(AuthoritiesConstants.ADMIN)
.and()
.apply(securityConfigurerAdapter());
}
and when i am trying to access swagger urls , i am getting below exception on browser and as well as on eclipse console.
org.springframework.security.authentication.InsufficientAuthenticationException: Full authentication is required to access this resource
How can i pass the jwt token to see the swagger page ?

Restrict access to Swagger UI

I have swagger UI working with spring-boot. I have a stateless authentication setup for my spring rest api which is restricted based on roles for every api path.
However, I am not sure how can i put <server_url>/swagger-ui.html behind Basic authentication.
UPDATE
I have following websecurity configured via WebSecurityConfig
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers("/sysadmin/**").hasRole("SYSADMIN")
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/siteadmin/**").hasRole("SITEADMIN")
.antMatchers("/api/**").hasRole("USER")
.anyRequest().permitAll();
// Custom JWT based security filter
httpSecurity
.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
}
One suggestion without knowing more about your configuration is from this SO question.
https://stackoverflow.com/a/24920752/1499549
With your updated question details here is an example of what you can add:
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers("/sysadmin/**").hasRole("SYSADMIN")
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/siteadmin/**").hasRole("SITEADMIN")
.antMatchers("/api/**").hasRole("USER")
// add the specific swagger page to the security
.antMatchers("/swagger-ui.html").hasRole("USER")
.anyRequest().permitAll();
// Custom JWT based security filter
httpSecurity
.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
}
The problem with this is it only protects the Swagger UI page and not the API specification which is loaded as a .json file from that UI page.
A better approach is to put the swagger files under a path so that you can just add antMatchers("/swagger/**").hasRole("USER")
A bit late to answer. I carried out a small POC to execute the same. I am using Keycloak and Spring Security. Below is my configuration
http
.antMatcher("/**").authorizeRequests()
.antMatchers("/swagger-resources/**","/swagger-ui.html**","/swagger-ui/").hasRole("admin")
.anyRequest().authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler(new AccessDeniedHandlerImpl())
.defaultAuthenticationEntryPointFor(authenticationEntryPoint(), new CustomRequestMatcher(AUTH_LIST))
.and()
.httpBasic()
.authenticationEntryPoint(restAuthenticationEntryPoint)
.and()
.csrf().disable()
.logout()
.logoutUrl("/logout")
.invalidateHttpSession(true)
.clearAuthentication(true)
.addLogoutHandler(keycloakLogoutHandler());
I have a working example here

two authentication mechanism on a spring boot application (Basic & JWT)

I have a spring boot app, I have just finished implementing a stateless authentication/authorization module based on jwt.
This is how I configured my security module:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.csrf()
.disable()
.headers()
.frameOptions()
.disable()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/**").authenticated()
.and()
.apply(securityConfigurerAdapter());
}
So basically if I want to access the url /api/jobs I get a 401 error unless I send the bearer token which I get after a succesfull authentication on /api/authenticate.
What I need to know is if it's possible to access /api/jobs without supplying the bearer token, using a basic http authentication with a login and passowrd
Yes, it's possible, just make sure you have:
http.httpBasic();
in your configuration. That builder also have other methods to configure the details for basic auth.

Spring security - Getting 404 error for REST call

I have an application that I am securing using Spring Security. I enable it using the annotations:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
I then configure it by overriding the configure() method:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.and()
.addFilterAfter(new CsrfCookieGeneratorFilter(), CsrfFilter.class)
.exceptionHandling()
.accessDeniedHandler(new CustomAccessDeniedHandler())
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.formLogin()
.loginProcessingUrl("/api/authentication")
.successHandler(ajaxAuthenticationSuccessHandler)
.failureHandler(ajaxAuthenticationFailureHandler)
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.logoutUrl("/api/logout")
.logoutSuccessHandler(ajaxLogoutSuccessHandler)
.deleteCookies("JSESSIONID", "CSRF-TOKEN")
.permitAll()
.and()
.headers()
.frameOptions()
.disable()
.and()
.authorizeRequests()
.antMatchers("/api/**").authenticated()
.antMatchers("/admin/**").hasAuthority(AuthoritiesConstants.ADMIN);
}
I'm getting redirected correctly to the login page when I try to get to the home page, but once I enter my credentials and try to login, I get the 404 not found error for /api/authentication REST call.
The loginProcessingUrl() method specifies the call to make. I don't have to implement this myself do I, as Spring should do that for me? Is there anything else I'm missing?
As far as I understood the login-processing-url, you have to handle the login process by yourself if you specify a special url to process the login.
Have you tried to just remove this line?:
.loginProcessingUrl("/api/authentication")
As you use springs default login form, you should just be able to remove the line and the generated login form will also change.
Maybe there's another way to solve your problem but this should also work.
If you're looking for an example on how to use custom login forms, this link might helo you.
I figured it out, it was a couple of things I needed to change:
I didn't have an Initializer class. After I added the following class, I went from a 404 not found error, to a 403 error:
public class SecurityWebApplicationInitializer
extends AbstractSecurityWebApplicationInitializer {
}
Note: you can also add the corresponding filter in your web.xml (read more here: http://websystique.com/spring-security/spring-security-4-hello-world-annotation-xml-example/)
The above change registers security with the Spring container. But I still needed to disable CSRF, as I wasn't sending the proper tokens from the client side. For my application, I don't need CSRF just yet so I have disabled it for now. However, this is not recommended so make sure sure you know what you are doing before making this change:
http.csrf().disable()

Resources