Restrict security authentication for read access - java

I created a web application using a sample project in GitHub. However, it required authentication for all crud operations. I want to restrict this security checking for all read DB operations. What changes do I need?
These are the related classes:
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(unauthorizedHandler)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/",
"/favicon.ico",
"/**/*.png",
"/**/*.gif",
"/**/*.svg",
"/**/*.jpg",
"/**/*.html",
"/**/*.css",
"/**/*.js")
.permitAll()
.antMatchers("/api/auth/**")
.permitAll()
.antMatchers("/api/user/checkUsernameAvailability", "/api/user/checkEmailAvailability")
.permitAll()
.antMatchers(HttpMethod.GET, "/api/polls/**", "/api/users/**")
.permitAll()
.anyRequest()
.authenticated();
// Add our custom JWT security filter
http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
}

As far as i know there is no way to magically create a read only user.However, you can create a role such as ROLE_UPDATE and make all of your methods that perform creates/updates/deletes be secured via #Secured("ROLE_UPDATE"). Then, if a user is not granted the ROLE_UPDATE authority, they will not be able to call any of the 'writing' methods, and therefore it will be restricted to only call 'read' methods.

Generally, Spring Security doesn't have such feature. You can do as #Alien suggested create some role (ex. ROLE_WRITE and then check on the resources if the user who is trying to access the resource has the correct role
#PreAuthorize("hasRole('ROLE_WRITE')")
public String someWriteOperation() {
}
The other way (but it's only applying when your JPA framework allows you such feature) it's create a Filter in spring and then before processing your request further in the chain create transaction read-only:
#Component
#Order(1)
public class TransactionFilter implements Filter {
#Override
public void doFilterServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//Create read only transaction
// ex. if(isUserReadOnly(Security ....getUser())) {DBSession.setReadOnly(true);}
//Remember it will work only if your JPA framework have the feature - explore your code/framework before
chain.doFilter(request, response);
}
}
Remember filter order should be after Spring Security Filter

Related

How to implement session management with WebFluxSecurity?

I am new to webfluxsecurity and I have been trying to implement the session management and I am using OKTA for authentication. I have found the below answers -
To kick out the old login with a new login, we only need to set the maximum number of sessions to 1. The configuration is as follows:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login.html")
.permitAll()
.and()
.csrf().disable()
.sessionManagement()
.maximumSessions(1);
}
do we have any equivalent method like sessionManagement() in webfluxsecurity ?
Or any other way we can implement session management in webflux ?
Thanks,

Do you know what problem I have with my spring security config?

I need to authenticate all requests starting from "/api/auth" except "/api/auth/login" and "/api/auth/token/refresh". This is my security config configure method. Problem is, it does not work as intended. It checks for authentication for "/api/auth/token/refresh" even though I assigned permitAll to it.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/api/auth/login").antMatcher("/api/auth/token/refresh")
.antMatcher("/api/auth/**")
.antMatcher("/api/**");
http
.cors()
.and()
.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(unauthorizedHandler)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(AUTH_WHITELIST)
.permitAll()
.antMatchers("/api/auth/login","/api/auth/token/refresh").permitAll()
.antMatchers("/api/auth/**").authenticated()
.antMatchers("/api/**").permitAll()
.anyRequest()
.permitAll();
// Add our custom JWT security filter
http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
Remove the first 3 lines of code.
Javadoc of antMatcher(String) says:
Invoking antMatcher(String) will override previous invocations of [...], antMatcher(String), [...].
Calling it 4 times doesn't do what you think it does.

Disable Basic Authentication(Spring Security) for one request and leave for all any

How can i disable basic authentication for one request and leave it for all any requests.
I try do it, but these not work for mi.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/registration").permitAll()
.and()
.authorizeRequests()
.anyRequest().authenticated().and().httpBasic();
}
Basic authentication still work for "/registration".
I assume the /registration is a web page which you have created. Then it should be
http.csrf()
.disable()
.httpBasic()
.and()
.authorizeRequests()
.antMatchers(HttpMethod.GET,"/registration")
.permitAll()
.anyRequest()
.authenticated()
You should use HttpMethod.POST if it is an API endpoint and not a webpage, or for some reason if you have a POST request for the /registration as well then remove the HttpMethod.GET all together and just leave /registration in the antMatchers

Spring security configuration; both Basic Auth and SiteMinder

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.

Spring Security applies filter to all paths, not only "/api**"

I am struggling to get my Spring Security config done properly.
I have JWT security set up, but I want it to work only on /api** and I can't get it right... Even when I try to hit localhost:8080 I am getting error from JWTFilter.
This is my config:
public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/api/**";
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class)
.exceptionHandling()
.authenticationEntryPoint(this.restAuthEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "**").permitAll()
.antMatchers(FORM_BASED_REGISTRATION_ENTRY_POINT).permitAll()
.antMatchers(FORM_BASED_LOGIN_ENTRY_POINT).permitAll()
.and()
.authorizeRequests()
.antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated()
.and()
.addFilterBefore(buildJWTLoginFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(buildJWTAuthFilter(), UsernamePasswordAuthenticationFilter.class);
}
Theoretically it should apply filters only on API, but it somehow applies them on all paths.
Can someone help to make it working as it should work, so only /api** will be secured and I can freely access all paths outside /api ?
Add and().antMatchers("/**").permitAll()

Categories

Resources