What is username and password when starting Spring Boot with Tomcat? - java

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=<>

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

Related

Spring Security log in working locally but not on live site

My application is structured with Java and Spring Security. I have two ways to log in, one is using windows log in (aka active directory), the other is using a password created by an admin user. Both of these are working when I run locally through IntelliJ but when I deploy the app to the server, it only lets people using windows login credentials log in. If you try to log in with a custom made login on the live site, it just refreshes the login page and removes the entered username and password. I am not getting any errors. Also, when a user admin creates the custom log in, it is stored in a sql table, with the password hashed. So the create function works/user exists, just logging in is not working. Any idea what might be the cause... Not sure if I should be looking at the code or the server connection. I use Tomcat and IIS to host this site.
Web Config File
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Value("${ad.hg.url}")
private String AD_HG_URL;
#Value("${ad.hp.nt.url}")
private String AD_HP_NT_URL;
#Autowired
DBAuthorizationFetcher dbAuthorizationFetcher;
#Autowired
ManualUserDetailsService manualUserDetailsService;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().ignoringAntMatchers("/specialSplit/**");
http.authorizeRequests()
.antMatchers("/css/**","/js/**","/images/**","/login","/accessDenied","/loginFailed","/changePassword","/resetPassword").permitAll()
.antMatchers("/newClient","/callLogs/**","/addClient","/saveClient","/delete/**","/save/**","/specialSplit/**").hasRole("OLIDB_ADMIN")
.antMatchers("/admin","/toggle/user/**").hasRole("USER_ADMIN")
.anyRequest().hasRole("OLIDB_USER").and()
.formLogin().loginPage("/login").failureHandler(new CustomAuthenticationFailureHandler()).successForwardUrl("/")
.and().exceptionHandling().accessDeniedPage("/accessDenied")
.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/");
}
#Override
protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
//authManagerBuilder.authenticationProvider(databaseAuthenticationProvider);
authManagerBuilder.authenticationProvider(activeDirectoryLdapAuthenticationProvider("HEFFGROUP.COM",AD_HP_NT_URL));
authManagerBuilder.authenticationProvider(activeDirectoryLdapAuthenticationProvider("HG",AD_HG_URL));
authManagerBuilder.authenticationProvider(manualAuthenticationProvider());
}
public AuthenticationProvider activeDirectoryLdapAuthenticationProvider(String domain,String url) {
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(domain, url);
provider.setConvertSubErrorCodesToExceptions(true);
provider.setUseAuthenticationRequestCredentials(true);
provider.setUserDetailsContextMapper(dbAuthorizationFetcher);
return provider;
}
public DaoAuthenticationProvider manualAuthenticationProvider() {
DaoAuthenticationProvider authProvider
= new DaoAuthenticationProvider();
authProvider.setUserDetailsService(manualUserDetailsService);
authProvider.setPasswordEncoder(new BCryptPasswordEncoder(11));
return authProvider;
}
}

Spring security custom UserDetails not authenticating

while experimenting around with spring boot, security, and data.
i just came across this scenario:
i use H2 in memory DB and poblate it with one user with liquibase on startup
with username and password.
now i want spring security to authenticate against H2. for that purpose i have this code:
#Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsServiceImp);
}
and im implementing the userDetails as follows:
#Override
public UserDetails loadUserByUsername(String username) {
//this works, the user with pass is pulled
com.fix.demo.logic.user.User byUsername =
userRepository.findByUsername(username);
if (byUsername == null) {
System.out.println("No user found with username: ");
return null; //trow ex here
}
User user = new User(byUsername.getUsername(),
byUsername.getPassword(), true, true,
true, true, getAuthorities(Collections.singletonList("user")));
//System.out.println(user.toString());
//System.out.println(byUsername.toString()+ " "+byUsername.getPassword());
return user;
}
but my tests keep failing with
Authentication should not be null
and trying to log in will give me
bad credentials
what is necessary for my custom implementation of UserDetailsService to work?
this is the failing test:
#Test
public void loginWithValidUserThenAuthenticated() throws Exception {
FormLoginRequestBuilder login = formLogin()
.user("admin")
.password("root");
mockMvc.perform(login)
.andExpect(authenticated().withUsername("admin"));
}
One of the reasons is, the password might my encoded and you need to tell spring security to use an encoder. Add the following line to the configure override.
auth.setPasswordEncoder(passwordEncoder());
define the passwordEncoder bean.
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

Getting multiple users for basic auth, spring boot security

