I'm trying to use authenticate using in-memory users but i always keep getting "bad credentials" even when they are right .
WebSecurityConfig.java:
package com.skillshare.project.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers( "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.permitAll()
.and()
.logout()
.permitAll();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("test").password("{noop}test").roles("USER");
}
}
Related
So i have created a Security Config where i defined the patterns that i want to be granted access to without logging in. And it is not working. In my mind either the file its self is not getting scanned(even though i set it so it would be using #ComponentScan tag in the main Spring application) or the code is faulty.
Here is the code :
package com.projects.AProj.security;
import com.projects.AProj.service.AccountUserDetailsService;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder;
import static com.projects.AProj.security.Permission.DATA_READ;
import static com.projects.AProj.security.Permission.DATA_WRITE;
#Configuration
#EnableWebSecurity
#AllArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final PasswordEncoder passwordEncoder;
private final AccountUserDetailsService accountUserDetailsService;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/","/**","/api/**")
.permitAll()
.antMatchers("/my-tree", "/my-tree/*")
.hasAnyAuthority(DATA_READ.getPermission_info(), DATA_WRITE.getPermission_info())
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login").permitAll()
.defaultSuccessUrl("/",true)
.and()
.logout()
.logoutSuccessUrl("/");
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(getDaoAuthenticationProvider());
}
#Bean
public DaoAuthenticationProvider getDaoAuthenticationProvider(){
DaoAuthenticationProvider daoAuthenticationProvider =
new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
daoAuthenticationProvider.setUserDetailsService(accountUserDetailsService);
return daoAuthenticationProvider;
}
}
btw i would think that it would be helpful to note that the project it self has been acting a tad bit strange. I would get errors that the Repositories are not getting recognized, stuff like can't create bean with name "baseController", unsatisfied dependencies and those kinds of stuff.
Thanks.
I have a circular dependency forming on my WebSecurityCongfig. I have tracked it down to the UserDetailsService and once I remove it it builds but I cannot perform jwt filter because of it. The interesting part is that on my other services the exact same code works flawlessly.
package com.fain.events.events.security;
import commons.src.main.java.software.commons.config.filters.ExceptionHandlerFilter;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
#Configuration
#EnableWebSecurity
#SuppressWarnings("SpringJavaAutowiringInspection")
#RequiredArgsConstructor
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Lazy
private final UserDetailsService userDetailsServiceImpl;
#Lazy
private final JwtAuthenticationEntryPoint unauthorizedHandler;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(unauthorizedHandler)
.and()
.authorizeRequests()
.antMatchers(
"/favicon.ico",
"/configuration/ui",
"/configuration/security",
"/swagger-ui.html",
"/v2/api-docs",
"/swagger-resources/**",
"/healthcheck",
"/webjars/**",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/*.html")
.permitAll()
.antMatchers(
HttpMethod.POST,
"/api/auth/register",
"/api/auth/socialMedia",
"/api/auth/login",
"/api/auth/refreshToken",
"/api/auth/forgotPassword",
"/api/auth/resetPassword",
"/api/auth/facebook/login",
"/api/auth/resendRegistrationEmail",
"/api/auth/facebook/forwardLogin",
"/api/auth/google/login",
"/api/auth/validateTwoFactorAuthenticationCode",
"/api/auth/activateAccount",
"/api/auth/confirmAccount",
"/api/auth/validateToken",
"/api/auth/generateToken",
"/api/auth/confirmEmail",
"/resetPassword",
"/Callback/**")
.permitAll()
.antMatchers(HttpMethod.PATCH,"/api/users/{\\d+}/give-role/{\\d+}", "/api/users/{\\d+}/remove-role/{\\d+}").permitAll()
.antMatchers(
HttpMethod.GET,
"/resetPassword",
"/images/**",
"/settings/**",
"/confirmEmail",
"/api/location/**",
"/api/auth/facebook/login")
.permitAll()
.antMatchers(
HttpMethod.GET,
"/api/users/{\\d+}",
"/api/users/profiles"
).access(("isAuthenticated() or hasIpAddress('127.0.0.1')"))
.antMatchers(HttpMethod.OPTIONS)
.permitAll()
.anyRequest()
.authenticated()
.and()
// And filter other requests to check the presence of JWT in header
.addFilterBefore(
authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new ExceptionHandlerFilter(), JwtTokenVerificationFilter.class);
}
#Autowired
public void configureAuthentication(#Lazy AuthenticationManagerBuilder authenticationManagerBuilder)
throws Exception {
authenticationManagerBuilder
.userDetailsService(this.userDetailsServiceImpl)
.passwordEncoder(new BCryptPasswordEncoder());
}
#Bean
public JwtTokenVerificationFilter authenticationTokenFilterBean() throws Exception {
JwtTokenVerificationFilter authenticationTokenFilter = new JwtTokenVerificationFilter();
authenticationTokenFilter.setAuthenticationManager(authenticationManagerBean());
return authenticationTokenFilter;
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
#Lazy
#Override
public UserDetailsService userDetailsService() {
return super.userDetailsService();
}
}
Here is the circular dependency error
I'm struggling with log into my application with postman. I'm using spring security with simple configuration:
package main.configuration;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
#Configuration
#EnableWebSecurity()
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
private final UserDetailsService userDetailsService;
public WebSecurityConfiguration(#Qualifier("userDetailsServiceImpl") UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/createUser").permitAll()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().permitAll();
}
#Override
public void configure(WebSecurity web) {
web
.ignoring()
.antMatchers(HttpMethod.POST, "/createUser")
.antMatchers(HttpMethod.POST, "/login");
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
I'm sending POST request on /loginso that I could log in, but all the time I get:
photo from postman
Could you tell me what I'm doing wrong here? How am I supposed to log in and oparte on postman normally? What is interesting if I try to get page within my browser, I'm asked for credentials and then I'm succesfully logged in.
I want to access my other pages which are protected and test them using POSTMAN.
Here is the answer, lack of httpBasic()
Conf class:
package main.configuration;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
#Configuration
#EnableWebSecurity()
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
private final UserDetailsService userDetailsService;
public WebSecurityConfiguration(#Qualifier("userDetailsServiceImpl") UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/createUser").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().permitAll().and().httpBasic();
http.csrf().disable();
}
#Override
public void configure(WebSecurity web) {
web
.ignoring()
.antMatchers(HttpMethod.POST, "/createUser");
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
In that case can you please change below as of now and take it from there ?
#Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user1").password(passwordEncoder().encode("user1Pass")).roles("POSTMAN");
}
#Override
protected void configure(final HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/login*").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginProcessingUrl("/login")
.defaultSuccessUrl("/success.html", true) // example page where request need to be redirected when login is sucessful.
.and()
.logout()
.deleteCookies("JSESSIONID");
}
Try above username and password using in memory implementation first and then configure databaseservice later.
Create success.html and you should see the same after login attempt
If you want to test internal URL's through POSTMAN without authentication/ authorization then comment .anyRequest().authenticated() during testing.
I am following the documentation from Spring.io to setup user authentication using Spring Boot.
Here are the files in question:
MvcConfig.java
package com.*********.*******;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Configuration
public class MvcConfig implements WebMvcConfigurer {
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/home").setViewName("home");
registry.addViewController("/").setViewName("home");
registry.addViewController("/hello").setViewName("hello");
registry.addViewController("/login").setViewName("login");
}
}
WebSecurityConfig.java
package com.*********.*******;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
#Bean
#Override
public UserDetailsService userDetailsService() {
UserDetails user =
User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
}
How can I eliminate the home.html file and wire it so that localhost:808 takes the user directly to the login which, if successful, brings them to the hello.html file?
If I change the default controller to the following code, then it just enters a loop of the login page because the login takes you to the previous page you were trying to access. How can I instead have it send the user to hello.html?
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/home").setViewName("home");
registry.addViewController("/").setViewName("login");
registry.addViewController("/hello").setViewName("hello");
registry.addViewController("/login").setViewName("login");
}
I apologize if this post is worded poorly. If there is anything I can add for clarity, please don't hesitate to ask and I will make any corrections.
Remove the line .antMatchers("/", "/home").permitAll() so all urls are protected and redirected to login.
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
I have a fundamental problem with spring boot application. The start webpage is http://127.0.0.1:8080/login and after log in user is redirect to http://127.0.0.1:8080/MainMenu. Unfortunatelly it is also possible to write in url bar http://127.0.0.1:8080/MainMenu and going there without authentication.
What is the main idea to block that action?
#edit
This is my configuration:
package local.vlex.security;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "src/main/resources/static/assets/css/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}
and Controller:
#GetMapping("/MainMenu")
public ModelAndView correctCredentials(){
ModelAndView mav = new ModelAndView();
mav.setViewName("MainMenu");
return mav;
}
Sum up:
I would like to block going to other sites without authentication - if someone is not logged in then it should go 404 on everything other than /login
if someone is not logged in then it should go 404 on everything other
than /login
This is a bit pecular requirement. What is usually done is that people get redirected to login page on all other urls than login, or get 401 Unauthorized or 403 Forbidden. However, it's not hard to do this one either.
You mentioned you need your static resources (css, js, images) in the assets directory as well, so given that, this should work:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
#Configuration
#EnableWebSecurity
public class YourSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login", "/assets/**").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.NOT_FOUND))
;
}
}
Using
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
and
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
in Maven pom.xml
Note that there is also accessDeniedHandler() in exceptionHandling(), but that seems to only fire when user is already authenticated but denied access, so you'd need authenticationentrypoint for your use case.
Addition:
Sometimes having a custom authentication entrypoint messes the existing entry point handler. That is the case at least if you use default spring-generated form login. One way to go around that is to specify your entrypoint to only match urls that are not matching your authentication handler url, like this:
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.NegatedRequestMatcher;
// snip...
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login", "/assets/**").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.defaultAuthenticationEntryPointFor(new HttpStatusEntryPoint(HttpStatus.NOT_FOUND),
new NegatedRequestMatcher(new AntPathRequestMatcher("/login")) )
.and()
.formLogin()
;
}
Add the following code, It will block all the request except "/" & "/login"
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers(
"/css/**",
"/js/**",
"/lib/**",
"/video/**",
"/images/**"
);
}
}
And add WebConfig
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter{
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/**")
.addResourceLocations("classpath:/static/")
.setCachePeriod(31556926)
.resourceChain(true);
}
}
Don't forget to add the security dependency in your pom.xml file.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Provided that you have spring-security dependencies on classpath, this is a working example from my code.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/login**")
.permitAll()
.anyRequest()
.authenticated();
This blocks me from any other requests than '/' or 'login' or 'loginPage' etc. with Authorization.
Follow that with ignoring the static ones, css, js etc.,
If this still doesn't work, for now try working on blocking the page alone:
http.authorizeRequests()
.antMatchers("/MainMenu")
.authenticated();
The above would give idea what's happening. Dependency issue or something like that.