When I deploy my Spring application via Spring Boot and access localhost:8080
I have to authenticate, but what is the username and password or how can I set it? I tried to add this to my tomcat-users
file but it didn't work:
<role rolename="manager-gui"/>
<user username="admin" password="admin" roles="manager-gui"/>
This is the starting point of the application:
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
And this is the Tomcat dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
How do I authenticate on localhost:8080
?
I think that you have Spring Security on your class path and then spring security is automatically configured with a default user and generated password
Please look into your pom.xml file for:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
If you have that in your pom than you should have a log console message like this:
Using default security password: ce6c3d39-8f20-4a41-8e01-803166bb99b6
And in the browser prompt you will import the user user
and the password printed in the console.
Or if you want to configure spring security you can take a look at Spring Boot secured example
It is explained in the Spring Boot Reference documentation in the Security section, it indicates:
The default AuthenticationManager has a single user (‘user’ username and random password, printed at `INFO` level when the application starts up)
Using default security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35
If spring-security
jars are added in classpath and also if it is spring-boot
application all http endpoints will be secured by default security configuration class SecurityAutoConfiguration
This causes a browser pop-up to ask for credentials.
The password changes for each application restarts and can be found in console.
Using default security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35
To add your own layer of application security in front of the defaults,
@EnableWebSecurity
public class SecurityConfig {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
or if you just want to change password you could override default with,
application.xml
security.user.password=new_password
or
application.properties
spring.security.user.name=<>
spring.security.user.password=<>
inMemoryAuthentication
you rather prefix your password with {noop} when you receive the error: There is no PasswordEncoder mapped for the id “null”
When overriding
spring.security.user.name=
spring.security.user.password=
in application.properties, you don't need "
around "username"
, just use username
. Another point, instead of storing raw password, encrypt it with bcrypt/scrypt and store it like
spring.security.user.password={bcrypt}encryptedPassword
If you can't find the password based on other answers that point to a default one, the log message wording in recent versions changed to
Using generated security password: <some UUID>
You can also ask the user for the credentials and set them dynamically once the server starts (very effective when you need to publish the solution on a customer environment):
@EnableWebSecurity
public class SecurityConfig {
private static final Logger log = LogManager.getLogger();
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
log.info("Setting in-memory security using the user input...");
Scanner scanner = new Scanner(System.in);
String inputUser = null;
String inputPassword = null;
System.out.println("\nPlease set the admin credentials for this web application");
while (true) {
System.out.print("user: ");
inputUser = scanner.nextLine();
System.out.print("password: ");
inputPassword = scanner.nextLine();
System.out.print("confirm password: ");
String inputPasswordConfirm = scanner.nextLine();
if (inputUser.isEmpty()) {
System.out.println("Error: user must be set - please try again");
} else if (inputPassword.isEmpty()) {
System.out.println("Error: password must be set - please try again");
} else if (!inputPassword.equals(inputPasswordConfirm)) {
System.out.println("Error: password and password confirm do not match - please try again");
} else {
log.info("Setting the in-memory security using the provided credentials...");
break;
}
System.out.println("");
}
scanner.close();
if (inputUser != null && inputPassword != null) {
auth.inMemoryAuthentication()
.withUser(inputUser)
.password(inputPassword)
.roles("USER");
}
}
}
(May 2018) An update - this will work on spring boot 2.x:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger log = LogManager.getLogger();
@Override
protected void configure(HttpSecurity http) throws Exception {
// Note:
// Use this to enable the tomcat basic authentication (tomcat popup rather than spring login page)
// Note that the CSRf token is disabled for all requests
log.info("Disabling CSRF, enabling basic authentication...");
http
.authorizeRequests()
.antMatchers("/**").authenticated() // These urls are allowed by any authenticated user
.and()
.httpBasic();
http.csrf().disable();
}
@Bean
public UserDetailsService userDetailsService() {
log.info("Setting in-memory security using the user input...");
String username = null;
String password = null;
System.out.println("\nPlease set the admin credentials for this web application (will be required when browsing to the web application)");
Console console = System.console();
// Read the credentials from the user console:
// Note:
// Console supports password masking, but is not supported in IDEs such as eclipse;
// thus if in IDE (where console == null) use scanner instead:
if (console == null) {
// Use scanner:
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.print("Username: ");
username = scanner.nextLine();
System.out.print("Password: ");
password = scanner.nextLine();
System.out.print("Confirm Password: ");
String inputPasswordConfirm = scanner.nextLine();
if (username.isEmpty()) {
System.out.println("Error: user must be set - please try again");
} else if (password.isEmpty()) {
System.out.println("Error: password must be set - please try again");
} else if (!password.equals(inputPasswordConfirm)) {
System.out.println("Error: password and password confirm do not match - please try again");
} else {
log.info("Setting the in-memory security using the provided credentials...");
break;
}
System.out.println("");
}
scanner.close();
} else {
// Use Console
while (true) {
username = console.readLine("Username: ");
char[] passwordChars = console.readPassword("Password: ");
password = String.valueOf(passwordChars);
char[] passwordConfirmChars = console.readPassword("Confirm Password: ");
String passwordConfirm = String.valueOf(passwordConfirmChars);
if (username.isEmpty()) {
System.out.println("Error: Username must be set - please try again");
} else if (password.isEmpty()) {
System.out.println("Error: Password must be set - please try again");
} else if (!password.equals(passwordConfirm)) {
System.out.println("Error: Password and Password Confirm do not match - please try again");
} else {
log.info("Setting the in-memory security using the provided credentials...");
break;
}
System.out.println("");
}
}
// Set the inMemoryAuthentication object with the given credentials:
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
if (username != null && password != null) {
String encodedPassword = passwordEncoder().encode(password);
manager.createUser(User.withUsername(username).password(encodedPassword).roles("USER").build());
}
return manager;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Addition to accepted answer -
If password not seen in logs, enable "org.springframework.boot.autoconfigure.security" logs.
If you fine-tune your logging configuration, ensure that the org.springframework.boot.autoconfigure.security category is set to log INFO messages, otherwise the default password will not be printed.
https://docs.spring.io/spring-boot/docs/1.4.0.RELEASE/reference/htmlsingle/#boot-features-security
For a start simply add the following to your application.properties file
spring.security.user.name=user
spring.security.user.password=pass
NB: with no double quote
Run your application and enter the credentials (user, pass)
As of Spring Security version 5.7.1, the default username is user
and the password is randomly generated and displayed in the console (e.g. 8e557245-73e2-4286-969a-ff57fe326336
).
Please see the documentation for further details:
https://docs.spring.io/spring-security/reference/servlet/getting-started.html
When I started learning Spring Security, then I overrided the method userDetailsService() as in below code snippet:
@Configuration
@EnableWebSecurity
public class ApplicationSecurityConfiguration extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/", "/index").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
}
@Override
@Bean
public UserDetailsService userDetailsService() {
List<UserDetails> users= new ArrayList<UserDetails>();
users.add(User.withDefaultPasswordEncoder().username("admin").password("nimda").roles("USER","ADMIN").build());
users.add(User.withDefaultPasswordEncoder().username("Spring").password("Security").roles("USER").build());
return new InMemoryUserDetailsManager(users);
}
}
So we can log in to the application using the above-mentioned creds. (e.g. admin/nimda)
Note: This we should not use in production.
Try to take username and password from below code snipet in your project and login and hope this will work.
@Override
@Bean
public UserDetailsService userDetailsService() {
List<UserDetails> users= new ArrayList<UserDetails>();
users.add(User.withDefaultPasswordEncoder().username("admin").password("admin").roles("USER","ADMIN").build());
users.add(User.withDefaultPasswordEncoder().username("spring").password("spring").roles("USER").build());
return new UserDetailsManager(users);
}
Success story sharing
org.springframework.boot.autoconfigure.security
category is set to log INFO messages, otherwise the default password will not be printed.