SpringSecurity - SecurityConfiguration.java - HttpSecurity - not working - java

I am trying to implement Spring Security to my MVC Maven based project with already included Spring Boot.
I have working front-end and back-end but until now I was using fake login - I was simply scoping user data such as username and password via JS and AngularJS and sending it to the back-end controller where data from DB was retrieved via DAO layer and compared to the scoped info after witch response was sent - and if it was "OK" I forwarded user to the User Home Page and vice versa.
This means that if I run my app and type directly to the browser bar localhost:8080/#/user (page that only user that is loged in is supposed to see) I can access it without any problems.
Now when business logic layer testing is finished the time has come to implement Spring Security.
I am still trying to understand Spring Security and trying to properly write SecurityConfiguration.java file - to have it set so it wont let no one access book.html and user.html pages, and, eventually, redirect such user to login.html.
This is my SecurityConfiguration.java file:
#Configuration
#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Resource
private DataSource dataSource;
#Bean
public BCryptPasswordEncoder PasseordEncoder() {
return new BCryptPasswordEncoder();
}
protected void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
JdbcUserDetailsManager userDetailsService = new JdbcUserDetailsManager();
userDetailsService.setDataSource(dataSource);
PasswordEncoder encoder = new BCryptPasswordEncoder();
auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
auth.jdbcAuthentication().dataSource(dataSource);
if (!userDetailsService.userExists("user")) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("USER"));
User userDetails = new User("user", encoder.encode("password"),
authorities);
userDetailsService.createUser(userDetails);
}
}
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/user").access("hasRole('USER')")
.antMatchers("/book").access("hasRole('USER')");
}
}
But when I run the app and try to access for example /user it allows me to! Can someone help me understand what am I to do, and how to fix this and pass the first step?

I think you forgot to declare an entry point for authentication. As you noted in your comment, you need to add .and().formLogin().loginPa‌​ge("collections/login") to your http.authorizeRequests().
But, you also need to authorize unauthenticated access to the login page to avoid the redirect loop : ask page -> need authentication -> redirect to login page -> need authentication -> redirect ...
You should simply have followed the following example of the reference manual about Java Configuration and Form Login :
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll();
}
With your code, it gives :
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/user").access("hasRole('USER')")
.antMatchers("/book").access("hasRole('USER')")
.and().formLogin().loginPage("/collections/login").permitAll();
}
Last remark : note the / in front of login URL. Always use absolute path if you want your login page to be found from any page other than / !

Give this a go
Current
http.authorizeRequests()
.antMatchers("/user").access("hasRole('USER')")
.antMatchers("/book").access("hasRole('USER')");
Change to:
http.authorizeRequests()
.antMatchers("/user").hasRole('USER')
.antMatchers("/book").hasRole('USER');
Hope that helps (worked for me).

Related

Spring Security Redirect Logged Users From Login/Register Page to Home

I'm building a spring boot application with spring security in which I want to prevent logged-in users from viewing some specific pages and instead redirect them to another.
For example, if a logged-in user goes to /register or /login, he should be redirected to /home.
What is the best way to achieve this?
My config class looks like this:
#Configuration
#EnableWebSecurity
public class AppSecurityConfig
{
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login-action")
.defaultSuccessUrl("/login-success")
.failureUrl("/login?error");
return httpSecurity.build();
}
}

Spring boot stateless form login /oauth/authorize

Is it possible to create a form login page, where the session creation policy SessionCreationPolicy.STATELESS.
When I configure it without sessionCreationPolicy, the login works.
#Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http.csrf().disable()
.and()
.authorizeRequests().anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").permitAll();
// #formatter:on
}
}
When logging in, the POST will be send to /login and apperantly it will look in the session to redirect it back to the /oauth/authorize page (if you were coming from there).
But when I add:
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
It does not know where to redirect it to after login. Does anyone know how to achieve this?
I could not make this work with the .formLogin() options.
What I did is create a new MVC controller, where you could post your username and password. Authenticate against AuthenticationManager, if login was successful, forward the request to where /oauth/authorize is locating.

Filter ordering with spring security and spring boot

