用户登录时的Spring引导安全自定义消息
我正在尝试将spring安全性集成到我的spring启动应用程序中。一切正常,但如果帐户过期或帐户被锁定,我如何显示消息?另外,我不想显示基于parm的错误消息,比如 这是我当前的代码:login.html用户登录时的Spring引导安全自定义消息,spring,spring-security,spring-data-jpa,spring-security-oauth2,spring-session,Spring,Spring Security,Spring Data Jpa,Spring Security Oauth2,Spring Session,我正在尝试将spring安全性集成到我的spring启动应用程序中。一切正常,但如果帐户过期或帐户被锁定,我如何显示消息?另外,我不想显示基于parm的错误消息,比如 这是我当前的代码:login.html <div th:if="${param.error}" class="alert alert-danger"> Invalid username or password. </div> <
<div th:if="${param.error}" class="alert alert-danger">
Invalid username or password.
</div>
<h3>Sign in to continue</h3>
<form th:action="@{/login}" name="loginForm" method="POST">
<div class="form-group">
<label for="userNameInput">Username</label>
<input type="text" class="form-control" id="userNameInput" name="username" placeholder="Username" />
</div>
<div class="form-group">
<label for="passwordInput">Password</label>
<input type="password" class="form-control" id="passwordInput" name="password" placeholder="Password" />
</div>
<button type="submit" class="btn btn-success">Login</button>
</form>
CustomUserDetailsService.java
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/css/**", "/js/**","/login/**").permitAll()
.anyRequest().authenticated()
.and().formLogin().loginPage("/login").defaultSuccessUrl("/dashboard")
.and().logout().logoutSuccessUrl("/");
}
@Autowired
public void configAuthBuilder(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
}
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
UserRepository userRepository;
@Override
@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//query for user from DB
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
}
Date today = new Date();
//do check if account expired / suspended / deleted
Boolean isAcconutExpired = false;
Boolean status = false;
if (user.getExpireOn() != null && today.before(user.getExpireOn())) {
isAcconutExpired = false;
}
if(user.getStatus() == 1){
status = true;
}
return new org.springframework.security.core.userdetails.User(user.getUsername(),
user.getPassword(),
status,
!isAcconutExpired,
true,
true,
getAuthorities(user));
}
private List<GrantedAuthority> getAuthorities(User user) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("USER"));
return authorities;
}
}
@Repository
public interface UserRepository extends CrudRepository<User, Long> {
User findByUsername(String username);
}
@服务
公共类CustomUserDetailsService实现UserDetailsService{
@自动连线
用户存储库用户存储库;
@凌驾
@事务(只读=真)
public UserDetails loadUserByUsername(字符串用户名)引发UsernameNotFoundException{
//从数据库查询用户
User=userRepository.findByUsername(用户名);
if(user==null){
抛出新用户名NotFoundException(用户名);
}
今天日期=新日期();
//检查帐户是否已过期/暂停/删除
布尔值IsAccountExpired=false;
布尔状态=假;
if(user.getExpireOn()!=null&&today.before(user.getExpireOn())){
IsAccountExpired=false;
}
if(user.getStatus()==1){
状态=真;
}
返回新的org.springframework.security.core.userdetails.User(User.getUsername(),
user.getPassword(),
地位
!我的帐户过期了,
是的,
是的,
获取权限(用户));
}
私有列表GetAuthories(用户){
列表权限=新建ArrayList();
添加(新的SimpleGrantedAuthority(“用户”);
返回当局;
}
}
UserRepository.java
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/css/**", "/js/**","/login/**").permitAll()
.anyRequest().authenticated()
.and().formLogin().loginPage("/login").defaultSuccessUrl("/dashboard")
.and().logout().logoutSuccessUrl("/");
}
@Autowired
public void configAuthBuilder(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
}
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
UserRepository userRepository;
@Override
@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//query for user from DB
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
}
Date today = new Date();
//do check if account expired / suspended / deleted
Boolean isAcconutExpired = false;
Boolean status = false;
if (user.getExpireOn() != null && today.before(user.getExpireOn())) {
isAcconutExpired = false;
}
if(user.getStatus() == 1){
status = true;
}
return new org.springframework.security.core.userdetails.User(user.getUsername(),
user.getPassword(),
status,
!isAcconutExpired,
true,
true,
getAuthorities(user));
}
private List<GrantedAuthority> getAuthorities(User user) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("USER"));
return authorities;
}
}
@Repository
public interface UserRepository extends CrudRepository<User, Long> {
User findByUsername(String username);
}
@存储库
公共接口UserRepository扩展了Crudepository{
用户findByUsername(字符串用户名);
}
这条消息有点旧,但我目前面临着同样的问题
因此,首先,您必须创建身份验证提供程序的自定义实例,以便将HideUserNotFoundExceptions传递给控制器:
public AuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider impl = new DaoAuthenticationProvider();
impl.setUserDetailsService(customUserDetailsService);
impl.setPasswordEncoder(new BCryptPasswordEncoder());
impl.setHideUserNotFoundExceptions(false) ;
return impl ;
}
此外,您应该在AuthenticationProviderBuilder中添加此提供程序,而不是添加customDetailService(添加customDetailService将添加其他提供程序):
有了它,您现在可以捕获UserNotFoundException而不是basicBadCredentialsException
因此,仍然需要显示这两个异常的自定义错误消息。Badcredentials异常由SpringSecurity直接抛出,并根据I18n messageAbstractUserDetailsAuthenticationProvider发出错误消息。Badcredentials(请参阅spring security中的实现):
过期和帐户锁定的情况相同。
因此,我建议您更改CustomUserDetailsService.java类,以使用类似的代码错误执行相同操作:
if (user == null) {
throw new UsernameNotFoundException(SpringSecurityMessageSource.getAccessor().getMessage("AbstractUserDetailsAuthenticationProvider.UserUnknown",new Object[] {login},"User is not known"));
}
在此之后,您可以在消息中添加这些行。属性:
AbstractUserDetailsAuthenticationProvider.UserUnknown = {0} was not found.
AbstractUserDetailsAuthenticationProvider.badCredentials = Password is bad
AbstractUserDetailsAuthenticationProvider.credentialsExpired = User credentials have expired
AbstractUserDetailsAuthenticationProvider.disabled = User is disabled
AbstractUserDetailsAuthenticationProvider.expired = User account has expired
AbstractUserDetailsAuthenticationProvider.locked = User account is locked
<div class="dialog-row">
<label th:if="${param.error}" th:text="${session['SPRING_SECURITY_LAST_EXCEPTION'].message}" class="text-center redText">Mot de passe inconnu</label>
</div>
并在login.html中显示错误消息:
AbstractUserDetailsAuthenticationProvider.UserUnknown = {0} was not found.
AbstractUserDetailsAuthenticationProvider.badCredentials = Password is bad
AbstractUserDetailsAuthenticationProvider.credentialsExpired = User credentials have expired
AbstractUserDetailsAuthenticationProvider.disabled = User is disabled
AbstractUserDetailsAuthenticationProvider.expired = User account has expired
AbstractUserDetailsAuthenticationProvider.locked = User account is locked
<div class="dialog-row">
<label th:if="${param.error}" th:text="${session['SPRING_SECURITY_LAST_EXCEPTION'].message}" class="text-center redText">Mot de passe inconnu</label>
</div>
莫特德帕塞因科努
如果使用jsp页面,可以将页面重定向到Login.jsp?status=error,如果查询字符串不是空的,则在jsp页面代码中使用查询字符串message@MohammadMirzaeyan-我没有使用jsp。我也需要这段代码,但我不工作。我不明白${session['SPRING\u SECURITY\u LAST\u EXCEPTION']在哪里。message}
来自!!以及message.properties中的消息如何显示?我需要在顶部添加任何会话变量吗?Hello@varman。${session['SPRING\u SECURITY\u LAST\u EXCEPTION'].message}由会话中的SPRING SECURITY直接设置(${session[XXX]是Thymeleaf获取此异常的方式)Spring security已在message.properties中搜索此值:AbstractUserDetailsAuthenticationProvider.badCredentials AbstractUserDetailsAuthenticationProvider.Credentials过期AbstractUserDetailsAuthenticationProvider.disabled[…]一个“AbstractUserDetailsAuthenticationProvider.UserUnknown”是由CustomUserDetailsService创建的。您的错误是什么?