Verify custom JWT claim in Springboot - spring-boot

What's the correct and most intelligent way of verifying custom JWT claims in Springboot? Right now I have the following code which works perfectly with roles:
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.authorizeRequests().antMatchers("/*").hasRole("USER")
.and()
.exceptionHandling()
.and()
.oauth2Login();
// #formatter:on
}

Related

Spring Security (with Spring Boot) returns login form as a response for POST, EDIT, DELETE operation

I am making a meme sharing app where I have secured some REST endpoints like POST, DELETE and EDIT. And removed authentication for GET operations.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/xmeme/delete/**").hasAuthority("ADMIN")
.antMatchers("/xmeme/edit/**").hasAnyAuthority("ADMIN")
.antMatchers("/xmeme/post").hasAnyAuthority("ADMIN", "USER")
.antMatchers("/user/register").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().permitAll().defaultSuccessUrl("/xmeme/memes", true)
.and()
.logout().permitAll()
.and()
.exceptionHandling().accessDeniedPage("/403");
}
#Override public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/xmeme");
web.ignoring().antMatchers("/xmeme/memes");
web.ignoring().antMatchers("/xmeme/meme/**");
}
Now the issue is when I am trying to POST a meme and use the Authorization > Type > Basic Auth option in POSTMAN, I am getting the login form as response. And same happens with the EDIT and DELETE operations.
I couldn't find a solution. Can someone please suggest some workaround for this issue?
enter image description here
enter image description here
You have enabled Form Login for you application in configure(HttpSecurity http)
http.formLogin()
If you want to enable HTTP Basic authentication, you need to configure it in configure(HttpSecurity http)
http.httpBasic()
If you have configured both formLogin and httpBasic, Spring Security will use content-negotiation to determine how it should behave towards an unauthenticated user based on the content type being requested.
you should specify the authority with the ROLE_ prefix such as ROLE_ADMIN and ROLE_USER in configure(HttpSecurity http) method.
configure(WebSecurity web) method should be placed before the configure(HttpSecurity http) check detailed usage
Disable the CSRF token using http.csrf().disable()
Verify that user om has the correct authority assigned
#Override public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/xmeme");
web.ignoring().antMatchers("/xmeme/memes");
web.ignoring().antMatchers("/xmeme/meme/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/xmeme/delete/**").hasAuthority("ROLE_ADMIN")
.antMatchers("/xmeme/edit/**").hasAnyAuthority("ROLE_ADMIN")
.antMatchers("/xmeme/post").hasAnyAuthority("ROLE_ADMIN", "ROLE_USER")
.antMatchers("/user/register").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().permitAll().defaultSuccessUrl("/xmeme/memes", true)
.and()
.logout().permitAll()
.and()
.exceptionHandling().accessDeniedPage("/403");
}

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

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?

Spring Security mapping uppercase in URL

I work on a JEE project, using the Spring Boot framework.
For the authentification, I use Spring Security, and I specified the pages in my template.
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/token", "/index", "/index.html", "/main", "/main.html", "/main2", "/main2.html", "/recent1", "/recent1.html", "/recent2", "/recent2.html").hasRole("USER");
http
.csrf()
.disable()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error=true")
.defaultSuccessUrl("/index");
http
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login");
}
The issue is that when I run the application and I wrote the URL with uppercase letters like: localhost:8080/INDEX.HTML or I add two letters localhost/index.httml, the page does appear without authantification.
If I understand correctly, here is the desired logic:
/login does not need to be secured by Spring Security (no roles are required)
All the other pages have to be secured with "USER" role.
To implement this, you could try the following:
#Override
public void configure(WebSecurity web) throws Exception {
// configuring here URLs for which security filters
// will be disabled (this is equivalent to using
// security="none")
web
.ignoring()
.antMatchers(
"/login"
)
;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().hasRole("USER");
http.csrf().disable().formLogin()
.loginPage("/login").failureUrl("/login?error=true")
.defaultSuccessUrl("/index");
http.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login");
}
So item 1 (no security on /login) is moved to configure(WebSecurity), and item 2 is left in the original configure(HttpSecurity).

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