Spring Security - Authentication issue - spring-boot

I am working on a web application & have opted to use spring Security. The idea is for the user to be authenticated to see the Home Page, if the user is not authenticated they are redirected to the login page. This login page also displays a link to a registration form, This part is working correctly.
However, I have encountered an issue when attempting to allow users to sign up via the registration link. The link to the registration form cannot be accessed if the user if not authenticated ("showRegistrationForm")
Can anyone provide insight to why this is occuring? I have Included the code snippet from my SecurityConfig below
#Override
protected void configure(HttpSecurity http) throws Exception {
//Restrict Access based on the Intercepted Servlet Request
http.authorizeRequests()
.antMatchers("/resources/**", "/register").permitAll()
.anyRequest().authenticated()
.antMatchers("/").hasRole("EMPLOYEE")
.antMatchers("/showForm/**").hasAnyRole("EMPLOYEE","MANAGER", "ADMIN")
.antMatchers("/save/**").hasAnyRole("MANAGER", "ADMIN")
.antMatchers("/delete/**").hasRole("ADMIN")
.and()
.formLogin()
// Show the custom form created for the below request mappings
.loginPage("/showSonyaLoginPage")
.loginProcessingUrl("/authenticateTheUser")
// No need to be logged in to see the login page
.permitAll()
.and()
// No need to be logged in to see the logout button.
.logout().permitAll()
.and()
.exceptionHandling().accessDeniedPage("/access-denied");
}

Change the code like below:
#Override
protected void configure(HttpSecurity http) throws Exception {
// Restrict Access based on the Intercepted Servlet Request
http.authorizeRequests()
.antMatchers("/showRegistrationForm/").permitAll()
.anyRequest().authenticated()
.antMatchers("/").hasRole("EMPLOYEE")
.antMatchers("/resources/").permitAll()
.antMatchers("/showForm/**").hasAnyRole("EMPLOYEE","MANAGER", "ADMIN")
.antMatchers("/save/**").hasAnyRole("MANAGER", "ADMIN")
.antMatchers("/delete/**").hasRole("ADMIN")
.and()
.formLogin()
// Show the custom form created for the below request mappings
.loginPage("/showSonyaLoginPage")
.loginProcessingUrl("/authenticateTheUser")
// No need to be logged in to see the login page
.permitAll()
.and()
// No need to be logged in to see the logout button.
.logout().permitAll()
.and()
.exceptionHandling().accessDeniedPage("/access-denied");
}
Moved down the below code:
anyRequest().authenticated()

Related

how to RestAPI JWT login and FormLogin Spring Security with

protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage("/")
.loginProcessingUrl("/login")
.defaultSuccessUrl("/admin/list");
http
.csrf().disable()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager(), jwtUserRepository))
.authorizeRequests()
.antMatchers("/api/join"
, "/login"
).permitAll()
.antMatchers("/api/**").authenticated()
.anyRequest().permitAll();
}
If two separate http settings as above, wouldn't it be applied separately?
For example, in the http setting at the top, a separate login page was specified,
In the http setting at the bottom, I set the login page to be accessed without permission.
The part I'm trying to do is not to use the filter when there is a login request, but to go through the login process, but the filter is executed first...
How can I modify the login process so that the login process does not go through the filter when there is a login attempt?

Excluding a specific page from Spring Security that is redirected from login page

I am having trouble while I am redirecting an authentication link from my login page. I added the link in to my login page in JSF like this:
<div>
Login via Testinium Cloud
</div>
My spring security configuration is like this:
and()
.authorizeRequests()
.antMatchers(DEFAULT_URL).permitAll()
.antMatchers("/javax.faces.resource/**").permitAll()
.antMatchers("/jsfPages/*").permitAll()
.antMatchers("/errorPages/*").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler(jsfAccessDeniedHandler())
.authenticationEntryPoint(jsfAuthenticationEntryPoint())
.and()
.formLogin()
.loginPage(LOGIN_PAGE).permitAll()
.failureUrl(LOGIN_PAGE).permitAll()
.defaultSuccessUrl(DEFAULT_URL)
.successHandler(authSuccessHandler)
.and()
.logout()
.logoutUrl(LOGOUT_URL).permitAll()
.invalidateHttpSession(true)
.logoutSuccessHandler(logoutSuccessHandler)
.and()
.exceptionHandling().accessDeniedPage("/error/403.xhtml");
How could I redirect my link from login page without gettin an authentication error. I tried
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/api/v1/signup");
}
But it didn't work out for me. Thanks!
If you want to exclude a page from your spring security configuration without overriding web security, you can add 'not' method that is connected to 'antMatchers' method in your code with authenticated() method following like this:
.authorizeRequests()
.antMatchers(DEFAULT_URL).permitAll()
.antMatchers("/javax.faces.resource/**").permitAll()
.antMatchers("/jsfPages/*").permitAll()
.antMatchers("/errorPages/*").permitAll()
.antMatchers(LOGIN_TESTINIUM).not().authenticated()
.anyRequest().authenticated()
.and()