I'm trying to use spring security to secure a rest/stateless api using JWT tokens. From the research I've been seeing, it involves turning off the spring security session management and then adding some custom filters to handle the user logging in as well as checking for the jwt token.
The problem I'm having is that once i add a filter, it's run on every instead of just the endpoints I want it on. I need to open up the login endpoint as well as a few others that will facilitate enrollment and reference data that doesn't need to be secured.
#Configuration
#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/user").permitAll()
.anyRequest().authenticated().and()
.addFilterBefore(new StatelessAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
;
}
}
All StatelessAuthenticationFilter does is print "in here". I'm only expecting to see that message print when you go to localhost:8080/api/order, but i see it show up when you go to localhost:8080/api/user.
Is there a way to get this behavior?
The way you configured, the HttpSecurity will be applied to all the URLs including the user endpoint.
authorizeRequests() .antMatchers("/api/user").permitAll() line won't prevent "user" endpoint from authentication filter being called.
It just says that any authenticated user can call it.
You need to apply the filter to "order" endpoint only. Like this:
http .requestMatchers().antMatchers("/api/user") .and() .authorizeRequests().
#tsolakp's answer sorta works for me. I ended up overriding the
configure(Websecurity) method though
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/api/user");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.anyRequest().authenticated().and()
.addFilterBefore(new StatelessAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
;
}

How to implement basic authentication in Spring boot?

I've followed this and this tutorial to create a skeleton of an Angular.JS application with a Java-based backend. Its code can be found here.
It has authentication - at the start Spring boot writes to the console a random password, which you can use to login to the started application. User name is user and the password is printed in the console at the start:
Now I want to have several user accounts with fixed passwords (it's OK, if they are hardcoded).
How can I do this in that application without breaking compatibility with AngularJS?
I suppose that I have to modify SecurityConfiguration in UiApplication and use something like
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password("password")
.roles("USER");
}
as explained here, but I'm not sure that it won't break AngularJS.
That's the solution:
#Configuration
#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
class SecurityConfiguration extends
WebSecurityConfigurerAdapter {
#Autowired
public void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user1")
.password("password1")
.roles("ADMIN")
.and()
.withUser("user2")
.password("password2")
.roles("USER");
}
As long as you don't change the authentication scheme (i.e. BASIC, FORM etc.), AngularJS doesn't care about how you manage the user accounts in the backend. Of course if you would have used a fixed user and password and have it hardcoded in the AngularJS code, you would have to change this.
It wouldn't break the angular compatibility. But in addition to the code change you mentioned, you would also need to make sure that you are allowing access to /login URI anonymously. Change in your overloaded configure method would also be required, something as follows:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/login.html").permitAll()
.antMatchers("/index.html", "/home.html").authenticated()
.antMatchers("/index.html", "/home.html").hasRole("USER")
.anyRequest().authenticated();
}

Spring Security Java Config without Forcing Auth

I am having a difficult time figuring out how to wire up spring security without forcing authentication. My specific app does not require the user to authenticate but the user can authenticate if they want.
I currently have a WebSecurityConfigurerAdapter set up that you can see at the end of this post. With this setup I'm getting a 403 on all /api/* requests and /j_spring_security_check.
Could someone please help me either fix my existing config or point me to a working example that accomplishes this?
Every example I see out there seems to require the user to authenticate and if they don't it throws a 403. In my app, I'm just using it to establish a session and at this point all users should be able to access all end points regardless of if they are authenticated or not.
WebSecurityConfig
#EnableWebSecurity
#Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private ItAuthenticationProvider customAuthenticationProvider;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(customAuthenticationProvider);
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().antMatchers("/**").permitAll()
.antMatchers("/j_spring_security_check").permitAll()
.and().formLogin()
.loginProcessingUrl("/j_spring_security_check")
.defaultSuccessUrl("/successful.html")
.loginPage("/#login")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/successful.html");
}
}
You can take a look at this sample Spring Security application we built with Stormpath support. In this example, the home screen does not require authentication. Furthermore, the information that is displayed there is dynamically calculated based on whether the user is authenticated or not.
If I understand your requirement, you can use the anonymous authentication.
The documentation can be found here

Categories

Resources