我正在用springboot和jsp创建一个web应用程序。我已经实现了Spring Security ,我正在重写 loadUserByUsername()
方法,当找不到用户时,我将 UsernameNotFoundException("User not found")
带着信息。现在我想在我的登录页面中显示一条正确的消息,我如何才能做到这一点?
myuserdetailsservice.java文件
package in.bushansirgur.security.service;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityMessageSource;
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.stereotype.Service;
import in.bushansirgur.security.entity.Role;
import in.bushansirgur.security.entity.User;
@Service
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UserService userService;
@Override
@Transactional
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException{
User user = userService.findUserByEmail(email);
if(user == null || user.getActive() == null){
throw new UsernameNotFoundException("User not found!");
}
List<GrantedAuthority> authorities = getUserAuthority(user.getRoles());
return buildUserForAuthentication(user, authorities);
}
...
}
登录控制器.java
@RequestMapping(value = {"/login", "/"})
public ModelAndView login(@RequestParam(name="error", required = false)String error,
@RequestParam(name="logout", required = false)String logout, HttpServletRequest request
) throws UnknownHostException {
// Port
String portNumber = environment.getProperty("server.port");
// Local address
String hostAddress = InetAddress.getLocalHost().getHostAddress();
String hostName = InetAddress.getLocalHost().getHostName();
System.out.println("Host address:"+hostAddress+" Host name:"+hostName+" Port number:"+portNumber);
// Remote address
InetAddress.getLoopbackAddress().getHostAddress();
InetAddress.getLoopbackAddress().getHostName();
ModelAndView mv = new ModelAndView("login");
if(error!=null) {
mv.addObject("message", "Invalid Username and Password!");
}
if(logout!=null) {
mv.addObject("logout", "User has successfully logged out!");
}
System.out.println("context path:"+request.getContextPath());
return mv;
}
登录.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<c:set var="contextRoot" value="${pageContext.request.contextPath}" />
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<style>
.help-block {
color: #ff0000;
}
</style>
<body>
<h1>Login</h1>
<c:if test="${not empty message}">
<div class="row">
<div class="col-md-offset-3 col-md-6">
<div class="alert alert-danger">${message}</div>
</div>
</div>
</c:if>
<c:if test="${not empty logout}">
<div class="row">
<div class="col-md-offset-3 col-md-6">
<div class="alert alert-success">${logout}</div>
</div>
</div>
</c:if>
<form action="login" method="post" id="loginform">
<input type="text" name="email" placeholder="Enter email" /><br/>
<input type="password" name="password" placeholder="Enter password" /><br/>
<button type="submit">Login</button>
<%-- <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> --%>
</form>
<a href="${contextRoot}/registration">Register</a>
<script type="text/javascript" src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.17.0/dist/jquery.validate.js"></script>
<script>
$(function(){
const $loginForm = $("#loginform");
if($loginForm.length){
$loginForm.validate({
rules: {
email: {
required: true
},
password: {
required: true
}
},
messages: {
email: {
required: "Please enter email"
},
password: {
required: "Please enter password"
}
},
errorElement: 'em',
errorPlacement: function(error, element) {
error.addClass('help-block');
error.insertAfter(element);
}
})
}
})
</script>
</body>
</html>
WebSecurity配置.java
@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
private MyUserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.
authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/registration").permitAll()
.antMatchers("/confirm-account").permitAll()
.antMatchers("/admin/**").hasAuthority("ADMIN")
.antMatchers("/user/**").hasAnyAuthority("ADMIN", "USER")
.anyRequest().authenticated().and().csrf().disable().formLogin()
.loginPage("/login")//.failureUrl("/login?error=true")
.defaultSuccessUrl("/dashboard")
.usernameParameter("email")
.passwordParameter("password")
.and().exceptionHandling().accessDeniedPage("/403");
}
...
}
jsp中显示的错误消息是“用户名和密码无效”。那么,如果 UserNotFoundException
被扔了!
提前谢谢!
1条答案
按热度按时间vuv7lop31#
默认情况下
AbstractUserDetailsAuthenticationProvider
如果找不到用户名或密码不正确,则引发badcredentialsexception。将此属性设置为false将导致UsernameNotFoundExceptions
为了前者而被抛弃。注意,这被认为比抛出更不安全
BadCredentialsException
对于这两个例外。为此,必须示例化身份验证提供程序,如下所示:警告:这样做不符合安全惯例。
请参见此处,sethideusernotfoundexceptions和spring security bad credentials区分无效的用户名或密码