I have a list of users, and I want to use them in my basic auth.
MY code currently looks like this:
#Configuration
#EnableWebSecurity
public class BasicAuthConfig extends WebSecurityConfigurerAdapter {
#Bean
public PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}
#Autowired
private ConfigService configService;
// Authentication : User --> Roles
// NoOpPasswordEncoder has been deprecated in Spring security so {noop} is being used to avoid errors
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().passwordEncoder(passwordEncoder())
.withUser("someuser")
.password("somepassword")
.roles("USER");
}
// Authorization : Role -> Access
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and().authorizeRequests()
.antMatchers("/actuator/**")
.permitAll()
.antMatchers("/tokenservice/**")
.hasRole("USER")
.antMatchers("/")
.permitAll()
.and().csrf()
.disable()
.headers()
.frameOptions()
.and().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}}
I want to replace "someuser" and "somepassword" with usernames and passwords from my list of users. Currently I can get the list with configService.getCOnfigurations().getUsers().
A user just has a username and a password, both strings. How do I go about getting all the usernames and all the passwords into .withUser()?
**EDIT
I made a simple for loop in the configure, that should do it, but whenever i try to post to my API, it says org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder:99 - Encoded password does not look like BCrypt
I used an online bcrypt generator to generate the passwords, and they look like this
<?xml version="1.0" encoding="UTF-8"?>
<Configurations>
<Port>8007</Port>
<EnableHttps>true</EnableHttps>
<KeyStorePath>classpath:ssl-server.jks</KeyStorePath>
<KeyPass>changeit</KeyPass>
<TokenTtlMillis>15000</TokenTtlMillis>
<Users Username="user1">
<Password>$2y$10$.8VQR6tJub5uVdVLByItQO8QYGZVuWPhLuBUTQSDJAvVpLAUmuqZ2</Password>
</Users>
<Users Username="user2">
<Password>$2y$10$r/CQz7PZp5banmSzr9OiDe2Kxrda4BhXIBXvvouRnm1w3M72wLQj.</Password>
</Users>
</Configurations>
the passwords are in plain just password and password2
Building on Claudio's answer with the DaoAuthenticationProvider:
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService());
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
#Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(userDetailsService())
.authenticationProvider(authenticationProvider());
}
#Override
protected UserDetailsService userDetailsService() {
return new MyUserDetailsService();
}
The UserDetailsService is where the real meat of your code would be. You would provide a custom implementation of the interface that reads from your XML. Assuming that you have a method getPassword(String username):
// Adding this import to demontrate where "User" is coming from
import org.springframework.security.core.userdetails.User;
public class MyUserDetailsService implements UserDetailsService {
#Override
public User loadUserByUsername(String username) {
return new User(username, getPassword(username), Arrays.asList(new SimpleGrantedAuthority("USER")));
}
private String getPassword(String username) {
// Get password from your XML
}
}
As for your BCrypt issue, the password hash gives me an invalid salt revision error. Try using your app directly to hash it, e.g.:
public static void main(String[] args) {
System.out.println(new BCryptPasswordEncoder().encode("password"));
}
Or to pass in a file with a password on each line (using Java 8):
public static void main(String[] args) throws IOException {
if (args.length != 1) {
System.out.println("Requires 1 parameter that points to a file.");
System.exit(1);
}
File f = new File(args[0]);
if (!f.isFile()) {
System.out.println("Not a file: " + f);
System.exit(1);
}
PasswordEncoder encoder = new BCryptPasswordEncoder();
try (Stream<String> lines = Files.lines(f.toPath())) {
lines.map(encoder::encode)
.forEach(System.out::println);
}
}
That will give you the Spring-generated hashes which you can then insert into your XML.
You can declare a DaoAuthentificationProvider in your WebSecurityConfigurerAdapter like this:
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService());
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
and give it your implementation of a passwordEncoder and a userDetailsService,
for which you have to implement the respective interfaces and their methods.
And then you can assign your authenticationProvider in your WebSecurityConfigurerAdapter class like this:
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService());
auth.authenticationProvider(authenticationProvider());
}
This way, your UserDetailService will provide all the available users and their credentials and you don't have to worry about that in the security configuration.
This way you can store the credentials in whatever way you want (simple file, nosql DB like MongoDB, etc.) and even change that implementation without impact on the way you authenticate with spring security.
Your UserDetailService should look somewhat like this:
public class SecUserDetailsService implements UserDetailsService {
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository().findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
} else {
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
grantedAuthorities.add(new SimpleGrantedAuthority(user.getRole().getName()));
return new org.springframework.security.core.userdetails.User(user.getName(), user.getPassword(),
grantedAuthorities);
}
}
}
Here I've used a UserRepository that takes care of loading all users from the storage of your choice. E.g. if you decide to store it in a file, it will load all users and their passwords from a file, and provide the method findByUsername that gives back the User object if one with a matching name is found. Your Repository can also take care of deleting users or modifying their names if needed.
I implemented this on spring boot 2.x, with getting users credentials from the console on server start; you can easily change it to load users from file or any other source:
#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();
}
}

