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

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.

Related

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 Boot WebSecurityConfig LogoutSuccessURL with invalidSessionUrl

I am working on a spring boot project and WebSecurityConfig for session control. The issue is that when the session expires, i am being redirected to /?sessionexpired when my expectation is that it should redirect o /?expiredsession. Also when user logout the page is redirected to /?sessionexpired and not /?logout.
My config is as follow
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/thirdparty/**", "/webjars/**", "/sessionerror").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/")
.failureUrl("/?error")
.defaultSuccessUrl("/dashboard")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/?logout")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")) // override default of only allowing POST for logout so we can use a GET
.deleteCookies("remove")
.invalidateHttpSession(true)
.permitAll()
.and()
.sessionManagement()
.maximumSessions(1)
.expiredUrl("/?expiredsession")
.maxSessionsPreventsLogin(false)
.and()
.invalidSessionUrl("/?sessionexpired");
}
Can someone please help me figure this out.
So i eventually figured it out. It is redirecting to /?sessionexpired because on logout i am invalidatingSession by setting it to true. I should set it to false and then use .deleteCookies("JSESSIONID") to invalidate the session. This way it will redirect properly.

What does .and() do in Spring Security classes like HttpSecurity?

In the below code example, what is the .and() actually doing?
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterAfter(new CsrfCookieGeneratorFilter(), CsrfFilter.class)
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.rememberMe()
.rememberMeServices(rememberMeServices)
.key(env.getProperty("jhipster.security.rememberme.key"))
.and()
.formLogin()
.loginProcessingUrl("/api/authentication")
.successHandler(ajaxAuthenticationSuccessHandler)
.failureHandler(ajaxAuthenticationFailureHandler)
.usernameParameter("j_username")
.passwordParameter("j_password")
.permitAll()
.and()
.logout()
.logoutUrl("/api/logout")
.logoutSuccessHandler(ajaxLogoutSuccessHandler)
.deleteCookies("JSESSIONID")
.permitAll()
.and()
.headers()
.frameOptions()
.disable()
.authorizeRequests()
.antMatchers("/api/register").permitAll()
.antMatchers("/api/activate").permitAll()
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/logs/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/api/subscriptions").permitAll()
.antMatchers("/api/**").authenticated();
}
from the spring documentation :
The Java Configuration equivalent of closing an XML tag is expressed
using the and() method which allows us to continue configuring the
parent. If you read the code it also makes sense. I want to configure
authorized requests and configure form login and configure HTTP Basic
authentication.
So consider you have multiple configuration one for users which have admin role, and the second for the simple user role, to concatenate all them together we use and() method.
And this technique is a builder design pattern

How can I get session data in my controller after user is logged in

I have extended WebSecurityConfigurerAdapter in my Spring Boot MVC application. I also created the below method
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/")
.permitAll()
.antMatchers("/login")
.permitAll()
.antMatchers("/registration")
.permitAll()
.antMatchers("/dashboard")
.hasAuthority("ADMIN")
.anyRequest()
.authenticated()
.and()
.csrf()
.disable()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error=true")
.defaultSuccessUrl("/dashboard")
.usernameParameter("email")
.passwordParameter("password")
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/home")
.and()
.exceptionHandling()
.accessDeniedPage("/access-denied");
}
After the user logs in, I need some information like username, role, email, etc in my /dashboard controller. How can I achieve that?
I tried googling but could not find any concrete information about this.
Well, you have few options:
You can call the static method SecurityContextHolder.getContext().getAuthentication() (this way you can get the credentials all over you application)
If you are in the controller, you can have a Principle as a parameter to get the information
If you want the authentication token, you can have an Authentication as a parameter.
Note that you have to have some kind of mechanism to authenticate the user (openid with active-directory for instance) and make you server work with it.
See http://www.baeldung.com/get-user-in-spring-security for more information

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