Logout doesn't work with Spring Boot and Spring Security - spring

This is my code using Spring Boot and Spring Security. The problem is when I used to logout (using Thyemleaf) the logout doesn't work for me.
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Autowired
private DataSource dataSource;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("select username as principal, password as credentials,active from users where username=?")
.authoritiesByUsernameQuery("select username as principal,roles as role from users_roles where username=?")
.rolePrefix("ROLE_")
.passwordEncoder(new Md5PasswordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage("/login");
http
.authorizeRequests()
.antMatchers("/index1").permitAll();
http
.authorizeRequests()
.antMatchers("/user").hasRole("USER")
.and()
.logout();
http
.authorizeRequests()
.antMatchers("/adpage").hasRole("ADMIN");
http
.exceptionHandling().accessDeniedPage("/403");
http
.logout().permitAll();
}
}
Link using Thyemleaf:
<li><a th:href="#{/login?logout}">logout</a></li>

Try doing something like this.
<form th:action="#{/logout}" method="post">
<input type="submit" value="Log out"/>
</form>
Spring security logout Url is POST only. You can support Non-POST logout by changing your Java Configuration
protected void configure(HttpSecurity http) throws Exception {
http
// ...
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
}
this way you can logout user using GET request
<li><a th:href="#{/logout}">logout</a></li>

Try the following instead:
http
.formLogin()
.loginPage("/login")
.failureUrl("/login?login_error=true")
.loginProcessingUrl("/j_spring_security_check") //if needed
.and()
.authorizeRequests()
.antMatchers("/index1").permitAll()
.antMatchers("/user").hasRole("USER")
.antMatchers("/adpage").hasRole("ADMIN")
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.logout()
.logoutSuccessUrl("/index") //or whatever page you want
.logoutUrl("/logout") //thinking this is what you need
.permitAll();
And your link would be:
<li><a th:href="#{/logout}">logout</a></li>

Related

Spring security makes a session when a user access the log in page

I'm making log in page, following official guide.
I want to add a function which makes redirect to home if a user join.
The logic is like this.
A user join with email, password and username.
Joinpage redirect to log in page.
if there is authentication, directly go to home.
How can I redirect to home with authentication?
#Slf4j
#Controller
#RequiredArgsConstructor
public class LoginController {
#GetMapping("/login")
public String loginForm(#ModelAttribute LoginForm loginForm) {
return "login/loginForm";
}
}
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final UserSecurityService userSecurityService;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() // 인가 요청 받기
.antMatchers("/", "/home", "/join",
"/css/**", "/*.ico", "/error").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/")
.failureUrl("/login")
.usernameParameter("email")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
.invalidateHttpSession(true);
}
basically, the security generates user session along the SessionCreationPolicy value when the user logins successfully.
if you want to change the session system to stateless system.
but following the below code.
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
}
and then, you need to set the authentication object.
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken("principal", "credentials", null));

Two login authentication ways in Spring Boot

I need develop an app with two authentication endpoints: one a login web form and other sending credentials via custom token.
I create two WebSecurityConfigurerAdapter and the login forms work perfectly but the token not: When I tried to identify via token, it run ok but always redirect to de login form page.
This is my configuration:
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(authenticationFilter(), CustomAuthenticationFilter.class)
.authorizeRequests()
.mvcMatchers(PublicUrls.URLS).permitAll()
.anyRequest().fullyAuthenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/")
.permitAll()
.and()
.cors()
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout")
.permitAll();
}
.. and the token configuration:
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.mvcMatcher(LOGINJWT)
.addFilterBefore(authenticationFilter(), WebAsyncManagerIntegrationFilter.class)
.authorizeRequests()
.antMatchers(LOGINJWT).permitAll()
.anyRequest().fullyAuthenticated()
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout")
.permitAll();
// #formatter:on
}
When I trie to authenticate via token, it run the customFilter, and the custom authentication provider correctly but always redirect to login page.
The classes order annotation are this:
// Token annotation class
#Configuration
#Order(1)
#EnableWebSecurity
public class JwtWebSecurityConfigurerAdapter
extends WebSecurityConfigurerAdapter {....}
//login annotation clas
#EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
#EnableWebSecurity
#Configuration
#RequiredArgsConstructor
#Slf4j
#Order(2)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {...}
I don't see the problem.
I found the problem: the JWT filter is executing before WebAsyncManagerIntegrationFilter.

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");
}
}

HTTPS Secured works only on home page not the next page

I am deploying a spring boot webapplication in AWS EC2 instance on port 80 and the home page is displayed as Secured When I click on the link like user login or admin login the browser shows it as Not Secured.What should I do to make my whole application secured.
Below is my code which I am using from a site,I am new to spring security,Please help.
Home.html
<div class="starter-template">
<h1>Spring Boot Web Thymeleaf + Spring Security</h1>
<h2>1. Visit <a th:href="#{/admin}">Admin page (Spring Security protected, Need Admin Role)</a></h2>
<h2>2. Visit <a th:href="#{/user}">User page (Spring Security protected, Need User Role)</a></h2>
<h2>3. Visit <a th:href="#{/about}">Normal page</a></h2>
</div>
#Configuration
// http://docs.spring.io/spring-boot/docs/current/reference/html/howto-security.html
// Switch off the Spring Boot security configuration
//#EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private AccessDeniedHandler accessDeniedHandler;
// roles admin allow to access /admin/**
// roles user allow to access /user/**
// custom 403 access denied handler
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/", "/home", "/about").permitAll()
.antMatchers("/admin/**").hasAnyRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("USER")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll()
.and()
.exceptionHandling().accessDeniedHandler(accessDeniedHandler);
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER")
.and()
.withUser("admin").password("password").roles("ADMIN");
}
}
What am I doing wrong?Is the issue in the code or my AWS Configuration
Solved the issue by setting application.properties to the below
server.use-forward-headers=true

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.

Resources