Why the character ';' is added the end of request in OAuth2 - spring-boot

There are Authorization Server(UAA) and Resource Server and Gateway applications that have been working correctly. The scenario for authentication is authorization_code. In the first time after authentication, the end of request is added ;jesessionid=[value], so its result is exception from HttpFirewall of Gateway application, because of having ';' in the request.
My question is that what is it and why jessionid is added the end of request? and how is it adaptable with HttpFirewall.
I have found a way around but I know it has some risks. It is like this:
#Bean
public HttpFirewall allowUrlEncodedSlashHttpFirwall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowSemicolon(true);
return firewall;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.headers().cacheControl().disable()
.and()
.headers()
.cacheControl()
.disable()
.frameOptions()
.sameOrigin()
.and()
.httpBasic().disable()
.authorizeRequests()
.requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
.mvcMatchers("/uaa/**", "/login**", "/favicon.ico", "/error**").permitAll()
.anyRequest().authenticated()
.and()
.logout()
.permitAll();
}
#Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
web.httpFirewall(allowUrlEncodedSlashHttpFirwall());
}
As above configuration, the ; is skipped but it is not right and it has some risks.
What is the correct way and config to solve this problem?

Related

How to throw user to a page other than /login if user is not authenticated in spring security

I wanted to throw users out on signup page instead of login page when they are not authenticated. One workaroud I did was to pass "/signup" in .loginPage() function in Security configuration of spring boot application.
But now I also need to put a .rememberMe() feature for login page. because of that I have to pass "/login" in .loginPage(). So that I can add .rememberMe() functionality.
To summarize, How can I throw non-authenticated users to /signup page as well as keeping the rememberMe functionality on login page?
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/game*/**").authenticated()
.antMatchers("/contest*/**").authenticated()
.antMatchers("/badges_awards").authenticated()
.antMatchers("/admin*/**").hasRole("ADMIN")
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("emailAddress")
.passwordParameter("password")
.permitAll()
.and()
.rememberMe()
.key("remember-me")
.rememberMeParameter("remember-me")
.rememberMeCookieName("rememberlogin")
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/")
.permitAll();
http.csrf().disable();
http.headers().frameOptions().disable();
}
Start your configuration like this to tell Spring Security that /signup URL does not need authentication and therefore won't be redirect to your login page :
http.authorizeRequests()
.antMatchers("/signup").permitAll()
try this
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login.html").permitAll()
.antMatchers("/signup*/**").permitAll()
.and()
.formLogin()
.loginPage("/login")
.failureHandler(LoginAuthFailureHandler)
.and()
.exceptionHandling()
.accessDeniedPage("/signup.html");
}
#Component
public class LoginAuthFailureHandler extends SimpleUrlAuthenticationFailureHandler {
#Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
getRedirectStrategy().sendRedirect(request, response, "/signup.html");
}
}

How to log out sucessfully

