BAEL-5638: Added display logged-in user details in Thymeleaf tutorial (#12524)
* BAEL-5638: Added display logged-in user details in Thymeleaf tutorial * BAEL-5638: Removed unneeded security config
This commit is contained in:
		
							parent
							
								
									8ec8c01a67
								
							
						
					
					
						commit
						81b05fb3ac
					
				| @ -0,0 +1,94 @@ | ||||
| package com.baeldung.customuserdetails; | ||||
| 
 | ||||
| import org.springframework.security.core.GrantedAuthority; | ||||
| import org.springframework.security.core.userdetails.User; | ||||
| 
 | ||||
| import java.util.Collection; | ||||
| import java.util.Objects; | ||||
| 
 | ||||
| public class CustomUserDetails extends User { | ||||
| 
 | ||||
|     private final String firstName; | ||||
|     private final String lastName; | ||||
|     private final String email; | ||||
| 
 | ||||
|     private CustomUserDetails(Builder builder) { | ||||
|         super(builder.username, builder.password, builder.authorities); | ||||
|         this.firstName = builder.firstName; | ||||
|         this.lastName = builder.lastName; | ||||
|         this.email = builder.email; | ||||
|     } | ||||
| 
 | ||||
|     public String getLastName() { | ||||
|         return this.lastName; | ||||
|     } | ||||
| 
 | ||||
|     public String getFirstName() { | ||||
|         return this.firstName; | ||||
|     } | ||||
| 
 | ||||
|     public String getEmail() { | ||||
|         return email; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean equals(Object o) { | ||||
|         if (this == o) | ||||
|             return true; | ||||
|         if (o == null || getClass() != o.getClass()) | ||||
|             return false; | ||||
|         if (!super.equals(o)) | ||||
|             return false; | ||||
|         CustomUserDetails that = (CustomUserDetails) o; | ||||
|         return firstName.equals(that.firstName) && lastName.equals(that.lastName) && email.equals(that.email); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int hashCode() { | ||||
|         return Objects.hash(super.hashCode(), firstName, lastName, email); | ||||
|     } | ||||
| 
 | ||||
|     public static class Builder { | ||||
| 
 | ||||
|         private String firstName; | ||||
|         private String lastName; | ||||
|         private String email; | ||||
|         private String username; | ||||
|         private String password; | ||||
|         private Collection<? extends GrantedAuthority> authorities; | ||||
| 
 | ||||
|         public Builder withFirstName(String firstName) { | ||||
|             this.firstName = firstName; | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         public Builder withLastName(String lastName) { | ||||
|             this.lastName = lastName; | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         public Builder withEmail(String email) { | ||||
|             this.email = email; | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         public Builder withUsername(String username) { | ||||
|             this.username = username; | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         public Builder withPassword(String password) { | ||||
|             this.password = password; | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         public Builder withAuthorities(Collection<? extends GrantedAuthority> authorities) { | ||||
|             this.authorities = authorities; | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         public CustomUserDetails build() { | ||||
|             return new CustomUserDetails(this); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,52 @@ | ||||
| package com.baeldung.customuserdetails; | ||||
| 
 | ||||
| import org.springframework.security.core.authority.SimpleGrantedAuthority; | ||||
| import org.springframework.security.core.userdetails.UserDetails; | ||||
| import org.springframework.security.core.userdetails.UserDetailsService; | ||||
| import org.springframework.security.core.userdetails.UsernameNotFoundException; | ||||
| import org.springframework.security.crypto.password.PasswordEncoder; | ||||
| import org.springframework.stereotype.Service; | ||||
| 
 | ||||
| import javax.annotation.PostConstruct; | ||||
| 
 | ||||
| import java.util.Collections; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| @Service | ||||
| public class CustomUserDetailsService implements UserDetailsService { | ||||
| 
 | ||||
|     private final PasswordEncoder passwordEncoder; | ||||
|     private final Map<String, CustomUserDetails> userRegistry = new HashMap<>(); | ||||
| 
 | ||||
|     public CustomUserDetailsService(PasswordEncoder passwordEncoder) { | ||||
|         this.passwordEncoder = passwordEncoder; | ||||
|     } | ||||
| 
 | ||||
|     @PostConstruct | ||||
|     public void init() { | ||||
|         userRegistry.put("user", new CustomUserDetails.Builder().withFirstName("Mark") | ||||
|             .withLastName("Johnson") | ||||
|             .withEmail("mark.johnson@email.com") | ||||
|             .withUsername("user") | ||||
|             .withPassword(passwordEncoder.encode("password")) | ||||
|             .withAuthorities(Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER"))) | ||||
|             .build()); | ||||
|         userRegistry.put("admin", new CustomUserDetails.Builder().withFirstName("James") | ||||
|             .withLastName("Davis") | ||||
|             .withEmail("james.davis@email.com") | ||||
|             .withUsername("admin") | ||||
|             .withPassword(passwordEncoder.encode("admin")) | ||||
|             .withAuthorities(Collections.singletonList(new SimpleGrantedAuthority("ROLE_ADMIN"))) | ||||
|             .build()); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { | ||||
|         final CustomUserDetails userDetails = userRegistry.get(username); | ||||
|         if (userDetails == null) { | ||||
|             throw new UsernameNotFoundException(username); | ||||
|         } | ||||
|         return userDetails; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,15 @@ | ||||
| package com.baeldung.customuserdetails; | ||||
| 
 | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | ||||
| import org.springframework.security.crypto.password.PasswordEncoder; | ||||
| 
 | ||||
| @Configuration | ||||
| public class PasswordEncoderConfiguration { | ||||
| 
 | ||||
|     @Bean | ||||
|     public PasswordEncoder passwordEncoder() { | ||||
|         return new BCryptPasswordEncoder(); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,38 @@ | ||||
| package com.baeldung.customuserdetails; | ||||
| 
 | ||||
| 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.UserDetailsService; | ||||
| import org.springframework.security.web.util.matcher.AntPathRequestMatcher; | ||||
| 
 | ||||
| @Configuration | ||||
| @EnableWebSecurity | ||||
| public class SecurityConfiguration extends WebSecurityConfigurerAdapter { | ||||
| 
 | ||||
|     private final UserDetailsService userDetailsService; | ||||
| 
 | ||||
|     public SecurityConfiguration(UserDetailsService userDetailsService) { | ||||
|         this.userDetailsService = userDetailsService; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected void configure(HttpSecurity http) throws Exception { | ||||
|         http.userDetailsService(userDetailsService) | ||||
|             .authorizeRequests() | ||||
|             .anyRequest() | ||||
|             .authenticated() | ||||
|             .and() | ||||
|             .formLogin() | ||||
|             .loginPage("/login") | ||||
|             .permitAll() | ||||
|             .successForwardUrl("/index") | ||||
|             .and() | ||||
|             .logout() | ||||
|             .permitAll() | ||||
|             .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) | ||||
|             .logoutSuccessUrl("/login"); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,12 @@ | ||||
| package com.baeldung.customuserdetails; | ||||
| 
 | ||||
| import org.springframework.boot.SpringApplication; | ||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
| 
 | ||||
| @SpringBootApplication | ||||
| public class SpringSecurityThymeleafApplication { | ||||
| 
 | ||||
|     public static void main(String[] args) { | ||||
|         SpringApplication.run(SpringSecurityThymeleafApplication.class, args); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,21 @@ | ||||
| package com.baeldung.customuserdetails; | ||||
| 
 | ||||
| import org.springframework.security.core.Authentication; | ||||
| import org.springframework.security.core.context.SecurityContextHolder; | ||||
| import org.springframework.stereotype.Controller; | ||||
| import org.springframework.web.bind.annotation.RequestMapping; | ||||
| 
 | ||||
| @Controller | ||||
| public class ViewController { | ||||
| 
 | ||||
|     @RequestMapping("/login") | ||||
|     public String login() { | ||||
|         return "login"; | ||||
|     } | ||||
| 
 | ||||
|     @RequestMapping({ "/index", "/" }) | ||||
|     public String index() { | ||||
|         Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); | ||||
|         return "userdetails"; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,25 @@ | ||||
| <!DOCTYPE html> | ||||
| <html xmlns:sec="http://www.thymeleaf.org/extras/spring-security"> | ||||
| <head> | ||||
| <title>Welcome to Spring Security Thymeleaf tutorial</title> | ||||
| </head> | ||||
| <body> | ||||
| 	<h2>Welcome</h2> | ||||
| 	<p>Spring Security Thymeleaf tutorial</p> | ||||
| 	<div sec:authorize="hasRole('USER')">Text visible to user.</div> | ||||
| 	<div sec:authorize="hasRole('ADMIN')">Text visible to admin.</div> | ||||
| 	<div sec:authorize="isAuthenticated()">Text visible only to | ||||
| 		authenticated users.</div> | ||||
| 	Authenticated username: | ||||
| 	<div sec:authentication="name"></div> | ||||
| 	Authenticated user's firstName: | ||||
| 	<div sec:authentication="principal.firstName"></div> | ||||
| 	Authenticated user's lastName: | ||||
| 	<div sec:authentication="principal.lastName"></div> | ||||
| 	Authenticated user's email: | ||||
| 	<div sec:authentication="principal.email"></div> | ||||
| 	Authenticated user roles: | ||||
| 	<div sec:authentication="principal.authorities"></div> | ||||
| 
 | ||||
| </body> | ||||
| </html> | ||||
| @ -0,0 +1,29 @@ | ||||
| package com.baeldung.customuserdetails; | ||||
| 
 | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.boot.test.context.SpringBootTest; | ||||
| import org.springframework.test.context.junit4.SpringRunner; | ||||
| import org.springframework.web.context.WebApplicationContext; | ||||
| 
 | ||||
| import static org.junit.Assert.assertNotNull; | ||||
| 
 | ||||
| import com.baeldung.customuserdetails.ViewController; | ||||
| 
 | ||||
| @RunWith(SpringRunner.class) | ||||
| @SpringBootTest | ||||
| public class SpringSecurityThymeleafApplicationIntegrationTest { | ||||
| 
 | ||||
| 	@Autowired | ||||
|     ViewController viewController; | ||||
| 	@Autowired | ||||
| 	WebApplicationContext wac; | ||||
| 	 | ||||
| 	@Test | ||||
| 	public void whenConfigured_thenLoadsContext() { | ||||
| 		assertNotNull(viewController); | ||||
| 		assertNotNull(wac); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,42 @@ | ||||
| package com.baeldung.customuserdetails; | ||||
| 
 | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; | ||||
| import org.springframework.context.annotation.Import; | ||||
| import org.springframework.test.context.junit4.SpringRunner; | ||||
| import org.springframework.test.web.servlet.MockMvc; | ||||
| import org.springframework.test.web.servlet.setup.MockMvcBuilders; | ||||
| import org.springframework.web.context.WebApplicationContext; | ||||
| 
 | ||||
| import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; | ||||
| import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; | ||||
| import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||||
| import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; | ||||
| 
 | ||||
| import com.baeldung.customuserdetails.PasswordEncoderConfiguration; | ||||
| 
 | ||||
| @RunWith(SpringRunner.class) | ||||
| @WebMvcTest | ||||
| @Import(PasswordEncoderConfiguration.class) | ||||
| public class ViewControllerIntegrationTest { | ||||
| 
 | ||||
| 	@Autowired | ||||
| 	private WebApplicationContext context; | ||||
| 	MockMvc mvc; | ||||
| 
 | ||||
| 	@Before | ||||
| 	public void setup() { | ||||
| 		mvc = MockMvcBuilders | ||||
| 				.webAppContextSetup(context) | ||||
| 				.build(); | ||||
| 	} | ||||
| 	 | ||||
| 	@Test | ||||
| 	public void givenUser_whenPerformingGet_thenReturnsIndex() throws Exception { | ||||
| 		mvc.perform(get("/index").with(user("user").password("password"))).andExpect(status().isOk()).andExpect(view().name("userdetails")); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user