Login page needs to be prompted if user is not authorized to access specific controller or URL in spring security. How to achieve that?

I'm using spring-boot, spring-security and JSP. If I click on a button it should go to a controller if user is logged in. Otherwise, it should first ask user to login and then get back to that page. In short, user should see the page if he is logged in. How can I achieve this?
I think filters/antmatchers might be used but I am wondering how the user will get back to that particular page/controller after logging in?
Try using something like this to allow users access to certain pages and then set the default success url accordingly. You can have a home page as I use here represented by "/" and once a user logs in they are redirected to your /welcome page.
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
// Public access to login, landing, and error pages
http.authorizeRequests().antMatchers("/", "/login", "/errorpage").permitAll();
// Static resource permissions
http.authorizeRequests()
.antMatchers("/css/**", "/fonts/**", "/images/**", "/webfonts/**", "/js/**", "/webjars/**", "/messages/**")
.permitAll();
// Login specifications
http.formLogin().loginPage("/login").defaultSuccessUrl("/welcome", true);
// Logout specifications
http
.logout()
.deleteCookies("remove")
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/")
.permitAll();
}
}
Inside WebSecurityConfigurerAdapter implementation, you need to inform a formLogin and specify the loginPage.
That's just enough to Spring to use the endpoint /login this way.
If you try to access a page without logged, for example /profile, you will be redirected to /login, and after logged, you'll be redirected to /profile
And in this example, you have 3 pages accessible without authentication / ,/homeand/info`
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
...
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home", "/info" ).permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
...
}

Create custom User with OAuth2 data from authorization with Spring Security

I'm trying to support both form login and Facebook authentication in my app, the goal is both to create a User object. With formLogin I can make a sign up controller and persist my User entity, but how can I intercept the OAuth2 authentication from Facebook to create (or login if it already exists) a User entity?
This is my security configuration so far:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/oauth2/**", "/webjars/**", "/users/signup", "/users/recover", "/users/reset/**", "/img/**", "/css/**", "/js/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/users/login")
.successHandler(loginSuccessHandler())
.permitAll()
.and()
.logout()
.logoutUrl("/users/logout")
.logoutSuccessUrl("/users/login?logout")
.permitAll()
.and()
.oauth2Login()
.defaultSuccessUrl("users/facebook");
}
Is there a way to create a successHandler or similar to accomplish this?
Finally found the solution, as mentioned here you should configure your OAuth2 authorization with the spring-security-oauth2-autoconfigure package using the # EnableOAuth2Sso annotation and then creating a PrincipalExtractor to build your User entity based on the data sent by the OAuth2 provider.
This way your own model object will be accesible through getPrincipal() in further calls.

Spring Boot, Spring Security specify redirect login url

At my Spring Boot application I need to implement a following scenario:
Anonymous User visits the following page: http://example.com/product-a.html
This User wants to ask a question about this product. It can be done at another page, located by the following address: http://example.com/product-a/ask. User press Ask Question button at the http://example.com/product-a.html and login/registration popup is shown. After successful login User should be automatically redirected to http://example.com/product-a/ask (but currently with a default Spring Security implementation User are redirecting back to the page originator http://example.com/product-a.html)
How to properly with Spring Boot/Spring Security implement/configure this redirect ?
UPDATED
This is my web security config:
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http.addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class);
http
.csrf().ignoringAntMatchers("/v1.0/**", "/logout")
.and()
.authorizeRequests()
.antMatchers("/oauth/authorize").authenticated()
//Anyone can access the urls
.antMatchers("/images/**").permitAll()
.antMatchers("/signin/**").permitAll()
.antMatchers("/v1.0/**").permitAll()
.antMatchers("/auth/**").permitAll()
.antMatchers("/actuator/health").permitAll()
.antMatchers("/actuator/**").hasAuthority(Permission.READ_ACTUATOR_DATA)
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login")
.failureUrl("/login?error=true")
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl(logoutSuccessUrl)
.permitAll();
// #formatter:on
}
I use OAuth2/JWT + Implicit Flow for AngularJS client
I think you should not use spring's default /login processing url, but create your own e.g /mylogin in a controller. And then you can inject the HttpServletRequest in the method and take the action based on the context of the request for example:
#PostMapping("/mylogin")
public ResponseEntity<> processingLogingURL(HttpServletRequest request){
// switch bases on the request URL after checking security off course
switch(request.getRequestURL()){
//redirect based on the caller URL
}
}
and finally change your .loginProcessingUrl("/login") to .loginProcessingUrl("/mylogin")

Resources