My login page is http://localhost:8080/nradmin/welcome
and my home page (after successful log in) is http://localhost:8080/nradmin/home
I'd like to log out and not anymore be able anymore to access any other page like the home page but only the welcome (login) page. If I type http://localhost:8080/nradmin/home on the browser after logout I continue to have access to the home page without logging in.
I've implemented the following methods overriden from the abstract class WebSecurityConfigurerAdapter:
#Override
protected void configure(HttpSecurity http) throws Exception { http
.authorizeRequests()
.antMatchers("/welcome").permitAll()
.antMatchers("/home", "/account/**", "/price/**").hasRole("ADMIN")
.antMatchers("/home", "/account/**", "/price/**").access("hasRole('ROLE_ADMIN')")
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/welcome")
.defaultSuccessUrl("/home")
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutSuccessUrl("/welcome")
.logoutUrl("/welcome")
.deleteCookies()
.permitAll()
.and()
.exceptionHandling()
.accessDeniedPage("/welcome")
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
}
#Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication() .withUser("username").password(passwordEncoder().encode("12345")).roles(LoginDataConstants.ROLE_ADMIN)
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
Does anyone have an idea how to do it?
I guess it may be due to having the same url in the methods logoutUrl and logoutSuccessUrl.
I suggest you to change logoutUrl to other path, for example just /logout and then try to perform the logout hitting that url. It should complete the logout task and the redirect to the logoutSuccessUrl, which is /welcome
Add CSRF
Reference from spring docs.
Will perform logout with the URL /logout is requested with any HTTP method
#Override protected void configure(HttpSecurity http) throws Exception {
http.
logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
}
}
You can also reference a good example on stack overflow using this same method here
When I had this issue I used this line
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login");
Where
.logoutSuccessUrl("/login") was the page the user will be redirected to.
You could re-factor your code to something like this
#Override
protected void configure(HttpSecurity http) throws Exception { http
.authorizeRequests()
.antMatchers("/welcome").permitAll()
.antMatchers("/home", "/account/**", "/price/**").hasRole("ADMIN")
.antMatchers("/home", "/account/**", "/price/**").access("hasRole('ROLE_ADMIN')")
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/welcome")
.defaultSuccessUrl("/home")
.and()
.logout()
.and() // This section is re-factored.
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/welcome").deleteCookies("JSESSIONID") //Or try .logoutSuccessUrl("/nradmin/welcome")
.invalidateHttpSession(true)
.permitAll()
.and()
.exceptionHandling()
.accessDeniedPage("/welcome")
.and()
.sessionManagement()
.sessio hinCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
Update : This is a modified version. This is essentially what I use in my project except for this portion:
.and()
.exceptionHandling()
.accessDeniedPage("/welcome")
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
So, I believe it should work; otherwise, I believe it may be a setup issue/configuration that resides somewhere else in your project. Please try the below example.
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/nradmin/welcome", "/home", "/account/**", "/price/**").hasRole("ADMIN")
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/nradmin/welcome")
.permitAll()
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/nradmin/welcome").deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.permitAll()
.and()
.exceptionHandling()
.accessDeniedPage("/nradmin/welcome")
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
}

Spring Security Ignores all requests when you should just ignore the OPTIONS requests

Before GET/POST request the client make a OPTIONS request, so I keep this calls ignored. But when I make this configuration, the another requests(GET/POST) are ignored too (but should not ignore).
When I add this line:
.antMatchers(HttpMethod.OPTIONS);
All requests are ignored, but the GET/POST should not ignored.
The following is the configuration method:
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.POST, "/login")
.antMatchers(HttpMethod.OPTIONS);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.anyRequest().authenticated()
.antMatchers(HttpMethod.OPTIONS).permitAll()
.antMatchers(HttpMethod.GET, "/login/authenticate").authenticated()
.antMatchers(HttpMethod.GET, "/credenciadas**").hasRole(PermissaoEnum.CONSULTAR_CREDENCIADA.getNomeInterno())
.antMatchers(HttpMethod.POST, "/credenciadas/validar").hasRole(PermissaoEnum.CONSULTAR_CREDENCIADA.getNomeInterno())
.antMatchers(HttpMethod.POST, "/credenciadas").hasRole(PermissaoEnum.INCLUIR_CREDENCIADA.getNomeInterno())
.antMatchers(HttpMethod.POST, "/credenciadas/alterar").hasRole(PermissaoEnum.ALTERAR_CREDENCIADA.getNomeInterno())
.antMatchers(HttpMethod.DELETE, "/credenciadas/").hasRole(PermissaoEnum.EXCLUIR_CREDENCIADA.getNomeInterno())
.and()
.addFilterBefore(authenticationByTokenFilter(), UsernamePasswordAuthenticationFilter.class)
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())
.and()
.csrf().disable();
}
Could you verify if you set the prefix string at role name as: "ROLE_"? The role name could be wrong.

Spring Security. Any request needs to be authorized and a special POST request needs an admin role. How to do this?

I want to secure my HATEOAS REST API build with Spring. All requests should need authorization and POST requests to "/rooms" should need the admin role. My WebSecurityConfigurerAdapter implementation code looks like this right now:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
// Todo: Make sure that all resources need to be authenticated and POST rooms needs ADMIN role
.anyRequest().authenticated()
.antMatchers(HttpMethod.POST, "/api/v1/rooms").hasRole("ADMIN")
.and()
.httpBasic()
.and()
.csrf().disable();
}
Right now all resources only need authentication if I put the "anyRequest().authenticated()" line before the "antMatchers..." line, but then the needed "ADMIN" role doesn't work or get applied and vice versa.
How am I to get both things working at the same time?
Kind Regards,
Florian
Securityconfiguration.java
#Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().and().authorizeRequests().antMatchers("/public/**")
.permitAll().antMatchers("/sa/**").hasAuthority("sa")
.antMatchers("/admin/**").hasAuthority("admin")
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/index.html").and()
.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
.csrf().disable();
}
And in the rest controller use..
#RequestMapping("/admin/adduser")
public void addUser(#RequestBody User user) {
authService.addUser(user);
}
The following code did it for me:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/api/v1/rooms").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.csrf().disable();
}
}
Thank you for the response Pankaj.

questions for spring security config

I`ve tried to config Spring Security.
This is my sucurity config.
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http.authorizeRequests()
.antMatchers("/api/**", "/denied**").permitAll()
.anyRequest().denyAll()
.and()
.exceptionHandling().accessDeniedPage("/denied")
.and()
.csrf().disable();
// #formatter:on
}
When I access url "localhost:8080/admin", I expect "/denied" page.
But it shows default 403 page provided spring security.
Is there any problem my configuration?
Update:
Change .anyRequest().denyAll() to .anyRequest().authenticated()
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http.authorizeRequests()
.antMatchers("/api/**", "/denied**").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling().accessDeniedPage("/denied")
.and()
.csrf().disable();
// #formatter:on
}
If u need to use requiresSecure(), just add .requiresChannel().anyRequest().requiresSecure().and() after .and()

Resources