JAVA-8360 Split or move spring-5-security module
This commit is contained in:
parent
9759513bf9
commit
bacd580822
@ -4,7 +4,6 @@ This module contains articles about Spring Security 5
|
|||||||
|
|
||||||
## Relevant articles:
|
## Relevant articles:
|
||||||
|
|
||||||
- [Extra Login Fields with Spring Security](https://www.baeldung.com/spring-security-extra-login-fields)
|
|
||||||
- [A Custom Spring SecurityConfigurer](https://www.baeldung.com/spring-security-custom-configurer)
|
- [A Custom Spring SecurityConfigurer](https://www.baeldung.com/spring-security-custom-configurer)
|
||||||
- [New Password Storage In Spring Security 5](https://www.baeldung.com/spring-security-5-password-storage)
|
- [New Password Storage In Spring Security 5](https://www.baeldung.com/spring-security-5-password-storage)
|
||||||
- [Default Password Encoder in Spring Security 5](https://www.baeldung.com/spring-security-5-default-password-encoder)
|
- [Default Password Encoder in Spring Security 5](https://www.baeldung.com/spring-security-5-default-password-encoder)
|
||||||
|
@ -12,6 +12,7 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com
|
|||||||
- [Spring Security – Customize the 403 Forbidden/Access Denied Page](https://www.baeldung.com/spring-security-custom-access-denied-page)
|
- [Spring Security – Customize the 403 Forbidden/Access Denied Page](https://www.baeldung.com/spring-security-custom-access-denied-page)
|
||||||
- [Spring Security – Redirect to the Previous URL After Login](https://www.baeldung.com/spring-security-redirect-login)
|
- [Spring Security – Redirect to the Previous URL After Login](https://www.baeldung.com/spring-security-redirect-login)
|
||||||
- [Spring Security Custom AuthenticationFailureHandler](https://www.baeldung.com/spring-security-custom-authentication-failure-handler)
|
- [Spring Security Custom AuthenticationFailureHandler](https://www.baeldung.com/spring-security-custom-authentication-failure-handler)
|
||||||
|
- [Extra Login Fields with Spring Security](https://www.baeldung.com/spring-security-extra-login-fields)
|
||||||
|
|
||||||
### Build the Project
|
### Build the Project
|
||||||
```
|
```
|
||||||
|
@ -16,6 +16,26 @@
|
|||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.thymeleaf.extras</groupId>
|
||||||
|
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||||
|
<version>${thymeleaf-extras-springsecurity5.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- Spring Security -->
|
<!-- Spring Security -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.security</groupId>
|
<groupId>org.springframework.security</groupId>
|
||||||
@ -98,6 +118,12 @@
|
|||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- test scoped -->
|
<!-- test scoped -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-test</artifactId>
|
<artifactId>spring-test</artifactId>
|
||||||
@ -110,6 +136,11 @@
|
|||||||
<version>${spring-security.version}</version>
|
<version>${spring-security.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>${commons-lang3.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@ -153,6 +184,9 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<!-- Maven plugins -->
|
<!-- Maven plugins -->
|
||||||
<cargo-maven3-plugin.version>1.9.9</cargo-maven3-plugin.version>
|
<cargo-maven3-plugin.version>1.9.9</cargo-maven3-plugin.version>
|
||||||
|
<spring-boot.version>2.6.4</spring-boot.version>
|
||||||
|
<thymeleaf-extras-springsecurity5.version>3.0.4.RELEASE</thymeleaf-extras-springsecurity5.version>
|
||||||
|
<commons-lang3.version>3.11</commons-lang3.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
@ -1,50 +1,50 @@
|
|||||||
package com.baeldung.loginextrafieldscustom;
|
package com.baeldung.loginextrafieldscustom;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
import org.springframework.security.core.AuthenticationException;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
|
||||||
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
|
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
|
||||||
|
|
||||||
public static final String SPRING_SECURITY_FORM_DOMAIN_KEY = "domain";
|
public static final String SPRING_SECURITY_FORM_DOMAIN_KEY = "domain";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
|
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws AuthenticationException {
|
throws AuthenticationException {
|
||||||
|
|
||||||
if (!request.getMethod().equals("POST")) {
|
if (!request.getMethod().equals("POST")) {
|
||||||
throw new AuthenticationServiceException("Authentication method not supported: "
|
throw new AuthenticationServiceException("Authentication method not supported: "
|
||||||
+ request.getMethod());
|
+ request.getMethod());
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomAuthenticationToken authRequest = getAuthRequest(request);
|
CustomAuthenticationToken authRequest = getAuthRequest(request);
|
||||||
setDetails(request, authRequest);
|
setDetails(request, authRequest);
|
||||||
return this.getAuthenticationManager().authenticate(authRequest);
|
return this.getAuthenticationManager().authenticate(authRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CustomAuthenticationToken getAuthRequest(HttpServletRequest request) {
|
private CustomAuthenticationToken getAuthRequest(HttpServletRequest request) {
|
||||||
String username = obtainUsername(request);
|
String username = obtainUsername(request);
|
||||||
String password = obtainPassword(request);
|
String password = obtainPassword(request);
|
||||||
String domain = obtainDomain(request);
|
String domain = obtainDomain(request);
|
||||||
|
|
||||||
if (username == null) {
|
if (username == null) {
|
||||||
username = "";
|
username = "";
|
||||||
}
|
}
|
||||||
if (password == null) {
|
if (password == null) {
|
||||||
password = "";
|
password = "";
|
||||||
}
|
}
|
||||||
if (domain == null) {
|
if (domain == null) {
|
||||||
domain = "";
|
domain = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CustomAuthenticationToken(username, password, domain);
|
return new CustomAuthenticationToken(username, password, domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String obtainDomain(HttpServletRequest request) {
|
private String obtainDomain(HttpServletRequest request) {
|
||||||
return request.getParameter(SPRING_SECURITY_FORM_DOMAIN_KEY);
|
return request.getParameter(SPRING_SECURITY_FORM_DOMAIN_KEY);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,28 +1,28 @@
|
|||||||
package com.baeldung.loginextrafieldscustom;
|
package com.baeldung.loginextrafieldscustom;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
|
||||||
public class CustomAuthenticationToken extends UsernamePasswordAuthenticationToken {
|
public class CustomAuthenticationToken extends UsernamePasswordAuthenticationToken {
|
||||||
|
|
||||||
private String domain;
|
private String domain;
|
||||||
|
|
||||||
public CustomAuthenticationToken(Object principal, Object credentials, String domain) {
|
public CustomAuthenticationToken(Object principal, Object credentials, String domain) {
|
||||||
super(principal, credentials);
|
super(principal, credentials);
|
||||||
this.domain = domain;
|
this.domain = domain;
|
||||||
super.setAuthenticated(false);
|
super.setAuthenticated(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CustomAuthenticationToken(Object principal, Object credentials, String domain,
|
public CustomAuthenticationToken(Object principal, Object credentials, String domain,
|
||||||
Collection<? extends GrantedAuthority> authorities) {
|
Collection<? extends GrantedAuthority> authorities) {
|
||||||
super(principal, credentials, authorities);
|
super(principal, credentials, authorities);
|
||||||
this.domain = domain;
|
this.domain = domain;
|
||||||
super.setAuthenticated(true); // must use super, as we override
|
super.setAuthenticated(true); // must use super, as we override
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDomain() {
|
public String getDomain() {
|
||||||
return this.domain;
|
return this.domain;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,92 +1,92 @@
|
|||||||
package com.baeldung.loginextrafieldscustom;
|
package com.baeldung.loginextrafieldscustom;
|
||||||
|
|
||||||
import org.springframework.security.authentication.BadCredentialsException;
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
import org.springframework.security.authentication.InternalAuthenticationServiceException;
|
import org.springframework.security.authentication.InternalAuthenticationServiceException;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
|
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
import org.springframework.security.core.AuthenticationException;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
public class CustomUserDetailsAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
|
public class CustomUserDetailsAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The plaintext password used to perform
|
* The plaintext password used to perform
|
||||||
* PasswordEncoder#matches(CharSequence, String)} on when the user is
|
* PasswordEncoder#matches(CharSequence, String)} on when the user is
|
||||||
* not found to avoid SEC-2056.
|
* not found to avoid SEC-2056.
|
||||||
*/
|
*/
|
||||||
private static final String USER_NOT_FOUND_PASSWORD = "userNotFoundPassword";
|
private static final String USER_NOT_FOUND_PASSWORD = "userNotFoundPassword";
|
||||||
|
|
||||||
private PasswordEncoder passwordEncoder;
|
private PasswordEncoder passwordEncoder;
|
||||||
private CustomUserDetailsService userDetailsService;
|
private CustomUserDetailsService userDetailsService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The password used to perform
|
* The password used to perform
|
||||||
* {@link PasswordEncoder#matches(CharSequence, String)} on when the user is
|
* {@link PasswordEncoder#matches(CharSequence, String)} on when the user is
|
||||||
* not found to avoid SEC-2056. This is necessary, because some
|
* not found to avoid SEC-2056. This is necessary, because some
|
||||||
* {@link PasswordEncoder} implementations will short circuit if the password is not
|
* {@link PasswordEncoder} implementations will short circuit if the password is not
|
||||||
* in a valid format.
|
* in a valid format.
|
||||||
*/
|
*/
|
||||||
private String userNotFoundEncodedPassword;
|
private String userNotFoundEncodedPassword;
|
||||||
|
|
||||||
public CustomUserDetailsAuthenticationProvider(PasswordEncoder passwordEncoder, CustomUserDetailsService userDetailsService) {
|
public CustomUserDetailsAuthenticationProvider(PasswordEncoder passwordEncoder, CustomUserDetailsService userDetailsService) {
|
||||||
this.passwordEncoder = passwordEncoder;
|
this.passwordEncoder = passwordEncoder;
|
||||||
this.userDetailsService = userDetailsService;
|
this.userDetailsService = userDetailsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication)
|
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication)
|
||||||
throws AuthenticationException {
|
throws AuthenticationException {
|
||||||
|
|
||||||
if (authentication.getCredentials() == null) {
|
if (authentication.getCredentials() == null) {
|
||||||
logger.debug("Authentication failed: no credentials provided");
|
logger.debug("Authentication failed: no credentials provided");
|
||||||
throw new BadCredentialsException(
|
throw new BadCredentialsException(
|
||||||
messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
|
messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
|
||||||
}
|
}
|
||||||
|
|
||||||
String presentedPassword = authentication.getCredentials()
|
String presentedPassword = authentication.getCredentials()
|
||||||
.toString();
|
.toString();
|
||||||
|
|
||||||
if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
|
if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
|
||||||
logger.debug("Authentication failed: password does not match stored value");
|
logger.debug("Authentication failed: password does not match stored value");
|
||||||
throw new BadCredentialsException(
|
throw new BadCredentialsException(
|
||||||
messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
|
messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doAfterPropertiesSet() throws Exception {
|
protected void doAfterPropertiesSet() throws Exception {
|
||||||
Assert.notNull(this.userDetailsService, "A UserDetailsService must be set");
|
Assert.notNull(this.userDetailsService, "A UserDetailsService must be set");
|
||||||
this.userNotFoundEncodedPassword = this.passwordEncoder.encode(USER_NOT_FOUND_PASSWORD);
|
this.userNotFoundEncodedPassword = this.passwordEncoder.encode(USER_NOT_FOUND_PASSWORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)
|
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)
|
||||||
throws AuthenticationException {
|
throws AuthenticationException {
|
||||||
CustomAuthenticationToken auth = (CustomAuthenticationToken) authentication;
|
CustomAuthenticationToken auth = (CustomAuthenticationToken) authentication;
|
||||||
UserDetails loadedUser;
|
UserDetails loadedUser;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
loadedUser = this.userDetailsService.loadUserByUsernameAndDomain(auth.getPrincipal()
|
loadedUser = this.userDetailsService.loadUserByUsernameAndDomain(auth.getPrincipal()
|
||||||
.toString(), auth.getDomain());
|
.toString(), auth.getDomain());
|
||||||
} catch (UsernameNotFoundException notFound) {
|
} catch (UsernameNotFoundException notFound) {
|
||||||
if (authentication.getCredentials() != null) {
|
if (authentication.getCredentials() != null) {
|
||||||
String presentedPassword = authentication.getCredentials()
|
String presentedPassword = authentication.getCredentials()
|
||||||
.toString();
|
.toString();
|
||||||
passwordEncoder.matches(presentedPassword, userNotFoundEncodedPassword);
|
passwordEncoder.matches(presentedPassword, userNotFoundEncodedPassword);
|
||||||
}
|
}
|
||||||
throw notFound;
|
throw notFound;
|
||||||
} catch (Exception repositoryProblem) {
|
} catch (Exception repositoryProblem) {
|
||||||
throw new InternalAuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem);
|
throw new InternalAuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadedUser == null) {
|
if (loadedUser == null) {
|
||||||
throw new InternalAuthenticationServiceException("UserDetailsService returned null, "
|
throw new InternalAuthenticationServiceException("UserDetailsService returned null, "
|
||||||
+ "which is an interface contract violation");
|
+ "which is an interface contract violation");
|
||||||
}
|
}
|
||||||
return loadedUser;
|
return loadedUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,10 +1,10 @@
|
|||||||
package com.baeldung.loginextrafieldscustom;
|
package com.baeldung.loginextrafieldscustom;
|
||||||
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
|
||||||
public interface CustomUserDetailsService {
|
public interface CustomUserDetailsService {
|
||||||
|
|
||||||
UserDetails loadUserByUsernameAndDomain(String username, String domain) throws UsernameNotFoundException;
|
UserDetails loadUserByUsernameAndDomain(String username, String domain) throws UsernameNotFoundException;
|
||||||
|
|
||||||
}
|
}
|
@ -1,30 +1,30 @@
|
|||||||
package com.baeldung.loginextrafieldscustom;
|
package com.baeldung.loginextrafieldscustom;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service("userDetailsService")
|
@Service("userDetailsService")
|
||||||
public class CustomUserDetailsServiceImpl implements CustomUserDetailsService {
|
public class CustomUserDetailsServiceImpl implements CustomUserDetailsService {
|
||||||
|
|
||||||
private UserRepository userRepository;
|
private UserRepository userRepository;
|
||||||
|
|
||||||
public CustomUserDetailsServiceImpl(UserRepository userRepository) {
|
public CustomUserDetailsServiceImpl(UserRepository userRepository) {
|
||||||
this.userRepository = userRepository;
|
this.userRepository = userRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserDetails loadUserByUsernameAndDomain(String username, String domain) throws UsernameNotFoundException {
|
public UserDetails loadUserByUsernameAndDomain(String username, String domain) throws UsernameNotFoundException {
|
||||||
if (StringUtils.isAnyBlank(username, domain)) {
|
if (StringUtils.isAnyBlank(username, domain)) {
|
||||||
throw new UsernameNotFoundException("Username and domain must be provided");
|
throw new UsernameNotFoundException("Username and domain must be provided");
|
||||||
}
|
}
|
||||||
User user = userRepository.findUser(username, domain);
|
User user = userRepository.findUser(username, domain);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new UsernameNotFoundException(
|
throw new UsernameNotFoundException(
|
||||||
String.format("Username not found for domain, username=%s, domain=%s",
|
String.format("Username not found for domain, username=%s, domain=%s",
|
||||||
username, domain));
|
username, domain));
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,33 +1,33 @@
|
|||||||
package com.baeldung.loginextrafieldscustom;
|
package com.baeldung.loginextrafieldscustom;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
@Repository("userRepository")
|
@Repository("userRepository")
|
||||||
public class CustomUserRepository implements UserRepository {
|
public class CustomUserRepository implements UserRepository {
|
||||||
|
|
||||||
private PasswordEncoder passwordEncoder;
|
private PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
public CustomUserRepository(PasswordEncoder passwordEncoder) {
|
public CustomUserRepository(PasswordEncoder passwordEncoder) {
|
||||||
this.passwordEncoder = passwordEncoder;
|
this.passwordEncoder = passwordEncoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public User findUser(String username, String domain) {
|
public User findUser(String username, String domain) {
|
||||||
if (StringUtils.isAnyBlank(username, domain)) {
|
if (StringUtils.isAnyBlank(username, domain)) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
Collection<? extends GrantedAuthority> authorities = new ArrayList<>();
|
Collection<? extends GrantedAuthority> authorities = new ArrayList<>();
|
||||||
User user = new User(username, domain,
|
User user = new User(username, domain,
|
||||||
passwordEncoder.encode("secret"), true,
|
passwordEncoder.encode("secret"), true,
|
||||||
true, true, true, authorities);
|
true, true, true, authorities);
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,63 +1,63 @@
|
|||||||
package com.baeldung.loginextrafieldscustom;
|
package com.baeldung.loginextrafieldscustom;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.PropertySource;
|
import org.springframework.context.annotation.PropertySource;
|
||||||
import org.springframework.security.authentication.AuthenticationProvider;
|
import org.springframework.security.authentication.AuthenticationProvider;
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
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.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
|
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@PropertySource("classpath:/application-extrafields.properties")
|
@PropertySource("classpath:/application-extrafields.properties")
|
||||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private CustomUserDetailsService userDetailsService;
|
private CustomUserDetailsService userDetailsService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private PasswordEncoder passwordEncoder;
|
private PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
|
||||||
http
|
http
|
||||||
.addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class)
|
.addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class)
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
.antMatchers("/css/**", "/index").permitAll()
|
.antMatchers("/css/**", "/index").permitAll()
|
||||||
.antMatchers("/user/**").authenticated()
|
.antMatchers("/user/**").authenticated()
|
||||||
.and()
|
.and()
|
||||||
.formLogin().loginPage("/login")
|
.formLogin().loginPage("/login")
|
||||||
.and()
|
.and()
|
||||||
.logout()
|
.logout()
|
||||||
.logoutUrl("/logout");
|
.logoutUrl("/logout");
|
||||||
}
|
}
|
||||||
|
|
||||||
public CustomAuthenticationFilter authenticationFilter() throws Exception {
|
public CustomAuthenticationFilter authenticationFilter() throws Exception {
|
||||||
CustomAuthenticationFilter filter = new CustomAuthenticationFilter();
|
CustomAuthenticationFilter filter = new CustomAuthenticationFilter();
|
||||||
filter.setAuthenticationManager(authenticationManagerBean());
|
filter.setAuthenticationManager(authenticationManagerBean());
|
||||||
filter.setAuthenticationFailureHandler(failureHandler());
|
filter.setAuthenticationFailureHandler(failureHandler());
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
auth.authenticationProvider(authProvider());
|
auth.authenticationProvider(authProvider());
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuthenticationProvider authProvider() {
|
public AuthenticationProvider authProvider() {
|
||||||
CustomUserDetailsAuthenticationProvider provider
|
CustomUserDetailsAuthenticationProvider provider
|
||||||
= new CustomUserDetailsAuthenticationProvider(passwordEncoder, userDetailsService);
|
= new CustomUserDetailsAuthenticationProvider(passwordEncoder, userDetailsService);
|
||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimpleUrlAuthenticationFailureHandler failureHandler() {
|
public SimpleUrlAuthenticationFailureHandler failureHandler() {
|
||||||
return new SimpleUrlAuthenticationFailureHandler("/login?error=true");
|
return new SimpleUrlAuthenticationFailureHandler("/login?error=true");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,23 +1,23 @@
|
|||||||
package com.baeldung.loginextrafieldscustom;
|
package com.baeldung.loginextrafieldscustom;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
|
||||||
public class User extends org.springframework.security.core.userdetails.User {
|
public class User extends org.springframework.security.core.userdetails.User {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private String domain;
|
private String domain;
|
||||||
|
|
||||||
public User(String username, String domain, String password, boolean enabled,
|
public User(String username, String domain, String password, boolean enabled,
|
||||||
boolean accountNonExpired, boolean credentialsNonExpired,
|
boolean accountNonExpired, boolean credentialsNonExpired,
|
||||||
boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
|
boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
|
||||||
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
|
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
|
||||||
this.domain = domain;
|
this.domain = domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDomain() {
|
public String getDomain() {
|
||||||
return domain;
|
return domain;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package com.baeldung.loginextrafieldscustom;
|
package com.baeldung.loginextrafieldscustom;
|
||||||
|
|
||||||
public interface UserRepository {
|
public interface UserRepository {
|
||||||
|
|
||||||
public User findUser(String username, String domain);
|
public User findUser(String username, String domain);
|
||||||
|
|
||||||
}
|
}
|
@ -1,51 +1,51 @@
|
|||||||
package com.baeldung.loginextrafieldscustom;
|
package com.baeldung.loginextrafieldscustom;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class WebController {
|
public class WebController {
|
||||||
|
|
||||||
@RequestMapping("/")
|
@RequestMapping("/")
|
||||||
public String root() {
|
public String root() {
|
||||||
return "redirect:/index";
|
return "redirect:/index";
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/index")
|
@RequestMapping("/index")
|
||||||
public String index(Model model) {
|
public String index(Model model) {
|
||||||
getDomain().ifPresent(d -> {
|
getDomain().ifPresent(d -> {
|
||||||
model.addAttribute("domain", d);
|
model.addAttribute("domain", d);
|
||||||
});
|
});
|
||||||
return "index";
|
return "index";
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/user/index")
|
@RequestMapping("/user/index")
|
||||||
public String userIndex(Model model) {
|
public String userIndex(Model model) {
|
||||||
getDomain().ifPresent(d -> {
|
getDomain().ifPresent(d -> {
|
||||||
model.addAttribute("domain", d);
|
model.addAttribute("domain", d);
|
||||||
});
|
});
|
||||||
return "user/index";
|
return "user/index";
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/login")
|
@RequestMapping("/login")
|
||||||
public String login() {
|
public String login() {
|
||||||
return "login";
|
return "login";
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<String> getDomain() {
|
private Optional<String> getDomain() {
|
||||||
Authentication auth = SecurityContextHolder.getContext()
|
Authentication auth = SecurityContextHolder.getContext()
|
||||||
.getAuthentication();
|
.getAuthentication();
|
||||||
String domain = null;
|
String domain = null;
|
||||||
if (auth != null && !auth.getClass().equals(AnonymousAuthenticationToken.class)) {
|
if (auth != null && !auth.getClass().equals(AnonymousAuthenticationToken.class)) {
|
||||||
User user = (User) auth.getPrincipal();
|
User user = (User) auth.getPrincipal();
|
||||||
domain = user.getDomain();
|
domain = user.getDomain();
|
||||||
}
|
}
|
||||||
return Optional.ofNullable(domain);
|
return Optional.ofNullable(domain);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,66 +1,66 @@
|
|||||||
package com.baeldung.loginextrafieldssimple;
|
package com.baeldung.loginextrafieldssimple;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.PropertySource;
|
import org.springframework.context.annotation.PropertySource;
|
||||||
import org.springframework.security.authentication.AuthenticationProvider;
|
import org.springframework.security.authentication.AuthenticationProvider;
|
||||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
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.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
|
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@PropertySource("classpath:/application-extrafields.properties")
|
@PropertySource("classpath:/application-extrafields.properties")
|
||||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserDetailsService userDetailsService;
|
private UserDetailsService userDetailsService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private PasswordEncoder passwordEncoder;
|
private PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
|
||||||
http
|
http
|
||||||
.addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class)
|
.addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class)
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
.antMatchers("/css/**", "/index").permitAll()
|
.antMatchers("/css/**", "/index").permitAll()
|
||||||
.antMatchers("/user/**").authenticated()
|
.antMatchers("/user/**").authenticated()
|
||||||
.and()
|
.and()
|
||||||
.formLogin().loginPage("/login")
|
.formLogin().loginPage("/login")
|
||||||
.and()
|
.and()
|
||||||
.logout()
|
.logout()
|
||||||
.logoutUrl("/logout");
|
.logoutUrl("/logout");
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimpleAuthenticationFilter authenticationFilter() throws Exception {
|
public SimpleAuthenticationFilter authenticationFilter() throws Exception {
|
||||||
SimpleAuthenticationFilter filter = new SimpleAuthenticationFilter();
|
SimpleAuthenticationFilter filter = new SimpleAuthenticationFilter();
|
||||||
filter.setAuthenticationManager(authenticationManagerBean());
|
filter.setAuthenticationManager(authenticationManagerBean());
|
||||||
filter.setAuthenticationFailureHandler(failureHandler());
|
filter.setAuthenticationFailureHandler(failureHandler());
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
auth.authenticationProvider(authProvider());
|
auth.authenticationProvider(authProvider());
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuthenticationProvider authProvider() {
|
public AuthenticationProvider authProvider() {
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
provider.setUserDetailsService(userDetailsService);
|
provider.setUserDetailsService(userDetailsService);
|
||||||
provider.setPasswordEncoder(passwordEncoder);
|
provider.setPasswordEncoder(passwordEncoder);
|
||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimpleUrlAuthenticationFailureHandler failureHandler() {
|
public SimpleUrlAuthenticationFailureHandler failureHandler() {
|
||||||
return new SimpleUrlAuthenticationFailureHandler("/login?error=true");
|
return new SimpleUrlAuthenticationFailureHandler("/login?error=true");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,54 +1,54 @@
|
|||||||
package com.baeldung.loginextrafieldssimple;
|
package com.baeldung.loginextrafieldssimple;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
import org.springframework.security.core.AuthenticationException;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
|
||||||
public class SimpleAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
|
public class SimpleAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
|
||||||
|
|
||||||
public static final String SPRING_SECURITY_FORM_DOMAIN_KEY = "domain";
|
public static final String SPRING_SECURITY_FORM_DOMAIN_KEY = "domain";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
|
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws AuthenticationException {
|
throws AuthenticationException {
|
||||||
|
|
||||||
if (!request.getMethod()
|
if (!request.getMethod()
|
||||||
.equals("POST")) {
|
.equals("POST")) {
|
||||||
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
|
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
|
||||||
}
|
}
|
||||||
|
|
||||||
UsernamePasswordAuthenticationToken authRequest = getAuthRequest(request);
|
UsernamePasswordAuthenticationToken authRequest = getAuthRequest(request);
|
||||||
setDetails(request, authRequest);
|
setDetails(request, authRequest);
|
||||||
return this.getAuthenticationManager()
|
return this.getAuthenticationManager()
|
||||||
.authenticate(authRequest);
|
.authenticate(authRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
private UsernamePasswordAuthenticationToken getAuthRequest(HttpServletRequest request) {
|
private UsernamePasswordAuthenticationToken getAuthRequest(HttpServletRequest request) {
|
||||||
String username = obtainUsername(request);
|
String username = obtainUsername(request);
|
||||||
String password = obtainPassword(request);
|
String password = obtainPassword(request);
|
||||||
String domain = obtainDomain(request);
|
String domain = obtainDomain(request);
|
||||||
|
|
||||||
if (username == null) {
|
if (username == null) {
|
||||||
username = "";
|
username = "";
|
||||||
}
|
}
|
||||||
if (password == null) {
|
if (password == null) {
|
||||||
password = "";
|
password = "";
|
||||||
}
|
}
|
||||||
if (domain == null) {
|
if (domain == null) {
|
||||||
domain = "";
|
domain = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
String usernameDomain = String.format("%s%s%s", username.trim(),
|
String usernameDomain = String.format("%s%s%s", username.trim(),
|
||||||
String.valueOf(Character.LINE_SEPARATOR), domain);
|
String.valueOf(Character.LINE_SEPARATOR), domain);
|
||||||
return new UsernamePasswordAuthenticationToken(usernameDomain, password);
|
return new UsernamePasswordAuthenticationToken(usernameDomain, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String obtainDomain(HttpServletRequest request) {
|
private String obtainDomain(HttpServletRequest request) {
|
||||||
return request.getParameter(SPRING_SECURITY_FORM_DOMAIN_KEY);
|
return request.getParameter(SPRING_SECURITY_FORM_DOMAIN_KEY);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,32 +1,32 @@
|
|||||||
package com.baeldung.loginextrafieldssimple;
|
package com.baeldung.loginextrafieldssimple;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service("userDetailsService")
|
@Service("userDetailsService")
|
||||||
public class SimpleUserDetailsService implements UserDetailsService {
|
public class SimpleUserDetailsService implements UserDetailsService {
|
||||||
|
|
||||||
private UserRepository userRepository;
|
private UserRepository userRepository;
|
||||||
|
|
||||||
public SimpleUserDetailsService(UserRepository userRepository) {
|
public SimpleUserDetailsService(UserRepository userRepository) {
|
||||||
this.userRepository = userRepository;
|
this.userRepository = userRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
String[] usernameAndDomain = StringUtils.split(username, String.valueOf(Character.LINE_SEPARATOR));
|
String[] usernameAndDomain = StringUtils.split(username, String.valueOf(Character.LINE_SEPARATOR));
|
||||||
if (usernameAndDomain == null || usernameAndDomain.length != 2) {
|
if (usernameAndDomain == null || usernameAndDomain.length != 2) {
|
||||||
throw new UsernameNotFoundException("Username and domain must be provided");
|
throw new UsernameNotFoundException("Username and domain must be provided");
|
||||||
}
|
}
|
||||||
User user = userRepository.findUser(usernameAndDomain[0], usernameAndDomain[1]);
|
User user = userRepository.findUser(usernameAndDomain[0], usernameAndDomain[1]);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new UsernameNotFoundException(
|
throw new UsernameNotFoundException(
|
||||||
String.format("Username not found for domain, username=%s, domain=%s",
|
String.format("Username not found for domain, username=%s, domain=%s",
|
||||||
usernameAndDomain[0], usernameAndDomain[1]));
|
usernameAndDomain[0], usernameAndDomain[1]));
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,33 +1,33 @@
|
|||||||
package com.baeldung.loginextrafieldssimple;
|
package com.baeldung.loginextrafieldssimple;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
@Repository("userRepository")
|
@Repository("userRepository")
|
||||||
public class SimpleUserRepository implements UserRepository {
|
public class SimpleUserRepository implements UserRepository {
|
||||||
|
|
||||||
private PasswordEncoder passwordEncoder;
|
private PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
public SimpleUserRepository(PasswordEncoder passwordEncoder) {
|
public SimpleUserRepository(PasswordEncoder passwordEncoder) {
|
||||||
this.passwordEncoder = passwordEncoder;
|
this.passwordEncoder = passwordEncoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public User findUser(String username, String domain) {
|
public User findUser(String username, String domain) {
|
||||||
if (StringUtils.isAnyBlank(username, domain)) {
|
if (StringUtils.isAnyBlank(username, domain)) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
Collection<? extends GrantedAuthority> authorities = new ArrayList<>();
|
Collection<? extends GrantedAuthority> authorities = new ArrayList<>();
|
||||||
User user = new User(username, domain,
|
User user = new User(username, domain,
|
||||||
passwordEncoder.encode("secret"), true,
|
passwordEncoder.encode("secret"), true,
|
||||||
true, true, true, authorities);
|
true, true, true, authorities);
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,21 +1,21 @@
|
|||||||
package com.baeldung.loginextrafieldssimple;
|
package com.baeldung.loginextrafieldssimple;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
|
||||||
public class User extends org.springframework.security.core.userdetails.User {
|
public class User extends org.springframework.security.core.userdetails.User {
|
||||||
|
|
||||||
private String domain;
|
private String domain;
|
||||||
|
|
||||||
public User(String username, String domain, String password, boolean enabled,
|
public User(String username, String domain, String password, boolean enabled,
|
||||||
boolean accountNonExpired, boolean credentialsNonExpired,
|
boolean accountNonExpired, boolean credentialsNonExpired,
|
||||||
boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
|
boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
|
||||||
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
|
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
|
||||||
this.domain = domain;
|
this.domain = domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDomain() {
|
public String getDomain() {
|
||||||
return domain;
|
return domain;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package com.baeldung.loginextrafieldssimple;
|
package com.baeldung.loginextrafieldssimple;
|
||||||
|
|
||||||
public interface UserRepository {
|
public interface UserRepository {
|
||||||
|
|
||||||
public User findUser(String username, String domain);
|
public User findUser(String username, String domain);
|
||||||
|
|
||||||
}
|
}
|
@ -1,51 +1,51 @@
|
|||||||
package com.baeldung.loginextrafieldssimple;
|
package com.baeldung.loginextrafieldssimple;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class WebController {
|
public class WebController {
|
||||||
|
|
||||||
@RequestMapping("/")
|
@RequestMapping("/")
|
||||||
public String root() {
|
public String root() {
|
||||||
return "redirect:/index";
|
return "redirect:/index";
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/index")
|
@RequestMapping("/index")
|
||||||
public String index(Model model) {
|
public String index(Model model) {
|
||||||
getDomain().ifPresent(d -> {
|
getDomain().ifPresent(d -> {
|
||||||
model.addAttribute("domain", d);
|
model.addAttribute("domain", d);
|
||||||
});
|
});
|
||||||
return "index";
|
return "index";
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/user/index")
|
@RequestMapping("/user/index")
|
||||||
public String userIndex(Model model) {
|
public String userIndex(Model model) {
|
||||||
getDomain().ifPresent(d -> {
|
getDomain().ifPresent(d -> {
|
||||||
model.addAttribute("domain", d);
|
model.addAttribute("domain", d);
|
||||||
});
|
});
|
||||||
return "user/index";
|
return "user/index";
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/login")
|
@RequestMapping("/login")
|
||||||
public String login() {
|
public String login() {
|
||||||
return "login";
|
return "login";
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<String> getDomain() {
|
private Optional<String> getDomain() {
|
||||||
Authentication auth = SecurityContextHolder.getContext()
|
Authentication auth = SecurityContextHolder.getContext()
|
||||||
.getAuthentication();
|
.getAuthentication();
|
||||||
String domain = null;
|
String domain = null;
|
||||||
if (auth != null && !auth.getClass().equals(AnonymousAuthenticationToken.class)) {
|
if (auth != null && !auth.getClass().equals(AnonymousAuthenticationToken.class)) {
|
||||||
User user = (User) auth.getPrincipal();
|
User user = (User) auth.getPrincipal();
|
||||||
domain = user.getDomain();
|
domain = user.getDomain();
|
||||||
}
|
}
|
||||||
return Optional.ofNullable(domain);
|
return Optional.ofNullable(domain);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
server.port=8081
|
||||||
|
|
||||||
|
logging.level.root=INFO
|
||||||
|
|
||||||
|
logging.level.com.baeldung.dsl.ClientErrorLoggingFilter=DEBUG
|
||||||
|
|
||||||
|
logging.level.org.springframework.security=DEBUG
|
@ -1,46 +1,46 @@
|
|||||||
package com.baeldung.loginextrafields;
|
package com.baeldung.loginextrafields;
|
||||||
|
|
||||||
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
|
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.web.FilterChainProxy;
|
import org.springframework.security.web.FilterChainProxy;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
|
||||||
public abstract class AbstractExtraLoginFieldsIntegrationTest {
|
public abstract class AbstractExtraLoginFieldsIntegrationTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private FilterChainProxy springSecurityFilterChain;
|
private FilterChainProxy springSecurityFilterChain;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private WebApplicationContext wac;
|
private WebApplicationContext wac;
|
||||||
|
|
||||||
protected MockMvc mockMvc;
|
protected MockMvc mockMvc;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)
|
this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)
|
||||||
.apply(springSecurity(springSecurityFilterChain))
|
.apply(springSecurity(springSecurityFilterChain))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenRootPathAccess_thenRedirectToIndex() throws Exception {
|
public void givenRootPathAccess_thenRedirectToIndex() throws Exception {
|
||||||
this.mockMvc.perform(get("/"))
|
this.mockMvc.perform(get("/"))
|
||||||
.andExpect(status().is3xxRedirection())
|
.andExpect(status().is3xxRedirection())
|
||||||
.andExpect(redirectedUrlPattern("/index*"));
|
.andExpect(redirectedUrlPattern("/index*"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenSecuredResource_whenAccessUnauthenticated_thenRequiresAuthentication() throws Exception {
|
public void givenSecuredResource_whenAccessUnauthenticated_thenRequiresAuthentication() throws Exception {
|
||||||
this.mockMvc.perform(get("/user/index"))
|
this.mockMvc.perform(get("/user/index"))
|
||||||
.andExpect(status().is3xxRedirection())
|
.andExpect(status().is3xxRedirection())
|
||||||
.andExpect(redirectedUrlPattern("**/login"));
|
.andExpect(redirectedUrlPattern("**/login"));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,72 +1,72 @@
|
|||||||
package com.baeldung.loginextrafields;
|
package com.baeldung.loginextrafields;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
|
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.mock.web.MockHttpSession;
|
import org.springframework.mock.web.MockHttpSession;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.core.context.SecurityContext;
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
|
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
|
||||||
import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig;
|
import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
import org.springframework.test.web.servlet.MvcResult;
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||||
|
|
||||||
import com.baeldung.loginextrafieldscustom.ExtraLoginFieldsApplication;
|
import com.baeldung.loginextrafieldscustom.ExtraLoginFieldsApplication;
|
||||||
import com.baeldung.loginextrafieldscustom.User;
|
import com.baeldung.loginextrafieldscustom.User;
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringJUnitWebConfig
|
@SpringJUnitWebConfig
|
||||||
@SpringBootTest(classes = ExtraLoginFieldsApplication.class)
|
@SpringBootTest(classes = ExtraLoginFieldsApplication.class)
|
||||||
public class LoginFieldsFullIntegrationTest extends AbstractExtraLoginFieldsIntegrationTest {
|
public class LoginFieldsFullIntegrationTest extends AbstractExtraLoginFieldsIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenAccessSecuredResource_whenAuthenticated_thenAuthHasExtraFields() throws Exception {
|
public void givenAccessSecuredResource_whenAuthenticated_thenAuthHasExtraFields() throws Exception {
|
||||||
MockHttpServletRequestBuilder securedResourceAccess = get("/user/index");
|
MockHttpServletRequestBuilder securedResourceAccess = get("/user/index");
|
||||||
MvcResult unauthenticatedResult = mockMvc.perform(securedResourceAccess)
|
MvcResult unauthenticatedResult = mockMvc.perform(securedResourceAccess)
|
||||||
.andExpect(status().is3xxRedirection())
|
.andExpect(status().is3xxRedirection())
|
||||||
.andReturn();
|
.andReturn();
|
||||||
|
|
||||||
MockHttpSession session = (MockHttpSession) unauthenticatedResult.getRequest()
|
MockHttpSession session = (MockHttpSession) unauthenticatedResult.getRequest()
|
||||||
.getSession();
|
.getSession();
|
||||||
String loginUrl = unauthenticatedResult.getResponse()
|
String loginUrl = unauthenticatedResult.getResponse()
|
||||||
.getRedirectedUrl();
|
.getRedirectedUrl();
|
||||||
|
|
||||||
User user = getUser();
|
User user = getUser();
|
||||||
|
|
||||||
mockMvc.perform(post(loginUrl)
|
mockMvc.perform(post(loginUrl)
|
||||||
.param("username", user.getUsername())
|
.param("username", user.getUsername())
|
||||||
.param("password", user.getPassword())
|
.param("password", user.getPassword())
|
||||||
.param("domain", user.getDomain())
|
.param("domain", user.getDomain())
|
||||||
.session(session)
|
.session(session)
|
||||||
.with(csrf()))
|
.with(csrf()))
|
||||||
.andExpect(status().is3xxRedirection())
|
.andExpect(status().is3xxRedirection())
|
||||||
.andExpect(redirectedUrlPattern("**/user/index"))
|
.andExpect(redirectedUrlPattern("**/user/index"))
|
||||||
.andReturn();
|
.andReturn();
|
||||||
|
|
||||||
mockMvc.perform(securedResourceAccess.session(session))
|
mockMvc.perform(securedResourceAccess.session(session))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
SecurityContext securityContext
|
SecurityContext securityContext
|
||||||
= (SecurityContext) session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
|
= (SecurityContext) session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
|
||||||
Authentication auth = securityContext.getAuthentication();
|
Authentication auth = securityContext.getAuthentication();
|
||||||
assertEquals(((User)auth.getPrincipal()).getDomain(), user.getDomain());
|
assertEquals(((User)auth.getPrincipal()).getDomain(), user.getDomain());
|
||||||
}
|
}
|
||||||
|
|
||||||
private User getUser() {
|
private User getUser() {
|
||||||
Collection<? extends GrantedAuthority> authorities = new ArrayList<>();
|
Collection<? extends GrantedAuthority> authorities = new ArrayList<>();
|
||||||
return new User("myusername", "mydomain", "secret", true, true, true, true, authorities);
|
return new User("myusername", "mydomain", "secret", true, true, true, true, authorities);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,72 +1,72 @@
|
|||||||
package com.baeldung.loginextrafields;
|
package com.baeldung.loginextrafields;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
|
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.mock.web.MockHttpSession;
|
import org.springframework.mock.web.MockHttpSession;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.core.context.SecurityContext;
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
|
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
|
||||||
import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig;
|
import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
import org.springframework.test.web.servlet.MvcResult;
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||||
|
|
||||||
import com.baeldung.loginextrafieldssimple.ExtraLoginFieldsApplication;
|
import com.baeldung.loginextrafieldssimple.ExtraLoginFieldsApplication;
|
||||||
import com.baeldung.loginextrafieldssimple.User;
|
import com.baeldung.loginextrafieldssimple.User;
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringJUnitWebConfig
|
@SpringJUnitWebConfig
|
||||||
@SpringBootTest(classes = ExtraLoginFieldsApplication.class)
|
@SpringBootTest(classes = ExtraLoginFieldsApplication.class)
|
||||||
public class LoginFieldsSimpleIntegrationTest extends AbstractExtraLoginFieldsIntegrationTest {
|
public class LoginFieldsSimpleIntegrationTest extends AbstractExtraLoginFieldsIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenAccessSecuredResource_whenAuthenticated_thenAuthHasExtraFields() throws Exception {
|
public void givenAccessSecuredResource_whenAuthenticated_thenAuthHasExtraFields() throws Exception {
|
||||||
MockHttpServletRequestBuilder securedResourceAccess = get("/user/index");
|
MockHttpServletRequestBuilder securedResourceAccess = get("/user/index");
|
||||||
MvcResult unauthenticatedResult = mockMvc.perform(securedResourceAccess)
|
MvcResult unauthenticatedResult = mockMvc.perform(securedResourceAccess)
|
||||||
.andExpect(status().is3xxRedirection())
|
.andExpect(status().is3xxRedirection())
|
||||||
.andReturn();
|
.andReturn();
|
||||||
|
|
||||||
MockHttpSession session = (MockHttpSession) unauthenticatedResult.getRequest()
|
MockHttpSession session = (MockHttpSession) unauthenticatedResult.getRequest()
|
||||||
.getSession();
|
.getSession();
|
||||||
String loginUrl = unauthenticatedResult.getResponse()
|
String loginUrl = unauthenticatedResult.getResponse()
|
||||||
.getRedirectedUrl();
|
.getRedirectedUrl();
|
||||||
|
|
||||||
User user = getUser();
|
User user = getUser();
|
||||||
|
|
||||||
mockMvc.perform(post(loginUrl)
|
mockMvc.perform(post(loginUrl)
|
||||||
.param("username", user.getUsername())
|
.param("username", user.getUsername())
|
||||||
.param("password", user.getPassword())
|
.param("password", user.getPassword())
|
||||||
.param("domain", user.getDomain())
|
.param("domain", user.getDomain())
|
||||||
.session(session)
|
.session(session)
|
||||||
.with(csrf()))
|
.with(csrf()))
|
||||||
.andExpect(status().is3xxRedirection())
|
.andExpect(status().is3xxRedirection())
|
||||||
.andExpect(redirectedUrlPattern("**/user/index"))
|
.andExpect(redirectedUrlPattern("**/user/index"))
|
||||||
.andReturn();
|
.andReturn();
|
||||||
|
|
||||||
mockMvc.perform(securedResourceAccess.session(session))
|
mockMvc.perform(securedResourceAccess.session(session))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
SecurityContext securityContext
|
SecurityContext securityContext
|
||||||
= (SecurityContext) session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
|
= (SecurityContext) session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
|
||||||
Authentication auth = securityContext.getAuthentication();
|
Authentication auth = securityContext.getAuthentication();
|
||||||
assertEquals(((User)auth.getPrincipal()).getDomain(), user.getDomain());
|
assertEquals(((User)auth.getPrincipal()).getDomain(), user.getDomain());
|
||||||
}
|
}
|
||||||
|
|
||||||
private User getUser() {
|
private User getUser() {
|
||||||
Collection<? extends GrantedAuthority> authorities = new ArrayList<>();
|
Collection<? extends GrantedAuthority> authorities = new ArrayList<>();
|
||||||
return new User("myusername", "mydomain", "secret", true, true, true, true, authorities);
|
return new User("myusername", "mydomain", "secret", true, true, true, true, authorities);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user