Usage of Spring Security in console Java Application

I'm building a simple console application which uses nice stack of frameworks(Hibernate, Spring), but found myself struggling with auth/reg issues. Usually for web projects I would use Spring Security framework, restrict some URL add configure login page which is completely processed by the framework automatically. But my console application contains 2 issues:
Storing encoded passwords in a database
Using User Service to configure Spring to work with my database
1st problem can be solved using some password encoder and specifying it in a spring-security configuration file like this
<beans:bean class="myconsoleapp.util.PasswordUtil" id="passwordEncoder" factory-method="getPasswordEncoder"/>
and later specify encoder in authentication manager
<authentication-manager>
<authentication-provider user-service-ref="userService">
<password-encoder ref="passwordEncoder"/>
</authentication-provider>
</authentication-manager>
2nd problem seems to be more complex. In my service class I've implemented UserDetailsService spring security interface and have overridden loadUserByUsername method like this
#Service("userService")
public class UserServiceImpl implements UserService, UserDetailsService {
public AuthorizedUser loadUserByUsername(String email) throws UsernameNotFoundException {
User user = repository.getByEmail(email.toLowerCase());
return new AuthorizedUser(user);
}
}
And my AuthorizedUser class has a constructor like this
public class AuthorizedUser extends org.springframework.security.core.userdetails.User {
private User user;
public AuthorizedUser(User user) {
super(user.getEmail(), user.getPassword(), user.isEnabled(), true, true, true, user.getRoles());
this.user= user;
}
}
Finally we're close to the question.. How can I use all that stuff providing email and password input from the console?? I see it like that:
System.out.println("Enter email:");
String userEmail = inputStream.readLine();
System.out.println("Enter your password");
String userPasspord = inputStream.readLine();
userService.//<-What method should I use here?
Given that you can access the authentication manager bean, you can check the credentials something like this:
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userEmail, userPassword);
try {
authenticationManager.authenticate(token);
System.out.println("Login successful!");
} catch (BadCredentialsException e) {
System.out.println("Bad credentials!");
}

How to authenticate user manually in spring boot?

I have two tables 'user' and 'role'.I want to create a login api (e.g '/login') which will take username and password as a json data. I want to check if given credential is a valid credential and if it is,then I want to set the user as authenticated user so that he/she may have the protected resources. I am new to spring boot framework and I don't know how to do so.I have read the offical documentation but cannot find any resources.Could someone help me on this?
You have number of choices to implement such authentication in Spring.
Case 1:- If you are building REST services then you can implement security in following ways:
i) - you can use Basic-Authentication to authenticate your user.
ii) - you can use OAuth2 to authenticate and authorize your user.
Case 2: If you are building web application
i) - you can use auth token (in case of Single page application SPA)
ii) - you can use session based authentication (traditional login form and all)
I Guess you are in beginner mode so i will recommend you to firstly understand the control flow user authentication in web app via login form. So Let's go through some code.
I'm assuming that you have set a basic spring project and now you are implementing security.
USER - Hibernate entity for your user table;
ROLE - Hibernate entity for your role table
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private CustomAuthProvider customAuthProvider;
#Override
protected void configure(HttpSecurity http) throws Exception {
// everyone is allowed tp view login page
http.authorizeRequests().antMatchers("/login").permitAll().and();
http.authorizeRequests().antMatchers("custom_base_path" + "**").authenticated().and().
formLogin().loginPage("/loginForm).loginProcessingUrl("/loginUser")
.usernameParameter("username").passwordParameter("password")
.defaultSuccessUrl("custom_base_path+ "home", true);
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthProvider);
}
//CustomAuthProvider
#Component
public class CustomAuthentiationProvider implements AuthenticationProvider{
#Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String userid = authentication.getName();
String password = authentication.getCredentials().toString();
Authentication auth = null;
try {
//write your custom logic to match username, password
boolean userExists = your_method_that_checks_username_and_password
if(userExists ){
List<Role> roleList= roleDao.getRoleList(userid);
if (roleList == null || roleList.isEmpty()) {
throw new NoRoleAssignedException("No roles is assigned to "+userid);
}
auth = new UsernamePasswordAuthenticationToken(userid, password,getGrantedAuthorities(roleList));
}
} catch (Exception e) {
log.error("error", e);
}
return auth;
}
#Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
public List<GrantedAuthority> getGrantedAuthorities(List<Role> roleList) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (Role role : roleList) {
authorities.add(new SimpleGrantedAuthority(role.getRoleName());
}
return authorities;
}
}
NOTE: Please consider these codes to understand the logic of authentication. don't consider as perfect code(Not for production env.). You can ping me anytime i'll suggest you more about that.

Categories